Saya memiliki beberapa aplikasi (beberapa asli, beberapa .NET) yang menggunakan file manifes sehingga mereka dapat digunakan dalam isolasi lengkap , tanpa memerlukan pendaftaran COM global. Misalnya, ketergantungan pada server dbgrid32.ocx com dideklarasikan sebagai berikut di file myapp.exe.manifest yang berada di folder yang sama dengan myapp.exe:
<?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 disebarkan ke folder yang sama, bersama dengan file dbgrid32.ocx.manifest itu sendiri:
<?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>
Ini semua berfungsi dengan baik tetapi mempertahankan file manifes ini secara manual agak merepotkan. Apakah ada cara untuk menghasilkan file ini secara otomatis? Idealnya saya hanya ingin menyatakan ketergantungan aplikasi pada daftar server COM (baik asli maupun .NET) dan kemudian biarkan sisanya dibuat secara otomatis. Apa itu mungkin?
Jawaban:
Sepertinya solusi yang tepat belum ada. Untuk meringkas beberapa penelitian:
Make My Manifest ( tautan )
Alat ini memindai proyek VB6 untuk mencari dependensi COM, tetapi juga mendukung deklarasi manual dependensi COM terikat-akhir (yaitu yang digunakan melalui CreateObject).
Yang cukup menarik, alat ini meletakkan semua informasi tentang dependensi di dalam manifes aplikasi. Exe aplikasi dan ketergantungannya digambarkan sebagai satu rakitan yang terdiri dari beberapa file. Saya tidak menyadari sebelumnya bahwa ini mungkin.
Sepertinya alat yang sangat bagus tetapi pada versi 0.6.6 memiliki batasan berikut:
Saya tidak menguji apakah itu mendukung perpustakaan com .NET.
regsvr42 ( tautan proyek kode )
Alat baris perintah ini menghasilkan file manifes untuk pustaka COM asli. Ini memanggil DllRegisterServer dan kemudian memata-matai pendaftaran mandiri saat menambahkan informasi ke dalam registri. Itu juga dapat menghasilkan manifes klien untuk aplikasi.
Utilitas ini tidak mendukung pustaka .NET COM, karena ini tidak mengekspos rutin DllRegisterServer.
Utilitas ini ditulis dalam C ++. Kode sumber tersedia.
mt.exe
Bagian dari Windows SDK (dapat diunduh dari MSDN ), yang sudah Anda miliki jika Anda menginstal studio visual. Itu didokumentasikan di sini . Anda dapat membuat file manifes untuk pustaka COM asli dengan itu seperti ini:
Anda dapat membuat file manifes untuk pustaka .NET COM dengan itu seperti ini:
Namun, ada beberapa masalah dengan alat ini:
<runtime>
dan<mvid>
elemen yang perlu dihapus sebelum manifes benar-benar berfungsi.Mungkin rilis SDK di masa mendatang akan meningkatkan alat ini, saya menguji yang ada di Windows SDK 6.0a (vista).
sumber
Dengan tugas MSBuild GenerateApplicationManifest saya menghasilkan manifes pada baris perintah yang identik dengan manifes yang dihasilkan Visual Studio. Saya menduga Visual Studio menggunakan GenerateApplicationManifest selama pembuatan. Di bawah ini adalah skrip build saya yang dapat dijalankan dari baris perintah menggunakan msbuild "msbuild build.xml"
Terima kasih kepada Dave Templin dan postingannya yang menunjukkan tugas GenerateApplicationManifest , dan dokumentasi tugas MSDN lebih lanjut .
build.xml
sumber
Make My Manifest (MMM) adalah alat yang bagus untuk melakukan ini. Anda juga dapat menulis skrip untuk memproses semua file DLL / OCX Anda menggunakan mt.exe untuk menghasilkan manifes untuk masing-masing file dan kemudian menggabungkan semuanya. MMM biasanya lebih baik / lebih mudah, karena juga menangani banyak kasus khusus / aneh.
sumber
Anda dapat menggunakan spin off Make My Manifest tanpa pengawasan untuk menghasilkan manifes langsung dalam build otomatis. Ini menggunakan file skrip untuk menambahkan komponen COM yang bergantung. Ini adalah kutipan dari contoh ini dengan perintah yang tersedia:
Ini akan berjalan pada Windows 32 atau 64 bit.
sumber
Untuk mengisi ProgID yang tidak disertakan mt.exe, Anda dapat memanggil
ProgIDFromCLSID
untuk mencarinya dari registri. Ini memerlukan registrasi COM tradisional sebelum menyelesaikan file manifes, tetapi selanjutnya, file manifes akan mencukupi sendiri.Kode C # ini menambahkan ProgID ke semua kelas COM dalam manifest:
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);
Kode tersebut bergantung pada definisi interop berikut:
[DllImport("ole32.dll")] static extern int ProgIDFromCLSID([In] ref Guid clsid, [MarshalAs(UnmanagedType.LPWStr)] out string lplpszProgID); const int S_OK = 0;
sumber