5

わかりました、私はこれを理解しようとして何度も行ってきました。GraphicScriptWizard.exe-i -F -w および -m オプションを使用して、PyInstaller バージョン 2.0 を使用して呼び出されるアプリケーションを構築しています。

-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'))

-m オプションを指定せずに pyinstaller でコンパイルし、次のコマンドを使用して mt を埋め込んでみました。

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

これを行うと、アプリケーションから昇格のプロンプトが表示されますが、プログラムの実行時にエラーが発生します。

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

私は本当に機知に富んでおり、Windows リソースとマニフェストに精通している人が、これについてもう少し詳しく説明してくれることを望んでいます。私のマニフェスト XML は間違っていますか? Pyinstaller を使用した私の方法論は間違っていますか?

4

2 に答える 2

11

私は自分自身でこの道をたどりました。ここに私の観察と経験があります。

最初に知っておくべきことは、マニフェストには 2 つの有効な場所があることです。

  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 によって作成されたアプリケーションが実際には 2 つの部分であるためです。アーカイブを抽出し、バンドルされた Python 環境でコードをセットアップして起動する小さな実行可能ファイルと、実行可能ファイルが動作するそのアーカイブ。これが機能するのは、実行可能ファイルの仕様では、実行可能ファイルの末尾に任意のデータを追加できるためですが、実行可能ファイル自体の外部では、実行可能ファイルのヘッダーに記録されたサイズで定義されています。Pyinstaller で作成された実行可能ファイルで mt.exe を実行すると、ヘッダーを調べてサイズを取得し、それ以上のものは無視するため、新しいマニフェストで実行可能ファイルを保存するときにそのアーカイブ データが破棄されます。

私が使用している解決策は、アーカイブ データが実行可能ファイルに追加される前にマニフェストを変更することです。これには、Pyinstaller ソース コードの変更が必要です。Pyinstaller ソースには、ビルド プロセスの一部として使用される実行可能ファイル/dll 内のリソースを更新するためのユーティリティがあります。Pyinstallerの場所にあるbuild.pywinmanifest.py、およびおそらくwinresource.pyを確認する必要があります。EXE クラスにパラメーターを追加し、そのクラスの assemble メソッドのステップを追加してマニフェストを更新しました。アーカイブを追加する直前にこれを行います。私が追加した肉は次のようなものです:

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"...

このソリューションは私にとってはうまくいきましたが、あまり満足していません. 埋め込まれたデフォルトのマニフェストを更新するのではなくオーバーライドしたいのですが、これまでのところ、私の努力は実を結んでいません。

テキストの壁で申し訳ありませんが、ここでは多くのことが起こっています。

于 2013-02-01T20:48:44.657 に答える
0

完全な解決策ではありませんが、役立つヒントになるかもしれません。

Python 2.7.5 AMD64 は上記のマニフェスト ファイルでは動作しません Python 2.7.5 32 ビットは問題なく動作します。

したがって、これは Python のバージョンによる制限にすぎない可能性があります。

于 2013-09-30T13:50:38.710 に答える