पंजीकरण मुक्त COM के लिए प्रकट फाइलें उत्पन्न करें


87

मेरे पास कुछ एप्लिकेशन (कुछ देशी, कुछ .NET) हैं जो प्रकट फ़ाइलों का उपयोग करते हैं ताकि उन्हें किसी भी वैश्विक COM पंजीकरण की आवश्यकता के बिना पूर्ण अलगाव में तैनात किया जा सके । उदाहरण के लिए, dbgrid32.ocx कॉम सर्वर पर निर्भरता myapp.exe.manifest फ़ाइल में निम्नानुसार घोषित की गई है जो 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 को एक ही फ़ोल्डर में तैनात किया गया है, इसके साथ ही 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 यह भी: टैग के रूप में फिर से दर्ज किए गए regfreecom को रजिस्ट्री फ्री COM के लिए अधिक सामान्य है
MarkJ

क्या मैं मैनिफ़ेस्ट फ़ाइल द्वारा अपने स्वयं के स्थापित फ़ोल्डर में एक उच्च संस्करण mstscax.dll का उपयोग कर सकता हूं?
ऐसविंड

@ वसूल हाँ। (आप अधिक विवरण के साथ एक नया प्रश्न पोस्ट करना चाह सकते हैं।)
UuDdLrLrSs

@UuDdLrLrSs खुशखबरी! मैं यहां एक नया प्रश्न पोस्ट करता हूं: stackoverflow.com/questions/63575746/…
Acewind

जवाबों:


63

ऐसा लगता है कि सही समाधान अभी तक मौजूद नहीं है। कुछ शोधों को संक्षेप में प्रस्तुत करने के लिए:

मेरा मेनिफेस्ट ( लिंक) बनाएं )

यह उपकरण COM निर्भरताओं को देखने के लिए VB6 प्रोजेक्ट को स्कैन करता है, लेकिन यह देर से बसा हुआ COM निर्भरता (यानी CreateObject के माध्यम से उपयोग किए जाने वाले) की मैन्युअल घोषणा का भी समर्थन करता है।

दिलचस्प रूप से पर्याप्त है, यह टूल एप्लिकेशन मैनिफ़ेस्ट के अंदर निर्भरता के बारे में सभी जानकारी रखता है। अनुप्रयोग exe और इसकी निर्भरताएँ एक ही असेंबली के रूप में बताई जाती हैं, जिसमें कई फाइलें होती हैं। मुझे इससे पहले एहसास नहीं था कि यह संभव है।

एक बहुत अच्छा उपकरण की तरह दिखता है, लेकिन संस्करण 0.6.6 के रूप में इसकी निम्न सीमाएँ हैं:

  • केवल VB6 अनुप्रयोगों के लिए, VB6 प्रोजेक्ट फ़ाइल से शुरू होता है। शर्म की बात है, क्योंकि यह वास्तव में VB6 से कोई लेना-देना नहीं है।
  • विज़ार्ड शैली अनुप्रयोग, एक निर्माण प्रक्रिया में एकीकृत करने के लिए उपयुक्त नहीं है। यदि आपकी निर्भरता बहुत अधिक नहीं बदलती है तो यह बहुत बड़ी समस्या नहीं है।
  • स्रोत के बिना फ्रीवेयर, इस पर भरोसा करना जोखिम भरा है क्योंकि यह किसी भी क्षण परित्याग बन सकता है।

मैंने परीक्षण नहीं किया कि क्या यह .NET कॉम पुस्तकालयों का समर्थन करता है।

regsvr42 ( कोडप्रोजेक्ट लिंक )

यह कमांड लाइन टूल देशी COM पुस्तकालयों के लिए प्रकट फाइलें उत्पन्न करता है। यह DllRegisterServer को आमंत्रित करता है और फिर स्व-पंजीकरण पर जासूसी करता है क्योंकि यह रजिस्ट्री में जानकारी जोड़ता है। यह अनुप्रयोगों के लिए एक ग्राहक प्रकट भी उत्पन्न कर सकता है।

यह उपयोगिता .NET COM पुस्तकालयों का समर्थन नहीं करती है, क्योंकि ये DllRegisterServer दिनचर्या को उजागर नहीं करते हैं।

उपयोगिता C ++ में लिखी गई है। स्रोत कोड उपलब्ध है।

mt.exe

विंडोज़ एसडीके का हिस्सा ( एमएसडीएन से डाउनलोड किया जा सकता है ), जो आपके पास पहले से ही है अगर आपके पास दृश्य स्टूडियो स्थापित है। यह यहाँ प्रलेखित है । आप इस तरह से इसके साथ देशी COM पुस्तकालयों के लिए प्रकट फाइलें उत्पन्न कर सकते हैं:

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

आप .NET COM पुस्तकालयों के लिए प्रकट फाइलें इस तरह से उत्पन्न कर सकते हैं:

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

हालाँकि, इस उपकरण के साथ कुछ समस्याएं हैं:

  • पहला स्निपेट प्रोगिड विशेषताओं को उत्पन्न नहीं करेगा, जो क्लाइंट को तोड़ता है जो प्रोजिड्स के साथ CreateObject का उपयोग करता है।
  • दूसरा स्निपेट उत्पन्न करेगा <runtime>और<mvid> तत्व जिन्हें वास्तव में काम करने से पहले छीनने की आवश्यकता है।
  • अनुप्रयोगों के लिए क्लाइंट मैनिफ़ेस्ट की पीढ़ी समर्थित नहीं है।

शायद भविष्य के एसडीके रिलीज इस उपकरण को बेहतर बनाएंगे, मैंने विंडोज एसडीके 6.0 ए (विस्टा) में परीक्षण किया।


1
मुझे लगता है कि आप एक विकल्प से चूक गए: mazecomputer.com लेकिन मुझे इसके बारे में कुछ नहीं पता कि वेब साइट इसका वर्णन नहीं करती है।
बॉब

MMM गैर-COM (मानक) DLL को भी पुनर्निर्देशित करेगा। मुझे यकीन नहीं है कि अन्य उपकरण ऐसा करते हैं।
बॉब

तंत्रिका के लिए बस एक नोट: एमएमएम के लिए स्रोत जारी किया गया है। नकारात्मक पक्ष पर, ऐसा प्रतीत होता है क्योंकि लेखक ने इस पर काम करना बंद करने का फैसला किया है। फिर भी एक सकारात्मक संकेत।
गैविन

2
MMM के लिए साइट नोलॉन्जर है, लेकिन जिस स्थान पर स्रोत कोड डाला गया था वह अभी भी v0.9 और v0.12 के लिए उपलब्ध है ।
स्कॉट चैंबरलेन 20

1
ऊपर वर्णित के रूप में .NET COM पुस्तकालयों के लिए बस mt.exe की कोशिश की और यह v7.1A का उपयोग कर प्रकट करने के लिए कोई संशोधन के साथ काम किया। इसके अलावा, MMM के लिंक काम नहीं करते थे लेकिन अनअटेंडेड मेक माई मेनिफेस्ट एक अच्छा काम करता है।
bzuillsmith

28

MSBuild कार्य GenerateApplicationManifest I के साथ मैं कमांड लाइन पर एक प्रकटन उत्पन्न करता हूं जो दृश्य स्टूडियो जेनरेट करता है। मुझे संदेह है कि Visual Studio बिल्ड के दौरान GenerateApplicationManifest का उपयोग करता है । नीचे मेरी बिल्ड स्क्रिप्ट है जिसे कमांड लाइन से msbuild "msbuild build.xml" का उपयोग करके चलाया जा सकता है

डेव टेम्पलिन और उनके पद के लिए धन्यवाद जिसने मुझे GenerateApplicationManifest कार्य और 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, आपने मुझे बहुत काम बचाया है।
पीट मैग्सेग

मैं मानता हूं कि विजुअल स्टूडियो के साथ निर्माण करते समय यह सबसे अच्छा समाधान है। यह शायद केवल इसलिए उच्चतर रेट नहीं किया गया है क्योंकि इसे दूसरे उत्तरों की तुलना में बहुत बाद में पोस्ट किया गया था
dsipleffer

यह कैसे एक csproj में जोड़ने के लिए?
jle

@ जले मुझे लगता है कि आप इसे आफ्टरबिल्ड लक्ष्य में अपने csproj में जोड़ सकते हैं। यहाँ msdn से एक लिंक है , और घटनाओं के निर्माण और पुनर्निर्माण के विषय पर एक और पोस्टनोट मैंने इसे csproj में शामिल नहीं किया है, लेकिन मुझे संदेह है कि यह काम करेगा।
mcdon

क्या C # COM DLL के लिए प्रकट किया जा सकता है, ताकि कोई भी exe इसका उपभोग कर सके (बजाय प्रत्येक exe पर प्रकट होने के और DLL सहित?)
GilesDMiddleton

9

मेक माई मेनिफेस्ट (MMM) ऐसा करने का एक अच्छा साधन है। अपने सभी DLL / OCX फ़ाइलों को संसाधित करने के लिए mt.exe का उपयोग करके प्रत्येक के लिए एक प्रकट बनाने और फिर उन सभी को एक साथ मर्ज करने के लिए एक स्क्रिप्ट लिखना भी संभव है । एमएमएम आमतौर पर बेहतर / आसान होता है, क्योंकि यह बहुत सारे विशेष / अजीब मामलों को भी संभालता है।


3
मैं इस MMM चीज़ को लेकर थोड़ा घबराया हुआ हूँ; यह सिर्फ एक ब्लॉग है, फ्रीवेयर है, लेकिन कोई स्रोत कोड उपलब्ध नहीं है, केवल "सेल्फ-एक्सट्रैक्टिंग एक्स" के लिए एक लिंक है और मुझे उपयोगिता के बारे में टिप्पणियां दिखाई देती हैं जिससे एक्सपी दुर्घटनाग्रस्त हो जाता है। एमएमएम ...
विम कॉइनन

"क्रैश" उन MMM उपयोगिता ही मर रहे थे। यह संस्करण 0.6.5 में तय किया गया था, लेकिन आप अभी भी 0.6.6 चाहते हैं, जबकि अभी भी एक बीटा अब यह समाप्त नहीं होता है। आप हमेशा पहले से सुझाए गए अनुसार MT.EXE का उपयोग कर सकते हैं।
बॉब

mt.exe प्रोगिड उत्पन्न नहीं कर रहा है जब मैं इसे dbgrid32.ocx जैसे देशी कॉम सर्वर पर उपयोग करता हूं
Wim Coenen

.NET अधिकृत घटकों के साथ reg नि: शुल्क COM का उपयोग जाहिरा तौर पर XP को दुर्घटना का कारण बन सकता है - इस stackoverflow.com/questions/617253/…
MarkJ

8

आप स्वचालित बिल्ड में सीधे मेनिफेस्ट बनाने के लिए अनअटेंडेड मेक माई मेनिफेस्ट स्पिन का उपयोग कर सकते हैं । यह संशोधित COM घटकों को जोड़ने के लिए एक स्क्रिप्ट फ़ाइल का उपयोग करता है। यह उपलब्ध आदेशों के साथ नमूना आईएन का एक अंश है:

# 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 बिट विंडोज पर चलेगा।


+1 दिलचस्प, विशेष रूप से क्योंकि स्रोत कोड उपलब्ध है। मैं समानता नाम से थोड़ा उलझन में हूं, जाहिर है "मेरी उपस्थिति बनाओ" और "अप्राप्य मेरी उपस्थिति बनाओ" विभिन्न लेखकों द्वारा अलग-अलग उपकरण हैं।
विम कोएनेन

2
नोट - 2017 तक (8 वर्ष ...) यह परियोजना अभी भी सामयिक रखरखाव अपडेट के साथ सक्रिय है। github.com/wqweto/UMMM/commits/master । यह अच्छी तरह से काम करता है और मैं इसे नियमित रूप से उपयोग करता हूं।
UUDdLrLrSs

0

ProgID में भरने के लिए जो mt.exe शामिल नहीं है, आप कॉल कर सकते हैं ProgIDFromCLSID उन्हें रजिस्ट्री से देखने के लिए । मैनिफ़ेस्ट फ़ाइल को पूरा करने से पहले पारंपरिक COM पंजीकरण की आवश्यकता होती है, लेकिन बाद में, मैनिफ़ेस्ट फ़ाइल आत्मनिर्भर होगी।

यह C # कोड एक प्रकट में सभी COM वर्गों के लिए ProgIDs जोड़ता है:

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;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.