2009-01-21 82 views
73

我有一些应用程序(一些本机,一些.NET),它们使用清单文件,以便它们可以是deployed in complete isolation,而不需要任何全局COM注册。例如,DBGRID32.OCX COM服务器的依赖被宣布为在同一文件夹坐作为MyApp.exe中的myapp.exe.manifest文件如下:生成清单文件免注册COM

<?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服务器列表(native和.NET)的依赖关系,然后让其余部分自动生成。可能吗?

+0

+1也:重新标记regfreecom作为标记是注册免费COM – MarkJ 2009-03-17 20:12:18

回答

55

看起来完美的解决方案尚不存在。要总结一些研究:

让我的清单link

这个工具扫描一个VB6项目寻找COM的依赖,但它也支持后期绑定的COM依赖手册报关(通过即那些用来创建对象)。

有趣的是,这个工具将关于应用程序清单内的依赖关系的所有信息。应用程序exe及其依赖关系被描述为由多个文件组成的单个程序集。我之前并没有意识到这是可能的。

看起来像一个很好的工具,而是版本0.6.6它具有以下限制:

  • 只为VB6应用,从VB6项目文件开始 。耻辱,因为 很多它确实与VB6无关 。
  • 向导风格应用程序,而不是 适合集成在构建 过程。如果您的 依赖关系变化不大,这不是一个大问题。
  • 没有源代码的免费软件,有依赖它的风险,因为它随时都可能成为弃用软件。

我没测试它是否支持.NET com库。

regsvr42codeproject link

此命令行工具生成用于本机COM库清单文件。它调用DllRegisterServer,然后在注册表中添加信息时监视自我注册。它也可以为应用程序生成客户端清单。

此实用程序不支持。NET COM库,因为它们不公开DllRegisterServer例程。

该实用程序是用C++编写的。源代码可用。

mt.exe

Windows SDK中(可从MSDN下载),如果你有安装Visual Studio,你已经的一部分。它是documented here。 您可以生成与它本机COM库清单文件是这样的:但是

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

,也存在一些问题:

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

您可以生成与它的.NET COM库清单文件这样与此工具:

  • 的第一个片段会不会产生 进程id属性,打破客户 其使用科瑞与progids的eObject。
  • 第二个片段将产生 <runtime><mvid>元素 这就需要之前 货单被剥离出来的实际工作。
  • 不支持为 应用程序生成客户端清单。

也许未来的SDK版本会改进这个工具,我测试了一个在Windows SDK 6.0a(vista)中的版本。

9

Make My Manifest (MMM)是一个很好的工具。也可以使用mt.exe编写一个脚本来处理所有DLL/OCX文件,为每个文件生成一个清单,然后将它们合并到一起。 MMM通常更好/更容易,因为它也处理许多特殊/奇怪的情况。

+3

我有点担心这个事情MMM多见;它只是一个博客,免费软件,但没有可用的源代码,只有一个“自解压exe”的链接,我看到有关导致XP崩溃的实用程序的评论。嗯... – 2009-01-21 22:21:08

+0

这些“崩溃”是MMM实用程序本身死亡。这在0.6.5版本中得到了修复,但您仍然需要0.6.6,因为虽然仍然是测试版本,但不会过期。 您可以随时使用MT.EXE,而不是像已经建议的那样。 – Bob 2009-01-21 23:19:05

+0

当我在本地com服务器(如dbgrid32.ocx)上使用mt.exe时,mt.exe不生成progid。 – 2009-01-23 01:21:43

8

您可以使用Unattended Make My 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 
# 
23

随着MSBuild任务GenerateApplicationManifest我生成的清单在命令行相同的清单,Visual Studio生成。我怀疑Visual Studio在构建期间使用GenerateApplicationManifest。下面是我可以从命令行使用msbuild“msbuild build.xml”运行的构建脚本

感谢Dave Templin和他的post that pointed me the the GenerateApplicationManifest task和MSDN的further documentation of the task

的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>