前文pyinstaller+python3.6搭建windows客戶端的服務(wù)(一)描述了使用python3.6+django+windows服務(wù)的方法搭建帶本地服務(wù)的客戶端方法。主要存在如下缺點(diǎn):
- windows服務(wù)不完全穩(wěn)定,有時(shí)可以訪問(wèn)正常,但偶爾又訪問(wèn)不正常;
- 調(diào)試windows服務(wù)太困難,據(jù)本人所知,就只有事件查看器和自己打印日志去調(diào)試程序2種方法,如果在服務(wù)運(yùn)行過(guò)程中出現(xiàn)服務(wù)自身的異常,可能并一定有日志,這種情況就非常難定位和分析。
經(jīng)過(guò)努力,本項(xiàng)目又嘗試了另外一種方法實(shí)現(xiàn)本地客戶端,詳見(jiàn)下文。
方案(二)Python3.6+pyinstaller+pythonw
一、開(kāi)始
??在查找更好解決方案過(guò)程中,網(wǎng)上有人說(shuō)使用pythonw.exe程序,可以啟動(dòng)一個(gè)無(wú)窗體的后臺(tái)進(jìn)程;而django自身在啟動(dòng)后,會(huì)一直監(jiān)聽(tīng)端口,此進(jìn)程是不會(huì)退出的。
??也就是說(shuō)如果使用pythonw.exe工具,讓django在無(wú)窗體的后臺(tái)進(jìn)程中運(yùn)行,這樣就和window服務(wù)的進(jìn)程看進(jìn)來(lái)沒(méi)有區(qū)別了,同時(shí)代碼運(yùn)行的調(diào)試能力也方便很多,因?yàn)檫@個(gè)進(jìn)程的所有日志都可以打印到日志文件中。
二、主程序打包過(guò)程
??上一篇文章已經(jīng)建立好helloworld的django工程,本次把service.ini和service.py文件刪除,同時(shí)刪除【E:\helloworld\hello\settings.py】文件中變量INSTALLED_APPS的'django_windows_tools'。
2.1、準(zhǔn)備工作
- 將工程中manage.py更名為manage.pyw
此時(shí)python能在打包后運(yùn)行時(shí)使用pythonw.exe,而不是使用默認(rèn)的python.exe去運(yùn)行
2.2、hello.spec——文件夾形式
# -*- mode: python -*-
block_cipher = None
hide_imports = ['django.contrib.admin.apps', 'django.contrib.auth.apps', 'django.contrib.contenttypes.apps',
'django.contrib.messages.apps', 'django.contrib.staticfiles.apps', 'django.contrib.sessions.models',
'django.contrib.sessions.apps', 'django.contrib.messages.middleware', 'django.contrib.auth.middleware',
'django.contrib.sessions.middleware', 'django.contrib.sessions.serializers','django.core.mail.backends',
'django.views.defaults', 'django.core.mail.backends.smtp',]
a = Analysis(['manage.pyw'], pathex=['E:\\LayaProj\\hello'], binaries=[],
datas=[('logo.ico', '.')], hiddenimports=hide_imports,
hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False,
win_private_assemblies=False, cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(pyz, a.scripts, exclude_binaries=True, name='Hello', debug=False, strip=False, upx=True, console=False, icon='logo.ico')
coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=True, name='Hello')
??其中l(wèi)ogo.ico為應(yīng)用的圖標(biāo),使用命令【pyinstaller -y hello.spec】編譯工程,會(huì)在dist\Hello\目錄下存放生成好的所有文件。
??在cmd命令行中執(zhí)行【dist\Hello\Hello.exe runserver --noreload 0.0.0.0:8800】,應(yīng)會(huì)創(chuàng)建Hello.exe進(jìn)程,此進(jìn)程會(huì)創(chuàng)建另外一個(gè)Hello.exe進(jìn)程,此兩個(gè)進(jìn)程即為django的服務(wù)器的監(jiān)聽(tīng)和處理進(jìn)程。
??但,此時(shí)只是進(jìn)行了打包,還是手工執(zhí)行命令啟動(dòng)服務(wù),而常規(guī)的windows客戶端程序是點(diǎn)擊桌面的快捷方式啟動(dòng)程序,還需進(jìn)一步改進(jìn)。
三、實(shí)現(xiàn)類桌面應(yīng)用的網(wǎng)頁(yè)版程序
3.1、新增一個(gè)啟動(dòng)工程entry
此工程主要有2個(gè)文件:entry.py和entry.spec。
本項(xiàng)目將其中的配置相關(guān)放在Configs.py文件中,LoggerHelper.py為記錄日志的類,視情況參考。
- 源文件entry\Configs.py:
import os, sys
# This is my base path
BASE_PATH = os.path.dirname(os.path.abspath(__file__))
# all tmp dir dirs
APP_TMP_DIR = os.path.join(BASE_PATH, 'tmp')
# determine if application is a script file or frozen exe
if getattr(sys, 'frozen', False):
BASE_PATH = sys._MEIPASS
APP_TMP_DIR = os.path.join(BASE_PATH, '..', 'tmp')
if not BASE_PATH in sys.path:
sys.path.append(BASE_PATH)
DJANGO_PORT = 18800
DJANGO_ARGS = 'runserver --noreload 0.0.0.0:%d' % DJANGO_PORT
DJANGO_PROCESS_ID = 'Hello.exe'
APP_LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters': { # 格式器
'standard': { # 詳細(xì)
'format': '[%(asctime)s|%(levelname)s|%(processName)s|%(module)s|%(lineno)s]: %(message)s',
#'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S',
},
},
'handlers': {
'start': {
'level': 'DEBUG',
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': os.path.join(APP_TMP_DIR, 'start.log'),
'when': 'D',
'interval': 1,
'backupCount': 3,
'formatter': 'standard',
},
},
'loggers': {
'start': {
'handlers': ['start'],
'level': 'DEBUG',
'propagate': True,
},
},
}
ROOT_URL = 'http://localhost:8800/'
# 主程序中django的主頁(yè)的url
INDEX_URL = '%sstatic/index.html' % ROOT_URL
- 源文件entry\entry.py:
#!/usr/bin/env python
import os, time
import traceback
import subprocess
from subprocess import Popen
from LoggerHelper import logger
from Configs import BASE_PATH, DJANGO_ARGS, DJANGO_PROCESS_ID, ROOT_URL, INDEX_URL, DJANGO_PORT
import webbrowser
import requests
import win32api, win32con
# 檢查服務(wù)進(jìn)程是否啟動(dòng),默認(rèn)嘗試1次
def check_server(retry=1):
print('檢查服務(wù)是否啟動(dòng) ...')
ret = False
while retry > 0 and not ret:
try:
r = requests.get(ROOT_URL, timeout=2)
ret = (r.status_code == requests.codes.ok)
except requests.HTTPError as exp:
logger.error('服務(wù)器返回了異常:%s' % exp)
ret = False
except (requests.Timeout, requests.ConnectionError) as exp:
logger.error('網(wǎng)頁(yè)連接超時(shí)或連接失?。?s' % exp)
ret = False
except (requests.RequestException, Exception) as exp:
logger.error('發(fā)現(xiàn)未處理的異常:%s' % exp)
ret = False
retry = retry - 1
print('%s' % ret)
return ret
# 啟動(dòng)服務(wù)進(jìn)程
def start_server():
ret = None
try:
print('檢查進(jìn)程是否存在 ...')
ret = os.system('netstat -an | find "%d"' % DJANGO_PORT)
if ret == 0:
ret = os.system('tasklist | find "%s"' % DJANGO_PROCESS_ID)
if ret == 0:
print('強(qiáng)制結(jié)束老進(jìn)程 ...')
os.system('TASKKILL /F /IM %s' % DJANGO_PROCESS_ID)
time.sleep(0.5)
url = os.path.join(BASE_PATH, '..', 'Hello', r'Hello.exe')
logger.info('開(kāi)始啟動(dòng)服務(wù) ... %s' % url)
print('開(kāi)始啟動(dòng)服務(wù) ... ')
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
ret = Popen('%s %s' % (url, DJANGO_ARGS), startupinfo=startupinfo)
except Exception as exp:
logger.error('Error : %s, Detail : %s' % (exp, traceback.format_exc()))
return ret
# 打開(kāi)主頁(yè),為后續(xù)實(shí)現(xiàn)雙擊exe可執(zhí)行文件能自動(dòng)打開(kāi)瀏覽器網(wǎng)頁(yè)作準(zhǔn)備
def start_url(url):
ret = None
try:
logger.info('start url ... %s' % url)
ret = webbrowser.open(url, new=2, autoraise=True)
time.sleep(2)
maxWindow()
except Exception as exp:
logger.error('Error : %s, Detail : %s' % (exp, traceback.format_exc()))
return ret
# 瀏覽器中全屏,使用按鍵進(jìn)行模擬
def maxWindow():
win32api.keybd_event(122,0,0,0) #F11
win32api.keybd_event(122, 0, win32con.KEYEVENT_KEYUP,0) #Realize the F11 button
if __name__ == "__main__":
logger.info('start server ...')
if check_server():
start_url(INDEX_URL)
elif start_server() is not None:
if check_server(30):
start_url(INDEX_URL)
else:
logger.error('ERROR : 服務(wù)未成功啟動(dòng),請(qǐng)手工殺死進(jìn)程LotServer.exe,再嘗試啟動(dòng)!')
print('ERROR : 服務(wù)未成功啟動(dòng),請(qǐng)手工殺死進(jìn)程LotServer.exe,再嘗試啟動(dòng)!')
else:
print('ERROR : 服務(wù)啟動(dòng)過(guò)程中發(fā)生異常,請(qǐng)先手工清理相關(guān)進(jìn)程,再嘗試啟動(dòng)!')
start_url(os.path.join(BASE_PATH, 'error.html'))
logger.info('end start!')
- 源文件entry\entry.spec:
# -*- mode: python -*-
block_cipher = None
a = Analysis(['entry.py'],
pathex=['E:\\entry'],
binaries=[],
datas=[('error.html','.')],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='entry',
debug=False,
strip=False,
upx=True,
console=True, icon='logo.ico')
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='entry')
- 源文件entry\LoggerHelper.py(記錄日志):
import sys, os
import logging
from logging.config import dictConfig
from Configs import APP_TMP_DIR, APP_LOGGING
## config the logging
#log_dir = os.path.join(APP_TMP_DIR, 'logs') ## os.getenv('SYSTEMROOT') + '\\..\\LOTS'
try:
if not os.path.exists(APP_TMP_DIR):
os.makedirs(APP_TMP_DIR)
except Exception as exp:
print('ERROR : Create Dir %s failed.' % APP_TMP_DIR)
sys.exit(1)
try:
dictConfig(APP_LOGGING)
except Exception as exp:
print('%s' % exp)
logger = logging.getLogger('start')
global __FIST_TIME
__FIST_TIME = True
if __FIST_TIME:
#sys.stderr.write = lambda s: logger.error(s)
#sys.stdout.write = lambda s: logger.info(s)
__FIST_TIME = False
if __name__ == '__main__':
logger.error("test-error")
logger.info("test-info")
logger.warn("test-warn")
- 源文件entry\error.html文件隨意寫(xiě),主要為提示用戶當(dāng)程序啟動(dòng)不了時(shí)應(yīng)如何處理。
3.2、編譯/啟動(dòng)工程entry
E:\entry>pyinstaller -y entry.spec
E:\entry>dist\entry\entry.exe
便可啟動(dòng)服務(wù)進(jìn)程了。
四、最后的安裝包Inno Setup Compiler
??前面已經(jīng)將helloworld(django工程)和entry(普通工程)打包成相應(yīng)的hello和entry目錄,剩下的就是使用Inno setup將這些可執(zhí)行文件統(tǒng)一打包并進(jìn)行安裝。
4.1、安裝向?qū)etup.iss:
4.2、中文的安裝向?qū)В?/h4>
需將Inno Setup安裝目錄(如D:\Program Files (x86)\Inno Setup 5\Languages)里添加一個(gè)ChineseSimplified.isl文件(此文件內(nèi)容來(lái)自網(wǎng)絡(luò)):
; *** Inno Setup version 5.5.3+ Chinese (Simplified) messages ***
; By Qiming Li (qiming at clault.com)
;
; To download user-contributed translations of this file, go to:
; http://www.jrsoftware.org/files/istrans/
;
; Note: When translating this text, do not add periods (.) to the end of
; messages that didn't have them already, because on those messages Inno
; Setup adds the periods automatically (appending a period would result in
; two periods being displayed).
[LangOptions]
; The following three entries are very important. Be sure to read and
; understand the '[LangOptions] section' topic in the help file.
LanguageName=<4E2D><6587><FF08><7B80><4F53><FF09>
LanguageID=$0804
LanguageCodePage=936
; If the language you are translating to requires special font faces or
; sizes, uncomment any of the following entries and change them accordingly.
DialogFontName=宋體
;DialogFontSize=8
;WelcomeFontName=Verdana
;WelcomeFontSize=12
;TitleFontName=Arial
;TitleFontSize=29
;CopyrightFontName=Arial
;CopyrightFontSize=8
[Messages]
; *** Application titles
SetupAppTitle=安裝向?qū)?SetupWindowTitle=安裝向?qū)?- %1
UninstallAppTitle=卸載向?qū)?UninstallAppFullTitle=%1卸載向?qū)?
; *** Misc. common
InformationTitle=信息
ConfirmTitle=確認(rèn)
ErrorTitle=錯(cuò)誤
; *** SetupLdr messages
SetupLdrStartupMessage=安裝向?qū)⒃谀碾娔X上安裝%1。確定要繼續(xù)嗎?
LdrCannotCreateTemp=無(wú)法創(chuàng)建臨時(shí)文件。安裝已終止
LdrCannotExecTemp=無(wú)法運(yùn)行臨時(shí)文件夾中的文件。安裝已終止
; *** Startup error messages
LastErrorMessage=%1.%n%n錯(cuò)誤 %2: %3
SetupFileMissing=安裝目錄中缺失文件%1。請(qǐng)解決該問(wèn)題,或重新獲取一份程序拷貝。
SetupFileCorrupt=安裝文件已被損壞。請(qǐng)重新獲取一份程序拷貝。
SetupFileCorruptOrWrongVer=安裝文件已被損壞,或與本安裝向?qū)О姹静患嫒荨U?qǐng)解決該問(wèn)題,或重新獲取一份程序拷貝。
InvalidParameter=無(wú)效命令行參數(shù):%n%n%1
SetupAlreadyRunning=安裝程序已經(jīng)運(yùn)行。
WindowsVersionNotSupported=程序不支持您電腦上運(yùn)行的Windows版本。
WindowsServicePackRequired=程序要求%1 Service Pack %2或更新版本。
NotOnThisPlatform=程序不可在%1上運(yùn)行。
OnlyOnThisPlatform=程序必須在%1上運(yùn)行。
OnlyOnTheseArchitectures=程序只能在為以下處理器架構(gòu)所設(shè)計(jì)的Windows版本上安裝:%n%n%1
MissingWOW64APIs=您所使用的Windows版本沒(méi)有包含進(jìn)行64位安裝所需的功能。請(qǐng)安裝Service Pack %1解決此問(wèn)題。
WinVersionTooLowError=程序要求%2版本或以上的%1。
WinVersionTooHighError=程序不可安裝的%2或更高版本的%1上。
AdminPrivilegesRequired=您必須登錄為管理員才能安裝此程序。
PowerUserPrivilegesRequired=您必須登錄為管理員或高權(quán)限用戶才能安裝此程序。
SetupAppRunningError=安裝向?qū)z測(cè)到%1正在運(yùn)行。%n%n請(qǐng)關(guān)閉其所有窗口并點(diǎn)擊“確定”繼續(xù),或點(diǎn)擊“取消”退出安裝。
UninstallAppRunningError=卸載向?qū)z測(cè)到%1正在運(yùn)行。%n%n請(qǐng)關(guān)閉其所有窗口,然后點(diǎn)擊“確定”繼續(xù),或點(diǎn)擊“取消”退出。
; *** Misc. errors
ErrorCreatingDir=安裝向?qū)o(wú)法創(chuàng)建文件夾“%1”
ErrorTooManyFilesInDir=由于文件夾“%1”中文件過(guò)多,無(wú)法在其中創(chuàng)建文件
; *** Setup common messages
ExitSetupTitle=退出安裝向?qū)?ExitSetupMessage=安裝尚未完成。如果現(xiàn)在退出,程序?qū)⒉粫?huì)被安裝。 %n%n您可以下次再運(yùn)行安裝向?qū)?lái)完成程序的安裝。%n%n確定退出安裝向?qū)幔?AboutSetupMenuItem=關(guān)于安裝向?qū)?&A)…
AboutSetupTitle=關(guān)于安裝向?qū)?AboutSetupMessage=%1版本%2%n%3%n%n%1主頁(yè):%n%4
AboutSetupNote=
TranslatorNote=
; *** Buttons
ButtonBack=< 上一步(&B)
ButtonNext=下一步(&N) >
ButtonInstall=安裝(&I)
ButtonOK=確定
ButtonCancel=取消
ButtonYes=是(&Y)
ButtonYesToAll=全選是(&A)
ButtonNo=否(&N)
ButtonNoToAll=全選否(&O)
ButtonFinish=結(jié)束(&F)
ButtonBrowse=瀏覽(&B)…
ButtonWizardBrowse=瀏覽(&R)…
ButtonNewFolder=創(chuàng)建文件夾(&M)
; *** "Select Language" dialog messages
SelectLanguageTitle=選擇語(yǔ)言
SelectLanguageLabel=選擇安裝時(shí)使用語(yǔ)言:
; *** Common wizard text
ClickNext=點(diǎn)擊“下一步”繼續(xù),或“取消”退出安裝向?qū)А?BeveledLabel=
BrowseDialogTitle=瀏覽選擇文件夾
BrowseDialogLabel=在以下列表中選取一個(gè)文件夾,并點(diǎn)擊“確定”。
NewFolderName=新建文件夾
; *** "Welcome" wizard page
WelcomeLabel1=歡迎使用[name]安裝向?qū)?WelcomeLabel2=本向?qū)⒃谀碾娔X上安裝[name/ver]%n%n建議您在繼續(xù)之前關(guān)閉其他所有應(yīng)用程序。
; *** "Password" wizard page
WizardPassword=密碼
PasswordLabel1=本安裝程序由密碼保護(hù)。
PasswordLabel3=請(qǐng)輸入密碼,并點(diǎn)擊“下一步”。密碼區(qū)分大小寫(xiě)。
PasswordEditLabel=密碼(&P):
IncorrectPassword=您輸入的密碼不正確。請(qǐng)重試。
; *** "License Agreement" wizard page
WizardLicense=許可協(xié)議
LicenseLabel=請(qǐng)閱讀以下重要信息,然后再進(jìn)入下一步。
LicenseLabel3=請(qǐng)閱讀以下許可協(xié)議。您必須接受此協(xié)議的條款,然后才能繼續(xù)安裝。
LicenseAccepted=我接受協(xié)議(&A)
LicenseNotAccepted=我不接受協(xié)議(&D)
; *** "Information" wizard pages
WizardInfoBefore=信息
InfoBeforeLabel=請(qǐng)閱讀以下重要信息再進(jìn)入下一步。
InfoBeforeClickLabel=準(zhǔn)備好繼續(xù)安裝后,點(diǎn)擊“下一步”。
WizardInfoAfter=信息
InfoAfterLabel=請(qǐng)閱讀以下重要信息再進(jìn)入下一步。
InfoAfterClickLabel=準(zhǔn)備好繼續(xù)安裝后,點(diǎn)擊“下一步”。
; *** "User Information" wizard page
WizardUserInfo=用戶信息
UserInfoDesc=請(qǐng)輸入您的信息
UserInfoName=用戶名稱(&U):
UserInfoOrg=機(jī)構(gòu)名稱(&O):
UserInfoSerial=序列號(hào)碼(&S):
UserInfoNameRequired=必須輸入用戶名
; *** "Select Destination Location" wizard page
WizardSelectDir=選擇安裝位置
SelectDirDesc=將[name]安裝到何處?
SelectDirLabel3=安裝向?qū)裑name]安裝到以下文件夾中。
SelectDirBrowseLabel=點(diǎn)擊“下一步”繼續(xù)。如果您要選擇不同的文件夾,請(qǐng)點(diǎn)擊“瀏覽”。
DiskSpaceMBLabel=必須至少有[mb]兆字節(jié)(MB)的閑置磁盤(pán)空間。
CannotInstallToNetworkDrive=無(wú)法安裝至網(wǎng)絡(luò)驅(qū)動(dòng)器。
CannotInstallToUNCPath=無(wú)法安裝至UNC路徑。
InvalidPath=您必須輸入包括盤(pán)符的完整路徑,例如:%n%nC:\應(yīng)用程序%n%n或如下格式的UNC路徑:%n%n\\服務(wù)器名\共享目錄名
InvalidDrive=您選擇的驅(qū)動(dòng)器或UNC共享不存在或不可訪問(wèn)。請(qǐng)另選一個(gè)。
DiskSpaceWarningTitle=磁盤(pán)空間不足
DiskSpaceWarning=必須至少有%1千字節(jié)(KB)的閑置空間才可安裝,但所選驅(qū)動(dòng)器僅有%2千字節(jié)(KB)可用空間。%n%n您確定要繼續(xù)嗎?
DirNameTooLong=文件夾名稱或路徑太長(zhǎng)。
InvalidDirName=文件夾名稱無(wú)效。
BadDirName32=文件夾名稱不能包含下列字符:%n%n%1
DirExistsTitle=文件夾已存在
DirExists=文件夾%n%n%1%n%n已存在。您確定要安裝到該文件夾嗎?
DirDoesntExistTitle=文件夾不存在
DirDoesntExist=文件夾%n%n%1%n%n不存在。您要?jiǎng)?chuàng)建該文件夾嗎?
; *** "Select Components" wizard page
WizardSelectComponents=選擇組件
SelectComponentsDesc=要安裝哪些組件?
SelectComponentsLabel2=請(qǐng)選擇要安裝的組件,清除不要安裝的組件。準(zhǔn)備好后點(diǎn)擊“下一步”。
FullInstallation=全部安裝
; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language)
CompactInstallation=簡(jiǎn)潔安裝
CustomInstallation=自定義安裝
NoUninstallWarningTitle=組件已存在
NoUninstallWarning=安裝向?qū)z測(cè)到已經(jīng)安裝下列組件:%n%n%1%n%n取消選定不會(huì)卸載這些組件。%n%n您確定要繼續(xù)安裝嗎?
ComponentSize1=%1千字節(jié)(KB)
ComponentSize2=%1兆字節(jié)(MB)
ComponentsDiskSpaceMBLabel=目前所選組件要求至少[mb]兆字節(jié)(MB)磁盤(pán)空間。
; *** "Select Additional Tasks" wizard page
WizardSelectTasks=選擇附加任務(wù)
SelectTasksDesc=要執(zhí)行哪些附加任務(wù)?
SelectTasksLabel2=請(qǐng)選擇安裝[name]時(shí)需要執(zhí)行的附加任務(wù),然后點(diǎn)擊“下一步”。
; *** "Select Start Menu Folder" wizard page
WizardSelectProgramGroup=選擇開(kāi)始菜單文件夾
SelectStartMenuFolderDesc=把程序快捷方式放到哪里?
SelectStartMenuFolderLabel3=安裝向?qū)⒃谝韵麻_(kāi)始菜單文件夾中創(chuàng)建程序快捷方式。
SelectStartMenuFolderBrowseLabel=點(diǎn)擊“下一步”繼續(xù)。如要選擇另一個(gè)文件夾,點(diǎn)擊“瀏覽”。
MustEnterGroupName=您必須輸入文件夾名稱
GroupNameTooLong=文件夾名稱或路徑太長(zhǎng)。
InvalidGroupName=文件夾名稱無(wú)效。
BadGroupName=文件夾名稱不能包含下列字符:%n%n%1
NoProgramGroupCheck2=不要?jiǎng)?chuàng)建開(kāi)始菜單文件夾(&D)
; *** "Ready to Install" wizard page
WizardReady=安裝準(zhǔn)備完畢
ReadyLabel1=安裝向?qū)б褱?zhǔn)備完畢,將開(kāi)始在您的電腦上安裝[name]。
ReadyLabel2a=點(diǎn)擊“安裝”開(kāi)始安裝。如要確認(rèn)或更改設(shè)置請(qǐng)點(diǎn)擊“上一步”。
ReadyLabel2b=點(diǎn)擊“安裝”開(kāi)始安裝。
ReadyMemoUserInfo=用戶信息:
ReadyMemoDir=安裝位置:
ReadyMemoType=安裝類型:
ReadyMemoComponents=所選組件:
ReadyMemoGroup=開(kāi)始菜單文件夾:
ReadyMemoTasks=附加任務(wù):
; *** "Preparing to Install" wizard page
WizardPreparing=準(zhǔn)備安裝
PreparingDesc=安裝向?qū)д跍?zhǔn)備在您的電腦上安裝[name]。
PreviousInstallNotCompleted=上次程序安裝/卸載未能完成。您需要重啟電腦來(lái)完成上次安裝。%n%n電腦重啟之后,請(qǐng)重新運(yùn)行安裝向?qū)?lái)安裝[name]。
CannotContinue=安裝無(wú)法繼續(xù)。請(qǐng)點(diǎn)擊“取消”退出。
ApplicationsFound=安裝向?qū)枰碌奈募幌铝袘?yīng)用程序占用。建議允許安裝向?qū)ё詣?dòng)關(guān)閉這些應(yīng)用程序。
ApplicationsFound2=安裝向?qū)枰碌奈募幌铝袘?yīng)用程序占用。建議允許安裝向?qū)ё詣?dòng)關(guān)閉這些應(yīng)用程序。安裝完成后,安裝向?qū)L試重新啟動(dòng)這些應(yīng)用程序。
CloseApplications=自動(dòng)關(guān)閉應(yīng)用程序(&A)
DontCloseApplications=不自動(dòng)關(guān)閉應(yīng)用程序(&D)
ErrorCloseApplications=安裝向?qū)o(wú)法自動(dòng)關(guān)閉所有的應(yīng)用程序。在進(jìn)入下一步之前,建議您關(guān)閉那些占用安裝向?qū)枰挛募膽?yīng)用程序。
; *** "Installing" wizard page
WizardInstalling=正在安裝
InstallingLabel=請(qǐng)稍候,安裝向?qū)д谀碾娔X上安裝[name]。
; *** "Setup Completed" wizard page
FinishedHeadingLabel=[name]安裝完成
FinishedLabelNoIcons=安裝向?qū)б言谀碾娔X上安裝[name]。
FinishedLabel=安裝向?qū)б言谀碾娔X上安裝[name]??梢酝ㄟ^(guò)已安裝的快捷方式來(lái)打開(kāi)此應(yīng)用程序。
ClickFinish=點(diǎn)擊“結(jié)束”退出安裝。
FinishedRestartLabel=為了完成[name]的安裝,安裝向?qū)П仨氈貑⒛碾娔X。要立即重啟嗎?
FinishedRestartMessage=為了完成[name]的安裝,安裝向?qū)П仨氈貑⒛碾娔X。%n%n要立即重啟嗎?
ShowReadmeCheck=是,我要閱讀自述文件
YesRadio=是,立即重啟電腦(&Y)
NoRadio=否,稍后我再重啟電腦(&N)
; used for example as 'Run MyProg.exe'
RunEntryExec=運(yùn)行%1
; used for example as 'View Readme.txt'
RunEntryShellExec=查閱%1
; *** "Setup Needs the Next Disk" stuff
ChangeDiskTitle=安裝向?qū)枰乱粡埓疟P(pán)
SelectDiskLabel2=請(qǐng)插入磁盤(pán)%1 并點(diǎn)擊“確定”。%n%n如果該磁盤(pán)中的文件并不在以下所示文件夾中,請(qǐng)輸入正確的路徑或點(diǎn)擊“瀏覽”。
PathLabel=路徑(&P):
FileNotInDir2=文件“%1”不在“%2”中。請(qǐng)插入正確的磁盤(pán)或選擇其它文件夾。
SelectDirectoryLabel=請(qǐng)指定下一張磁盤(pán)的位置。
; *** Installation phase messages
SetupAborted=安裝未能完成。%n%n請(qǐng)解決問(wèn)題后再重新運(yùn)行安裝向?qū)А?EntryAbortRetryIgnore=點(diǎn)擊“重試”重新嘗試,點(diǎn)擊“忽略”繼續(xù)安裝,或點(diǎn)擊“中止”取消安裝。
; *** Installation status messages
StatusClosingApplications=正在關(guān)閉應(yīng)用程序…
StatusCreateDirs=正在創(chuàng)建文件夾…
StatusExtractFiles=正在取出文件…
StatusCreateIcons=正在創(chuàng)建快捷方式…
StatusCreateIniEntries=正在創(chuàng)建INI條目…
StatusCreateRegistryEntries=正在創(chuàng)建注冊(cè)表?xiàng)l目…
StatusRegisterFiles=正在創(chuàng)建注冊(cè)表項(xiàng)目…
StatusSavingUninstall=正在保存卸載信息…
StatusRunProgram=正在結(jié)束安裝…
StatusRestartingApplications=正在重啟應(yīng)用程序…
StatusRollback=正在撤銷更改…
; *** Misc. errors
ErrorInternal2=內(nèi)部錯(cuò)誤:%1
ErrorFunctionFailedNoCode=%1失敗
ErrorFunctionFailed=%1失敗,錯(cuò)誤碼%2
ErrorFunctionFailedWithMessage=%1失敗,錯(cuò)誤碼%2。%n%3
ErrorExecutingProgram=無(wú)法運(yùn)行程序:%n%1
; *** Registry errors
ErrorRegOpenKey=打開(kāi)注冊(cè)表鍵時(shí)出錯(cuò):%n%1\%2
ErrorRegCreateKey=創(chuàng)建注冊(cè)表鍵時(shí)出錯(cuò):%n%1\%2
ErrorRegWriteKey=寫(xiě)入注冊(cè)表鍵時(shí)出錯(cuò):%n%1\%2
; *** INI errors
ErrorIniEntry=在文件“%1”中創(chuàng)建INI條目時(shí)出錯(cuò)。
; *** File copying errors
FileAbortRetryIgnore=點(diǎn)擊“重試”重新嘗試,點(diǎn)擊“忽略”跳過(guò)此文件(不推薦這樣做),或點(diǎn)擊“中止”取消安裝。
FileAbortRetryIgnore2=點(diǎn)擊“重試”重新嘗試,點(diǎn)擊“忽略”繼續(xù)安裝(不推薦這樣做),或點(diǎn)擊“中止”取消安裝。
SourceIsCorrupted=源文件已損壞
SourceDoesntExist=源文件“%1”不存在
ExistingFileReadOnly=現(xiàn)有文件被標(biāo)記為只讀。%n%n點(diǎn)擊“重試”移除其只讀屬性并重新嘗試,點(diǎn)擊“忽略”跳過(guò)此文件,或點(diǎn)擊“中止”取消安裝。
ErrorReadingExistingDest=讀取現(xiàn)有文件時(shí)出錯(cuò):
FileExists=文件已存在。%n%n讓安裝向?qū)Ц采w它嗎?
ExistingFileNewer=現(xiàn)有文件比安裝向?qū)г噲D安裝的還要新。建議保留現(xiàn)有文件。%n%n您要保留現(xiàn)有文件嗎?
ErrorChangingAttr=更改現(xiàn)有文件屬性時(shí)出錯(cuò):
ErrorCreatingTemp=在目的文件夾中創(chuàng)建文件時(shí)出錯(cuò):
ErrorReadingSource=讀取源文件時(shí)出錯(cuò):
ErrorCopying=復(fù)制文件時(shí)出錯(cuò):
ErrorReplacingExistingFile=替換現(xiàn)有文件時(shí)出錯(cuò):
ErrorRestartReplace=重啟替換失?。?ErrorRenamingTemp=為目的文件夾中文件重命名時(shí)出錯(cuò):
ErrorRegisterServer=無(wú)法注冊(cè)動(dòng)態(tài)庫(kù)或控件(DLL/OCX):%1
ErrorRegSvr32Failed=運(yùn)行RegSvr32失敗,其返回值為:%1
ErrorRegisterTypeLib=無(wú)法注冊(cè)類型庫(kù):%1
; *** Post-installation errors
ErrorOpeningReadme=打開(kāi)自述文件時(shí)出錯(cuò)。
ErrorRestartingComputer=安裝向?qū)o(wú)法重啟電腦。請(qǐng)手動(dòng)重啟。
; *** Uninstaller messages
UninstallNotFound=文件“%1”不存在。無(wú)法卸載。
UninstallOpenError=無(wú)法打開(kāi)文件“%1”。無(wú)法卸載
UninstallUnsupportedVer=此版本的卸載向?qū)o(wú)法識(shí)別卸載日志文件“%1”的格式。無(wú)法卸載
UninstallUnknownEntry=在卸載日志中遇到未知條目 (%1)
ConfirmUninstall=您是否確定要完全刪除%1及其所有組件?
UninstallOnlyOnWin64=此安裝只能在64位Windows上卸載。
OnlyAdminCanUninstall=此安裝只能由具備管理員權(quán)限的用戶卸載。
UninstallStatusLabel=請(qǐng)稍候,正在刪除%1。
UninstalledAll=已成功地從您的電腦中刪除%1。
UninstalledMost=%1卸載完畢。%n%n某些項(xiàng)目無(wú)法在卸載過(guò)程中刪除??梢允謩?dòng)刪除這些項(xiàng)目。
UninstalledAndNeedsRestart=若要完成%1的卸載,必須重啟電腦。%n%n要立即重啟嗎?
UninstallDataCorrupted=文件“%1”已損壞。無(wú)法卸載
; *** Uninstallation phase messages
ConfirmDeleteSharedFileTitle=刪除共享文件嗎?
ConfirmDeleteSharedFile2=系統(tǒng)顯示沒(méi)有任何程序使用以下共享文件。要?jiǎng)h除該共享文件嗎?%n%n如果有程序使用該文件,當(dāng)它被刪除后這些程序可能無(wú)法正常運(yùn)行。如果不確定,請(qǐng)選擇“否”。留下該文件不會(huì)對(duì)系統(tǒng)造成任何危害。
SharedFileNameLabel=文件名:
SharedFileLocationLabel=位置:
WizardUninstalling=卸載狀態(tài)
StatusUninstalling=正在卸載%1…
; *** Shutdown block reasons
ShutdownBlockReasonInstallingApp=正在安裝%1。
ShutdownBlockReasonUninstallingApp=正在卸載%1。
; The custom messages below aren't used by Setup itself, but if you make
; use of them in your scripts, you'll want to translate them.
[CustomMessages]
NameAndVersion=%1版本%2
AdditionalIcons=附加快捷方式:
CreateDesktopIcon=創(chuàng)建桌面快捷方式(&D)
CreateQuickLaunchIcon=創(chuàng)建快速啟動(dòng)欄快捷方式(&Q)
ProgramOnTheWeb=%1網(wǎng)站
UninstallProgram=卸載%1
LaunchProgram=運(yùn)行%1
AssocFileExtension=將%1與%2文件擴(kuò)展名關(guān)聯(lián)(&A)
AssocingFileExtension=正在將%1與%2文件擴(kuò)展名關(guān)聯(lián)…
AutoStartProgramGroupDescription=啟動(dòng):
AutoStartProgram=自動(dòng)啟動(dòng)%1
AddonHostProgramNotFound=在您所選文件夾中找不到%1。%n%n是否仍然繼續(xù)?