将UAC设置为需要pipe理员使用PyInstaller onefile选项和清单

好的,我一直在努力弄清楚这个问题。 我使用-i -F -w和-m选项使用PyInstaller版本2.0构build名为GraphicScriptWizard.exe的应用程序。

我已经定义了与-m选项一起使用的清单文件叫做GraphicScriptWizard.exe.manifest ,它包含以下内容:

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity version="1.0.0.0" processorArchitecture="x86" name="GraphicScriptWizard" type="win32"/> <!-- Identify the application security requirements. --> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> <security> <requestedPrivileges> <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/> </requestedPrivileges> </security> </trustInfo> </assembly> 

使用这个清单和命令行选项,我没有得到一个提示升级的可执行文件。

为了完整起见,Pyinstaller生成的spec文件是:

 # -*- mode: python -*- a = Analysis(['GraphicScriptWizard.py'], pathex=[<Full Development Path>], hiddenimports=[], hookspath=None) pyz = PYZ(a.pure) exe = EXE(pyz, a.scripts, a.binaries, a.zipfiles, a.datas, name=os.path.join('dist', 'GraphicScriptWizard.exe'), debug=False, strip=None, upx=True, console=False , icon='SP.ico', manifest='GraphicScriptWizard.exe.manifest') app = BUNDLE(exe, name=os.path.join('dist', 'GraphicScriptWizard.exe.app')) 

我已经尝试编译与pyinstaller没有-m选项,并使用命令mtembedded:

 mt.exe -manifest GraphicScriptWizard.exe.manifest -outputresource:GraphicScriptWizard.exe;#1 

当我这样做时,应用程序会提示我进行提升,但程序运行时出现错误:

"Cannot open self <Full path to exe>\GraphicScriptWizard.exe or archive..."

我真的在智慧的结尾,希望对Windows资源和清单更加熟悉的人可以为我更多的了解这一点。 我的清单XML错了吗? 我的Pyinstaller方法错了吗?

Solutions Collecting From Web of "将UAC设置为需要pipe理员使用PyInstaller onefile选项和清单"

我刚刚走了这条路,这里是我的观察和经验。

首先要知道的是有两个有效的清单位置:

  1. 嵌入在可执行文件(或dll)作为资源

  2. 在可执行文件(或dll)旁边,就像你现在正在做的那样。

在这里阅读有关清单: http : //msdn.microsoft.com/en-us/library/windows/desktop/aa374191(v=vs.85).aspx

根据我的经验,您可以同时使用两者,但是如果有重叠,则嵌入式清单优先。 这是搞砸了你。 Pyinstaller创建的可执行文件有一个嵌入式清单,它将请求的执行级别设置为“asInvoker”,它覆盖了正在使用的清单中的级别。

–manifest(或EXE()清单参数)只是修改Pyinstaller放置在可执行文件/ dll旁边的清单,而不是嵌入式清单。

所以,我们可以转向mt.exe来更改嵌入式清单,但正如您发现的那样,这会导致无法运行的应用程序。 这是因为Pyinstaller创建的应用程序实际上是两个部分; 一个小的可执行文件,提取一个档案,然后在其捆绑的python环境中设置并启动你的代码,并执行可执行文件。 这是可行的,因为可执行文件的规范允许将任意数据附加到可执行文件的末尾,但在可执行文件本身之外,正如可执行文件头中记录的大小所定义的那样。 当我们在Pyinstaller创建的可执行文件上运行mt.exe时,它会查看头文件以获取大小,并忽略超出该大小的任何内容,从而在保存带有新清单的可执行文件时丢弃该存档数据,从而导致出现错误看到。

我使用的解决方案是在归档数据被追加到可执行文件之前修改清单,这需要修改Pyinstaller源代码。 Pyinstaller源程序有实用程序来更新可执行文件/ dll中的资源,它将作为其构建过程的一部分使用。 你会想看看build.pywinmanifest.py ,也许winresource.py在你的Pyinstaller的位置。 我向EXE类中添加了一个参数,然后在该类的汇编方法中的一个步骤来更新清单,在添加归档之前我这样做。 我添加的肉是这样的:

 if self.manifest_override != None: print "Overriding default manifest" tmpnm = tempfile.mktemp() shutil.copy2(exe, tmpnm) os.chmod(tmpnm, 0755) winmanifest.UpdateManifestResourcesFromXMLFile(tmpnm, self.manifest_override, names=[1], languages=[1033]) exe = tmpnm trash.append(tmpnm) 

我已经把它放在exe = checkCache(exe, ...的行之前,它应该在上面,但接近print "Appending archive to EXE"...

这个解决方案一直在为我工作,但我并不是很满意。 我宁愿重写嵌入的默认清单,而不是更新它,但是迄今为止,我的努力没有取得成果。

对不起,对文本的墙壁,但有很多事情在这里。

不是一个完整的解决方案,但也许是一个有用的提示。

Python 2.7.5 AMD64不能与上面的Manifest文件一起工作Python 2.7.5 32位工作得很好。

所以也许这只是由于Python版本的限制。