我的 .NET 客户端应用程序依赖于另一个程序集。这种依赖关系在一个app.manifest
文件中声明:
应用程序清单
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity version="1.0.0.0" name="Contoso.Frobber.Admin"/>
<!-- We have a dependancy on Grobber -->
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Contoso.Grobber" version="1.0.0.0" processorArchitecture="x86" />
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC Manifest Options
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 7-->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
</application>
</compatibility>
</asmv1:assembly>
然后将项目配置为使用我们的app.manifest
文件。您在Project -> Application -> Resourcesapp.manifest
下指定使用自定义:
这一切都有效
我必须确保将我的其他程序集放在同一个文件夹中^1。例如:
Contoso.Grobber.manifest
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="Contoso.Grobber" version="1.0.0.0" processorArchitecture="x86" />
<file name = "Grobberify.dll">
<comClass
progid="Contoso.Grobberify"
clsid="{EB4B9718-0625-4505-BBF2-42CF7E94643E}"
description="Grobber system frobs"
threadingModel = "Apartment" />
</file>
</assembly>
所以我的文件夹中有:
- 示例应用程序.exe
- Contoso.Grobber.Manifest
- Grobberify.dll
一切正常。我的应用程序运行,一切正常。
我可以证明我的嵌入式清单受到尊重,因为如果我将嵌入式清单更改为需要名为Contoso.Grobber asdfasfaraasdf的东西:
<!-- We have a dependancy on Grobber -->
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="asdfasfaraasdf" version="1.0.0.0" processorArchitecture="x86" />
</dependentAssembly>
</dependency>
如果现在运行我的应用程序,Fusion 加载器将意识到没有名为asdfasfaraasdf的程序集,并在加载时抛出错误:
应用程序无法启动,因为它的并排配置不正确。请查看应用程序事件日志或使用命令行 sxstrace.exe 工具了解更多详细信息。
如果我将我的依赖程序集放回正确的asdfasfaraasdf --> Contso.Grobber,那么一切正常。
调试时除外
没有特别的原因,如果我在调试器中,那么融合加载程序看不到我的程序集清单,它是依赖程序集。
我可以通过在我的程序集清单中声明我依赖于一个不存在的程序集来证明这一点(例如 name="asdfasdfasf")
![enter image description here][3]
该应用程序应该无法启动 -但它会启动!不管我做什么:
- 使用假程序集名称
- 删除我的依赖程序集的清单
- 删除
.dll
我的依赖程序集
该应用程序不会启动失败。这意味着 Visual Studio 正在运行的我的可执行文件的任何版本:它不包含我嵌入app.manifest
的 .
这是一个问题,因为它坏了
您可能认为让应用程序运行是一件好事——我不希望它失败。这是错误的,原因有两个:
- 如果所需的程序集不存在,我希望它无法启动
- 依赖程序集包含所需的融合信息
我正在加载的程序集是一个 COM dll。我的.manifest
文件包含急需的 COMclsid
和文件名信息。当 Visual Studio 不支持我的应用程序清单时,Fusion 加载程序将看不到我的免注册 COM 对象:
<comClass
progid="Contoso.Grobberify"
clsid="{EB4B9718-0625-4505-BBF2-42CF7E94643E}"
description="Grobber system frobs"
threadingModel = "Apartment" />
</file>
如果没有此程序集 comClass 信息,我的 .NET 应用程序在调试时无法创建 COM 对象:
[ComImport]
[Guid("EB4B9718-0625-4505-BBF2-42CF7E94643E")]
public class Grabasstic
{
}
IGrobberAss ga = (IGrobberAss)new Grabasstic();
仅在调试时发生
带有 32 位应用程序的 Windows 7 64 位上的 Visual Studio Community 2013 失败,并且登录用户未配置壁纸仅在调试应用程序时发生。如果我直接运行SampleApplication.exe,则嵌入程序集清单将受到尊重。
这可能与 Visual Studio 不调试的事实有关
示例应用程序.exe
Visual Studio 实际上调试了一个名为:
SampleApplication.vshost.exe
或不。我知道什么?
我如何使它工作?
我知道没有解决办法。地球上对免注册 COM有任何经验的人数仅限于:
可以肯定地说,没有人真正阅读过上面的“研究工作”的整个部分。我也很想知道哪些用户在那里抓住了复活节彩蛋,以及谁会抱怨过多的研究工作。
实际上,我知道没有解决方案。虽然我可以记录这是一个问题的事实,但我并没有暗示任何人都可以解决它。这使得整个 45 分钟的问题成为我发泄无法解决的问题的一种方式。
奖金阅读
- 这是一个嵌入清单的人也被忽略了。对他来说,这导致应用程序不遵守他的
requireAdministrator
安全条目 - 在调试模式下运行应用程序时,清单不会强制 Visual Studio 2013 在管理员下重新启动
- 应用清单被忽略
- Visual Studio 导致在调试时忽略嵌入式程序集清单