【发布时间】:2015-08-16 16:15:02
【问题描述】:
我的 .NET 客户端应用程序依赖于另一个程序集。这种依赖关系在app.manifest 文件中声明:
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 -> Resources 下指定使用自定义app.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>
所以我的文件夹里有:
- SampleApplication.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 文件包含急需的 COM clsid 和文件名信息。当 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();
只有在调试时才会发生
Visual Studio Community 2013 在带有 32 位应用程序的 64 位 Windows 7 上的故障,以及未配置壁纸的登录用户仅在调试应用程序时发生。如果我直接运行 SampleApplication.exe,嵌入的程序集清单 得到尊重。
这可能与 Visual Studio 不调试有关
SampleApplication.exe
Visual Studio 实际上调试了一个名为:
SampleApplication.vshost.exe
或者没有。我知道什么?
如何让它发挥作用?
我知道没有解决办法。地球上对registration-free COM 有任何经验的人数仅限于:
可以肯定地说,没有人真正阅读过上述“研究工作”的整个部分。我也很想知道哪些用户在那里抓到了复活节彩蛋,以及谁会抱怨太多研究工作。
实际上,我知道没有解决方案。虽然我可以记录这是一个问题的事实,但我并没有暗示任何人都可以解决它。这使得整个 45 分钟的问题成为我发泄无法解决的问题的一种方式。
阅读奖励
-
Here's a guy who's embedded manifest is also being ignored。对他来说,这会导致应用程序不遵守他的
requireAdministrator安全条目 - Manifest does not force Visual Studio 2013 to restart under Admin when running application in Debug mode
- App Manifest Ignored
- Visual Studio causing embedded assembly manifest to be ignored while debugging
【问题讨论】:
-
您在调试时实际上并没有使用嵌入式清单。将使用磁盘上的 bin\Debug\SampleApplication.vshost.exe.manifest 文件。有什么不对的,看一下。 Fwiw,将其命名为 Contoso.Grobber.Manifest 并显示 app.manifest 的屏幕截图并不能帮助我们帮助您。还可以考虑禁用托管进程,这样就不会成为问题。
-
@HansPassant 那是因为确实有两个清单。一种是主机可执行文件 (
SampleApplication.exe) 及其嵌入式清单 (app.manifest)。另一个是单独的 dll (Contoso.Grobber.dll) 和它的(外部)程序集清单 (Contoso.Grobber.manifest)。 -
其实我无法在 Visual Studio 2012 中复制这个问题,它可能是 2013 中的回归。也就是说,当我将清单更改为依赖于不存在的程序集或声明
requireAdministrator时,转到 DEBUG > Start Debugging 会立即显示效果,例如加载失败,或 UAC 提示符。
标签: visual-studio visual-studio-2013 com registration-free-com