python写魔兽世界脚本_用python bat写软件安装脚本 + HM NIS Edit自动生成软件安装脚本...
2019-03-11更新:原來(lái)NSIS腳本也可以禁用64位文件操作重定向的!
1、在安裝腳本的開(kāi)始處定義 LIBRARY_X64。
!include "MUI.nsh"
!include "Library.nsh"
;如果做32位安裝包就把下句注釋。
!define LIBRARY_X64
2、在調(diào)用涉及目標(biāo)機(jī)器上系統(tǒng)目錄(即$SYSDIR)的函數(shù)前用 ${DisableX64FSRedirection}。
在安裝包的第一個(gè)Section中調(diào)用一次即可。
!ifdef LIBRARY_X64
${DisableX64FSRedirection}
!endif
之前問(wèn)題主要在于64位重定向問(wèn)題,所以自己用python寫(xiě)了個(gè)腳本。找到了NSIS禁用重定向方法就可以無(wú)論32位還是64位都可以使用NSIS來(lái)寫(xiě)腳本了。
原文:
前些天自己做了一年多的軟件成功交付客戶(hù),客戶(hù)提出些完善意見(jiàn),其中一條就是要一個(gè)軟件安裝腳本。
這個(gè)之前也嘗試python做過(guò),只不過(guò)當(dāng)時(shí)有更緊急的任務(wù),最后就沒(méi)深入嘗試。
這次我就撿起了之前的python工程,繼續(xù)做做。
整個(gè)過(guò)程很簡(jiǎn)單:
1,把軟件解壓到客戶(hù)選擇的目錄
2,把一個(gè)dll程序復(fù)制到windows\system32目錄
3,創(chuàng)建一個(gè)桌面快捷方式
因?yàn)榫瓦@么幾步,所以我以為很容易搞,就選擇了久違的python自己寫(xiě),而沒(méi)有選擇一些成熟的自動(dòng)生成腳本工具。
首先肯定要有個(gè)界面吧,主要是要用戶(hù)選擇安裝目錄。我用Tkinter寫(xiě)了個(gè)簡(jiǎn)陋的界面,這個(gè)不多說(shuō)。
解壓壓縮包的話(huà),python有很好的庫(kù)zipfile:
def unzip(zipFilePath, destDir):
zfile = zipfile.ZipFile(zipFilePath)
for name in zfile.namelist():
(dirName, fileName) = os.path.split(name)
if fileName == '':
# directory
newDir = destDir + '/' + dirName
if not os.path.exists(newDir):
os.mkdir(newDir)
else:
# file
fd = open(destDir + '/' + name, 'wb')
fd.write(zfile.read(name))
fd.close()
zfile.close()
創(chuàng)建桌面快捷方式python肯定也有庫(kù),但我最后選擇了使用bat腳本。
set Program=這里要寫(xiě)快捷方式對(duì)應(yīng)的程序目錄,且必須是絕對(duì)路徑。
在python里將這個(gè)路徑填寫(xiě)上,然后程序里運(yùn)行bat腳本即可。
@ echo off
set Program=
set LnkName=manager software
set WorkDir=
set Desc=soft
if not defined WorkDir call:GetWorkDir "%Program%"
(echo Set WshShell=CreateObject("WScript.Shell"^)
echo strDesKtop=WshShell.SpecialFolders("DesKtop"^)
echo Set oShellLink=WshShell.CreateShortcut(strDesKtop^&"\%LnkName%.lnk"^)
echo oShellLink.TargetPath="%Program%"
echo oShellLink.WorkingDirectory="%WorkDir%"
echo oShellLink.WindowStyle=1
echo oShellLink.Description="%Desc%"
echo oShellLink.Save)>makelnk.vbs
echo SUCCESS
makelnk.vbs
del /f /q makelnk.vbs
exit
goto :eof
:GetWorkDir
set WorkDir=%~dp1
set WorkDir=%WorkDir:~,-1%
goto :eof
上面都算順利,最后竟然在本以為很簡(jiǎn)單的復(fù)制文件到系統(tǒng)目錄上出了問(wèn)題。
不管怎樣努力,都沒(méi)法將文件復(fù)制到windows\system32目錄下。
一開(kāi)始本以為是權(quán)限問(wèn)題。
在程序開(kāi)始前加入這樣的代碼:
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
if is_admin():
#主程序代碼
else:
# Re-run the program with admin rights
ctypes.windll.shell32.ShellExecuteW(None, u"runas", unicode(sys.executable), unicode(__file__), None, 1)
這樣在運(yùn)行前就會(huì)彈窗要求獲取管理員權(quán)限。
按道理這樣程序就已經(jīng)有了管理員權(quán)限了,可還是沒(méi)有復(fù)制到system32目錄下。
后來(lái)在同事幫我看這個(gè)問(wèn)題,他弄了一會(huì),發(fā)現(xiàn)其實(shí)是64位系統(tǒng)下,系統(tǒng)自動(dòng)重定向到C:\Windows\SysWOW64目錄下了!
所以一定要在復(fù)制操作前,禁止重定向。
with disable_file_system_redirection():
shutil.copy2('sdfp_lib.dll',os.getenv("SystemDrive")+'\\windows\\system32')
上述,便是用python寫(xiě)我的軟件自動(dòng)安裝腳本的全過(guò)程,后面會(huì)附上我的全部代碼。
我先再講下要實(shí)現(xiàn)這種軟件自動(dòng)安裝腳本需求 最常用最合適的實(shí)現(xiàn)方法。
其實(shí)用工具自動(dòng)生成就好了!
這個(gè)HM NIS Edit工具。
點(diǎn)擊文件,選擇新建腳本向?qū)А?/p>
然后按照向?qū)б话愕陌惭b,基本的安裝需求都可以簡(jiǎn)單實(shí)現(xiàn)。
重點(diǎn)是這一步:
左邊可以添加分組,右邊可以給每個(gè)分組添加安裝指令,可以給組添加單獨(dú)的文件,也可以給組添加主程序目錄。每個(gè)組再配置安裝目標(biāo)目錄。這個(gè)目標(biāo)目錄有很多選擇,包括系統(tǒng)目錄、用戶(hù)選擇目錄…………不贅述。
這個(gè)工具編譯好腳本,就生成了一個(gè)Setup.exe文件。這就是安裝程序。要安裝的軟件文件都包含在這個(gè)exe里了,很厲害。
按道理,只要用這個(gè)工具就可以完成我的需求了,但在64位系統(tǒng)還有些問(wèn)題,那就是依然會(huì)有系統(tǒng)重定向現(xiàn)象。本來(lái)要復(fù)制到system32目錄下的dll還是會(huì)被復(fù)制到C:\Windows\SysWOW64下。
最后我就決定,做兩個(gè)版本。
32位的安裝程序用HM NIS Edit工具自動(dòng)生成。
64位我自己用python寫(xiě)。
另外,python轉(zhuǎn)化成exe文件的寫(xiě)法,之前文章介紹過(guò):
附上py完整代碼:
# -*- coding: utf-8 -*-
from __future__ import print_function
from Tkinter import *
import os
import sys
import subprocess
import shutil
reload(sys)
defaultencoding = 'utf-8'
import ctypes
import tkFileDialog as filedialog
import zipfile
from shutil import copyfile
class disable_file_system_redirection:
_disable = ctypes.windll.kernel32.Wow64DisableWow64FsRedirection
_revert = ctypes.windll.kernel32.Wow64RevertWow64FsRedirection
def __enter__(self):
self.old_value = ctypes.c_long()
self.success = self._disable(ctypes.byref(self.old_value))
def __exit__(self, type, value, traceback):
if self.success:
self._revert(self.old_value)
def unzip(zipFilePath, destDir):
zfile = zipfile.ZipFile(zipFilePath)
for name in zfile.namelist():
(dirName, fileName) = os.path.split(name)
if fileName == '':
# directory
newDir = destDir + '/' + dirName
if not os.path.exists(newDir):
os.mkdir(newDir)
else:
# file
fd = open(destDir + '/' + name, 'wb')
fd.write(zfile.read(name))
fd.close()
zfile.close()
def choose_directory():
global dir_choosen
global dir_choosen2
dir_choosen = filedialog.askdirectory(initialdir='C:')
# unzip my program to directory choosen
dir_choosen2 = dir_choosen
dir_choosen = dir_choosen + '/tgsoft'
if not os.path.exists(dir_choosen):
os.makedirs(dir_choosen)
entryText.set(dir_choosen)
def install():
if dir_choosen2.strip()=='' or dir_choosen.strip()=='':
return -1
unzip('tgsoft.zip',dir_choosen)
with disable_file_system_redirection():
shutil.copy2('sdfp_lib.dll',os.getenv("SystemDrive")+'\\windows\\system32')
str_bat = ''
f = open('CREATE_SHORTCUT.bat', 'r')
line = f.readline()
while line:
str_bat+=line
line = f.readline()
f.close()
nPos=str_bat.index('=')+1
str_bat = str_bat[:nPos]+dir_choosen2+"\\tgsoft\\ManagerSoftware.exe"+str_bat[nPos:]
f = open('CREATE_SHORTCUT2.bat', 'w') # 若是'wb'就表示寫(xiě)二進(jìn)制文件
f.write(str_bat)
f.close()
child = subprocess.Popen('CREATE_SHORTCUT2.bat',shell=False)
# reset the window
file_label.destroy()
file_entry.destroy()
file_btn.destroy()
b2.destroy()
w = Label(master, text="安裝成功\n感謝使用")
w.grid(row=0)
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
if is_admin():
global master
master = Tk()
master.title('指靜脈注冊(cè)軟件安裝程序')
master.geometry('400x100')
global file_label
file_label = Label(master, text="選擇軟件安裝路徑")
file_label.grid(row=0)
global entryText
entryText = StringVar()
global file_entry
file_entry = Entry(master,textvariable=entryText)
file_entry.grid(row=0, column=1)
global file_btn
file_btn = Button(master, text='點(diǎn)擊選擇路徑', command=choose_directory)
file_btn.grid(row=0,column=2)
global b1
b1 = Button(master, text=' 退 出 ', command=master.quit)
b1.grid(row=1,column=0)
global b2
b2 = Button(master, text=' 確 定 ', command=install)
b2.grid(row=1,column=1)
mainloop()
else:
# Re-run the program with admin rights
ctypes.windll.shell32.ShellExecuteW(None, u"runas", unicode(sys.executable), unicode(__file__), None, 1)
總結(jié)
以上是生活随笔為你收集整理的python写魔兽世界脚本_用python bat写软件安装脚本 + HM NIS Edit自动生成软件安装脚本...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 图像重建算法_降噪重建技术路在何方?
- 下一篇: 生活常识与车辆维护的关系是什么?