将程序集清单直接加载到应用程序上下文中是否正确?

时间:2013-10-15 12:32:53

标签: winapi visual-c++ side-by-side regfreecom activation-context-api

我正在尝试使用免注册COM来运行一个相当纠结的方案。

并不是它不起作用,而是我遇到了一种令人困惑的情况,似乎我应该直接在应用程序上下文中激活程序集依赖关系的清单,而不是让应用程序上下文指向依赖项组装

example project MS themselves publish

很容易解释

通常,你有一个应用程序,一个app清单,一个(server-)dll和它的程序集清单。这些对应于the example gives

  • client.exe
  • client.exe.manifest(这个指向到SideBySide.X为dependentAssembly
  • SideBySide.dll
  • SideBySide.X.manifest

现在,一个标准情况是将客户端应用程序清单嵌入客户端可执行文件中,然后使用DLL及其外部清单文件。

现在,如果由于某种原因在编译时未知正确的应用程序清单,您可以通过Activation Context API在运行时加载清单文件。

这就是令人困惑的地方:

根据文章,客户端应用程序现在直接将激活上下文切换到程序集清单:

  

如果你看一下client.cpp中的_tmain函数......一个初始化激活上下文的新代码段,如下所示:

actCtx.lpSource = "SideBySide.X.manifest";

我已经交叉检查了这个,它也可以动态加载包含来自client.exe.manifest的信息的文件,即只是对SideBySide.X的引用,并继续使用此激活上下文 - 这也是对应的当我们将正确的应用程序清单嵌入可执行文件时,使用ActCtx。

也就是说,actCtx.lpSource = "client.exe.manifest";也可以。

TL; DR 应用程序代码中直接激活“包含”程序集清单的激活上下文(如果有)的含义是什么

这是从文件加载清单时应该怎么做的?(如果是这样的话,为什么我们不能直接将汇编清单嵌入到可执行文件中,当它在编译时已知。)


注意 :(这应该是对@Eric Brown答案的评论,但它变得相当冗长)

linked article在解释两种RT_MANIFEST资源类型方面做得不错,但就regFreeCOm而言,它留下了一些松散的结果。我会引用一些引用我的语录:

  

ISOLATIONAWARE_MANIFEST_RESOURCE_ID主要用于DLL。它   如果dll想要除了之外的私有依赖项,应该使用   进程默认。 ...   NT库加载器检查是否有   dll具有类型为RT_MANIFEST,ID的资源   ISOLATIONAWARE_MANIFEST_RESOURCE_ID。如果是,则加载程序调用   使用资源创建CreateActCtx,并使用生成的激活   用于探测 dll的静态依赖关系的上下文。

我理解这意味着RT_MANIFEST/2点是静态 DLL依赖性加载器找到用于解析的正确资源 DLL依赖。 ( COM依赖项,请参阅下文。)

  

有时,您希望在探测之外使用激活上下文   dll的静态依赖。您可以定义宏   编译模块时ISOLATION_AWARE_ENABLED。

     

定义ISOLATION_AWARE_ENABLED后,Windows会重新定义某些内容   蜜蜂。例如,LoadLibraryExW被重新定义为   IsolationAwareLoadLibraryExW。

     

...并非所有受激活上下文影响的API都会被包装。例如,   ......,也不是任何COM API

所以,总结一下:我认为RT_MANIFEST机制主要与regFreeCOM正交,因为COM根本不关心激活上下文的来源,并且没有regFreeCOM wrt的内置帮助。隔离意识。

1 个答案:

答案 0 :(得分:2)

是的,这就是它应该如何完成的,你可以将程序集清单嵌入到可执行文件中(好吧,资源部分)。这就是RT_MANIFEST资源类型的用途。有two default types of manifest resources个进程清单,在进程创建期间使用ID CREATEPROCESS_MANIFEST_RESOURCE_ID(1),在DLL加载期间使用ID为ISOLATIONAWARE_MANIFEST_RESOURCE_ID(2)的隔离感知清单。

有几种用法(主要围绕Click-once部署),说明了使用RT_MANIFEST在子DLL中嵌入免注册COM清单的能力。特别是,如果DLL具有CREATEPROCESS_MANIFEST_RESOURCE_ID,则也将使用该清单。

这里的例子似乎是件好事。

给出

  • client.exe
  • sidebyside.dll

如果sidebyside.dll有一个ID为1的RT_MANIFEST资源(CREATEPROCESS_MANIFEST_RESOURCE_ID),其中包含相应的免注册COM条目,并且client.exe有一个ID为1的RT_MANIFEST资源,其中包含<file>条目sidebyside.dll,然后Win32将自动处理免注册COM管理。

Part 8 of the example article强烈暗示了这一点,我已经看到它在许多内部项目中完成。