登録不要のCOMのマニフェストファイルを生成する


87

マニフェストファイルを使用するアプリケーション(ネイティブ、.NET)があり、グローバルCOM登録を必要とせずに完全に分離して展開できます。たとえば、dbgrid32.ocx comサーバーへの依存関係は、myapp.exeと同じフォルダーにあるmyapp.exe.manifestファイルで次のように宣言されています。

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity type="win32" name="myapp.exe" version="1.2.3.4" />
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="dbgrid32.ocx" version="5.1.81.4" />
    </dependentAssembly>
  </dependency>
</assembly>

dbgrid32.ocxは、独自のdbgrid32.ocx.manifestファイルとともに同じフォルダーにデプロイされます。

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity type="win32" name="dbgrid32.ocx" version="5.1.81.4" />
  <file name="dbgrid32.ocx">
     <typelib
        tlbid="{00028C01-0000-0000-0000-000000000046}"
        version="1.0"
        helpdir=""/>
    <comClass progid="MSDBGrid.DBGrid"
       clsid="{00028C00-0000-0000-0000-000000000046}"
       description="DBGrid  Control" />
  </file>
</assembly>

これはすべて正常に機能しますが、これらのマニフェストファイルを手動で維持するのは少し面倒です。これらのファイルを自動的に生成する方法はありますか?理想的には、COMサーバー(ネイティブと.NETの両方)のリストに対するアプリケーションの依存関係を宣言し、残りを自動的に生成させたいと思います。出来ますか?


+1も:そのタグはレジストリフリーCOMでより一般的であるため、regfreecomにタグを付け直しました
MarkJ 2009年

マニフェストファイルで自分のインストールフォルダにあるより高いバージョンのmstscax.dllを使用できますか?
Acewind

@acewindはい。(詳細を記載した新しい質問を投稿することをお勧めします。)
UuDdLrLrSs

@UuDdLrLrSs朗報です!私はここに新しい質問を投稿:stackoverflow.com/questions/63575746/...
Acewind

回答:


63

完璧な解決策はまだ存在していないようです。いくつかの研究を要約すると:

マニフェストを作成するリンク

このツールは、VB6プロジェクトをスキャンしてCOMの依存関係を探しますが、遅延バインドされたCOMの依存関係(つまり、CreateObjectを介して使用される依存関係)の手動宣言もサポートします。

興味深いことに、このツールは、依存関係に関するすべての情報をアプリケーションマニフェスト内に配置します。アプリケーションexeとその依存関係は、複数のファイルで構成される単一のアセンブリとして記述されます。これが可能だとは以前は気づいていませんでした。

非常に優れたツールのように見えますが、バージョン0.6.6以降、次の制限があります。

  • VB6アプリケーションの場合のみ、VB6プロジェクトファイルから開始します。残念ながら、それが行うことの多くは実際にはVB6とは何の関係もありません。
  • ウィザードスタイルのアプリケーション。ビルドプロセスに統合するのには適していません。依存関係があまり変わらなければ、これは大きな問題ではありません。
  • ソースのないフリーウェア。いつでもアバンダンウェアになる可能性があるため、信頼するのは危険です。

.NETcomライブラリをサポートしているかどうかはテストしていません。

PASSWORD42codeprojectリンク

このコマンドラインツールは、ネイティブCOMライブラリのマニフェストファイルを生成します。DllRegisterServerを呼び出してから、レジストリに情報を追加するときに自己登録をスパイします。また、アプリケーションのクライアントマニフェストを生成することもできます。

このユーティリティは、DllRegisterServerルーチンを公開しないため、.NETCOMライブラリをサポートしていません。

ユーティリティはC ++で書かれています。ソースコードが利用可能です。

mt.exe

Visual Studioがインストールされている場合は、Windows SDKの一部(MSDNからダウンロードできます)。それはされてここで記述します。次のように、ネイティブCOMライブラリのマニフェストファイルを生成できます。

mt.exe -tlb:mycomlib.ocx -dll:mycomlib.ocx -out:mycomlib.ocx.manifest

次のように、.NETCOMライブラリのマニフェストファイルを生成できます。

mt.exe -managedassemblyname:netlib.dll -nodependency -out:netlib.dll.manifest

ただし、このツールにはいくつかの問題があります。

  • 最初のスニペットはprogid属性を生成せず、progidでCreateObjectを使用するクライアントを破壊します。
  • 2番目のスニペットは、マニフェストが実際に機能する前に削除する必要のある要素を生成 <runtime><mvid>ます。
  • アプリケーションのクライアントマニフェストの生成はサポートされていません。

将来のSDKリリースでこのツールが改善される可能性があります。WindowsSDK6.0a(vista)でテストしました。


1
mazecomputer.comという1つのオプションを見逃したと思いますが、Webサイトで説明されていないことについては何も知りません。
ボブ

MMMは、非COM(標準)DLLもリダイレクトします。他のツールがこれを行うかどうかはわかりません。
ボブ

神経質な方へのメモ:MMMのソースがリリースされました。欠点としては、これは作者が作業をやめることにしたためと思われます。それでも前向きな兆候。
Gavin 2011

2
MMMのサイトはもう稼働していませんが、ソースコードが配置された場所はv0.9およびv0.12で引き続き使用できます。
スコットチェンバレン

1
上記のように.NETCOMライブラリ用のmt.exeを試したところ、v7.1Aを使用してマニフェストを変更することなく動作しました。また、MMMのリンクは機能しませんでしたが、Unattented Make MyManifestはまともな仕事をしているようです。
bzuillsmith 2016

28

MSBuildタスクGenerateApplicationManifestを使用して、VisualStudioが生成するマニフェストと同じコマンドラインでマニフェストを生成しました。VisualStudioはビルド中にGenerateApplicationManifestを使用していると思われます。以下は、msbuild "msbuildbuild.xml"を使用してコマンドラインから実行できるビルドスクリプトです。

GenerateApplicationManifestタスクを指摘してくれたDaveTemplinと彼の投稿、およびMSDNのタスクに関する詳細なドキュメントに感謝します

build.xml

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="Build">
        <ItemGroup>
            <File Include='MyNativeApp.exe'/>
            <ComComponent Include='Com1.ocx;Com2.ocx'/>
        </ItemGroup>
        <GenerateApplicationManifest
            AssemblyName="MyNativeApp.exe"
            AssemblyVersion="1.0.0.0"
            IsolatedComReferences="@(ComComponent)"
            Platform="x86"
            ManifestType="Native">
            <Output
                ItemName="ApplicationManifest"
                TaskParameter="OutputManifest"/>
        </GenerateApplicationManifest>
    </Target>   
</Project>

これは本当にこの質問への答えとしてマークされるべきだと思います。現在、これを使用して、すべてのマニフェスト生成を自動化しています。@mcdonに感謝します、あなたは私に多くの仕事を節約してくれました。
Pete Magsig 2013

Visual Studioでビルドする場合、これが最良のソリューションであることに同意します。他の回答よりもはるかに遅れて投稿されたという理由だけで、おそらく高く評価されていません
dschaeffer 2014年

これをcsprojに追加する方法は?
jle 2016年

@jleAfterBuildターゲットのcsprojに追加できると思います。ここだMSDNからのリンク、および他のポスト事前に作成し、ポストビルドイベントの話題には。 なお、私はcsprojでこれを含めてテストしていませんが、私はそれがうまくいくと思います。
mcdon 2016年

(?ではなく、各exeファイルにマニフェストを生成し、DLLを含む)マニフェストは、そう任意exeファイルがそれを消費することができるC#COM DLLのために生成することができる
GilesDMiddleton

9

Make My Manifest(MMM)は、これを行うための優れたツールです。mt.exeを使用してすべてのDLL / OCXファイルを処理するスクリプトを記述して、それぞれのマニフェストを生成し、それらをすべてマージすることもできます。MMMは、多くの特殊な/奇妙なケースも処理するため、通常は優れた/簡単です。


3
私はこのMMMのことについて少し緊張しています。これは単なるブログ、フリーウェアですが、利用可能なソースコードはなく、「自己解凍型exe」へのリンクのみであり、XPをクラッシュさせるユーティリティに関するコメントが表示されます。mmm ...
Wim Coenen

それらの「クラッシュ」は、MMMユーティリティ自体が死にかけていることでした。これはバージョン0.6.5で修正されましたが、まだベータ版であるにもかかわらず有効期限が切れないため、とにかく0.6.6が必要になります。すでに提案されているように、代わりにいつでもMT.EXEを使用できます。
ボブ

dbgrid32.ocxのようなネイティブcomサーバーで使用すると、mt.exeがprogidを生成しません
Wim Coenen

.NETで作成されたコンポーネントで
regfree

8

無人のMakeMy Manifestスピンオフ使用して、自動ビルドでマニフェストを直接生成できます。スクリプトファイルを使用して、依存するCOMコンポーネントを追加します。これは、使用可能なコマンドを使用したサンプルiniからの抜粋です。

# Unattended MMM script
#
# Command names are case-insensitive. Reference of supported commands:
#
# Command: Identity
#
#   Appends assemblyIdentity and description tags.
#
#   Parameters       <exe_file> [name] [description]
#      exe_file      file name can be quoted if containing spaces. The containing folder 
#                    of the executable sets base path for relative file names
#      name          (optional) assembly name. Defaults to MyAssembly
#      description   (optional) description of assembly
#
# Command: Dependency
#
#   Appends dependency tag for referencing dependent assemblies like Common Controls 6.0, 
#     VC run-time or MFC
#
#   Parameters       {<lib_name>|<assembly_file>} [version] [/update]
#     lib_name       one of { comctl, vc90crt, vc90mfc }
#     assembly_file  file name of .NET DLL exporting COM classes
#     version        (optional) required assembly version. Multiple version of vc90crt can
#                    be required by a single manifest
#     /update        (optional) updates assembly_file assembly manifest. Spawns mt.exe
#
# Command: File
#
#   Appends file tag and collects information about coclasses and interfaces exposed by 
#     the referenced COM component typelib.
#
#   Parameters       <file_name> [interfaces]
#     file_name      file containing typelib. Can be relative to base path
#     interfaces     (optional) pipe (|) separated interfaces with or w/o leading 
#                    underscore
#
# Command: Interface
#
#   Appends comInterfaceExternalProxyStub tag for inter-thread marshaling of interfaces
#
#   Parameters       <file_name> <interfaces>
#     file_name      file containing typelib. Can be relative to base path
#     interfaces     pipe (|) separated interfaces with or w/o leading underscore
#
# Command: TrustInfo
#
#   Appends trustInfo tag for UAC user-rights elevation on Vista and above
#
#   Parameters       [level] [uiaccess]
#     level          (optional) one of { 1, 2, 3 } corresponding to { asInvoker, 
#                    highestAvailable, requireAdministrator }. Default is 1
#     uiaccess       (optional) true/false or 0/1. Allows application to gain access to 
#                    the protected system UI. Default is 0
#
# Command: DpiAware
#
#   Appends dpiAware tag for custom DPI aware applications
#
#   Parameters       [on_off]
#     on_off         (optional) true/false or 0/1. Default is 0
#
# Command: SupportedOS
#
#   Appends supportedOS tag
#
#   Parameters       <os_type>
#     os_type        one of { vista, win7 }. Multiple OSes can be supported by a single 
#                    manifest
#

32ビットまたは64ビットのWindowsで動作します。


+1興味深い、特にソースコードが利用できるからです。名前の類似性に少し混乱しています。どうやら「マニフェストを作成する」と「マニフェストを無人で作成する」は、作成者によって異なるツールです。
Wim Coenen

2
注-2017年(8年後...)の時点で、このプロジェクトはまだアクティブであり、時折メンテナンスが更新されています。github.com/wqweto/UMMM/commits/master。それはうまく機能し、私はそれを日常的に使用しています。
UuDdLrLrSs 2017年

0

mt.exeに含まれていないProgIDを入力するにはProgIDFromCLSID、レジストリからそれらを検索するために呼び出すことができます。これには、マニフェストファイルを完成させる前に従来のCOM登録が必要ですが、その後、マニフェストファイルは自給自足になります。

このC#コードは、マニフェスト内のすべてのCOMクラスにProgIDを追加します。

var manifest = XDocument.Load(fileName);
var namespaceManager = new XmlNamespaceManager(new NameTable());
namespaceManager.AddNamespace("s", "urn:schemas-microsoft-com:asm.v1");
foreach (var classElement in manifest.XPathSelectElements("s:assembly/s:file/s:comClass", namespaceManager)) {
    var clsid = Guid.Parse(classElement.Attribute("clsid").Value);
    int result = ProgIDFromCLSID(ref clsid, out string progId); if (result != S_OK) throw new COMException($"ProgID lookup failed for {clsid}.", result);
    classElement.SetAttributeValue("progid", progId);
}
manifest.Save(fileName);

コードは、次の相互運用定義に依存しています。

[DllImport("ole32.dll")] static extern int ProgIDFromCLSID([In] ref Guid clsid, [MarshalAs(UnmanagedType.LPWStr)] out string lplpszProgID);
const int S_OK = 0;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.