【问题标题】:Duplicate lines being generated in .manifest file.manifest 文件中生成的重复行
【发布时间】:2015-12-30 00:23:32
【问题描述】:

总结: 我的项目使用需要自行注册的 COM 组件。该项目有自己的自定义myapp.exe.manifest 文件,其中包括两行:

<comInterfaceExternalProxyStub name="ICapturer" iid="{DCAFCA37-546E-4D0A-9C02-D3221E65FCA9}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}" baseInterface="{00000000-0000-0000-C000-000000000046}" tlbid="{8EDAD3BB-AE5F-43B4-A2F1-B04F4130F2E0}" xmlns="urn:schemas-microsoft-com:asm.v1" />
<comInterfaceExternalProxyStub name="IVideoWMVSettings" iid="{1A814EC2-55A9-4FA2-99E2-2C20A897C2E7}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}" baseInterface="{00000000-0000-0000-C000-000000000046}" tlbid="{8EDAD3BB-AE5F-43B4-A2F1-B04F4130F2E0}" xmlns="urn:schemas-microsoft-com:asm.v1" />

但是,构建项目会在实际的实时.manifest 文件中生成这些文件:

<comInterfaceExternalProxyStub name="" iid="{DCAFCA37-546E-4D0A-9C02-D3221E65FCA9}" numMethods="" baseInterface="{00000000-0000-0000-C000-000000000046}" tlbid="" xmlns="urn:schemas-microsoft-com:asm.v1" />
<comInterfaceExternalProxyStub name="" iid="{1A814EC2-55A9-4FA2-99E2-2C20A897C2E7}" numMethods="" baseInterface="{00000000-0000-0000-C000-000000000046}" tlbid="" xmlns="urn:schemas-microsoft-com:asm.v1" />
<comInterfaceExternalProxyStub name="ICapturer" iid="{DCAFCA37-546E-4D0A-9C02-D3221E65FCA9}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}" baseInterface="{00000000-0000-0000-C000-000000000046}" tlbid="{8EDAD3BB-AE5F-43B4-A2F1-B04F4130F2E0}" xmlns="urn:schemas-microsoft-com:asm.v1" />
<comInterfaceExternalProxyStub name="IVideoWMVSettings" iid="{1A814EC2-55A9-4FA2-99E2-2C20A897C2E7}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}" baseInterface="{00000000-0000-0000-C000-000000000046}" tlbid="{8EDAD3BB-AE5F-43B4-A2F1-B04F4130F2E0}" xmlns="urn:schemas-microsoft-com:asm.v1" />

也就是说,缺少属性值的重复行,在应用启动时自然会抛出错误。

如果我从原始清单中删除任一“源”行,则虚拟副本和正确的行都会从生成的清单中消失 - 即注释掉 ICapturer 行,并且该行及其副本都是没有生成。

引用的组件将“嵌入互操作”和“隔离”都设置为 false(请参见下面的屏幕截图)。

鉴于 Visual Studio 总是希望生成清单(即使我已经要求它专门使用我的文件),我如何才能停止生成重复的行?

原始问题文本:

从我的previous question 开始,我很难将 COM 组件与 ClickOnce 应用程序一起部署。我现在已经解决了这个问题,但它涉及编辑生成的.manifest 文件以包含一些被省略的参数。

我已将自定义清单文件放入我的项目中,但每次构建它时,它都会重新生成一个几乎但不完全相同的清单。我有重复的部分:例如,在我的app.manifest 我有:

<comInterfaceExternalProxyStub name="ICapturer" iid="{DCAFCA37-546E-4D0A-9C02-D3221E65FCA9}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}" baseInterface="{00000000-0000-0000-C000-000000000046}" tlbid="{8EDAD3BB-AE5F-43B4-A2F1-B04F4130F2E0}" xmlns="urn:schemas-microsoft-com:asm.v1" />
<comInterfaceExternalProxyStub name="IVideoWMVSettings" iid="{1A814EC2-55A9-4FA2-99E2-2C20A897C2E7}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}" baseInterface="{00000000-0000-0000-C000-000000000046}" tlbid="{8EDAD3BB-AE5F-43B4-A2F1-B04F4130F2E0}" xmlns="urn:schemas-microsoft-com:asm.v1" />

但生成的exe.manifest 有:

  <comInterfaceExternalProxyStub name="" iid="{DCAFCA37-546E-4D0A-9C02-D3221E65FCA9}" numMethods="" baseInterface="{00000000-0000-0000-C000-000000000046}" tlbid="" xmlns="urn:schemas-microsoft-com:asm.v1" />
  <comInterfaceExternalProxyStub name="" iid="{1A814EC2-55A9-4FA2-99E2-2C20A897C2E7}" numMethods="" baseInterface="{00000000-0000-0000-C000-000000000046}" tlbid="" xmlns="urn:schemas-microsoft-com:asm.v1" />
  <comInterfaceExternalProxyStub name="ICapturer" iid="{DCAFCA37-546E-4D0A-9C02-D3221E65FCA9}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}" baseInterface="{00000000-0000-0000-C000-000000000046}" tlbid="{8EDAD3BB-AE5F-43B4-A2F1-B04F4130F2E0}" xmlns="urn:schemas-microsoft-com:asm.v1" />
  <comInterfaceExternalProxyStub name="IVideoWMVSettings" iid="{1A814EC2-55A9-4FA2-99E2-2C20A897C2E7}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}" baseInterface="{00000000-0000-0000-C000-000000000046}" tlbid="{8EDAD3BB-AE5F-43B4-A2F1-B04F4130F2E0}" xmlns="urn:schemas-microsoft-com:asm.v1" />

...所以重复的部分缺少“名称”属性。

理想情况下,我只想使用我已知的良好清单文件,因此我创建了该文件并将其添加到我的项目中:

但是,即使在告诉 Visual Studio 不要生成清单文件并根据该特定清单文件在我的项目中创建一个新文件之后,它仍然坚持摆弄它。

如何在不使用 Visual Studio 向其中添加内容并破坏它的情况下生成一个完全符合我要求的清单文件?

编辑:我检查过,引用的 DLL 上的独立标志为 False:

EDIT2:有趣的是,如果我在项目的清单文件中注释掉 comInterfaceExternalProxyStub 部分中的任何一个,生成的文件中都会省略这两行。似乎我的清单中这些行的存在以某种方式在生成的文件中生成了两行 - 它们几乎相同,但它们缺少“名称”属性。因此,为了说明:在app.manifest 中有这一行:

 <comInterfaceExternalProxyStub name="IVideoWMVSettings" iid="{1A814EC2-55A9-4FA2-99E2-2C20A897C2E7}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}" baseInterface="{00000000-0000-0000-C000-000000000046}" tlbid="{8EDAD3BB-AE5F-43B4-A2F1-B04F4130F2E0}" xmlns="urn:schemas-microsoft-com:asm.v1" />

在实际构建中生成这两行:

<comInterfaceExternalProxyStub name="" iid="{1A814EC2-55A9-4FA2-99E2-2C20A897C2E7}" numMethods="" baseInterface="{00000000-0000-0000-C000-000000000046}" tlbid="" xmlns="urn:schemas-microsoft-com:asm.v1" />
<comInterfaceExternalProxyStub name="IVideoWMVSettings" iid="{1A814EC2-55A9-4FA2-99E2-2C20A897C2E7}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}" baseInterface="{00000000-0000-0000-C000-000000000046}" tlbid="{8EDAD3BB-AE5F-43B4-A2F1-B04F4130F2E0}" xmlns="urn:schemas-microsoft-com:asm.v1" />

如果我注释掉app.manifest 中的comInterfaceExternalProxyStub 行,则生成的清单中不会出现任何行。

【问题讨论】:

  • 除非您为 Microsoft 工作,否则您对 VS 生成清单的方式几乎无能为力。注册表中的垃圾可能会导致它出错,请使用 Regedit.exe 进行查看。 HKLM\Sofware\Wow6432Node\Classes\Interface\{iid} 键。只做你自己的清单。项目 > 添加新项目 > 应用程序清单文件。不要弄乱那里的东西,将 regfree 条目合并到其中。
  • 我创建了自己的清单,并要求 VS 使用它,但它在文件中添加了额外的行和整个部分 - 并破坏了它。如果我将我的“好”清单复制到 bin\debug 中的清单上,它可以正常工作。
  • @HansPassant:不,Isolated 是 False - 见上面的截图
  • 这很奇怪。您确定不是其他程序或第三方破坏了文件吗?您能否提供一个包含每个人都有的 COM 组件的重现案例,以便我们也可以在没有您的特定组件的情况下重现问题。
  • 恐怕我对COM没有任何其他经验;这是我第一次需要在我的任何项目中使用它,它是第三方组件——尽管我使用的是免费提供的试用版 (bytescout.com/products/developer/screencapturingsdk/…)。我的机器上没有安装任何特别奇特的东西 AFAIK ...我希望我可以让 VS 使用我告诉它的 EXACT .manifest 文件,而不是每次都生成一个新文件。

标签: .net visual-studio manifest


【解决方案1】:

我看到了。问题中不清楚的是,当 Click-Once 发布者重写您的清单并添加 click-once 特定的 goo 时,这会出错。

我研究了一段时间的解决方法,有不止一种方法可以做到这一点。例如,您可以将组件清单分开并在主清单中使用&lt;dependency&gt;。没区别。 Click-Once 清单中&lt;file&gt; 元素的documented schema 非常奇怪,请注意它如何将comInterfaceExternalProxyStub 声明为file 的子元素。移动它以匹配模式不起作用,它会导致元素完全消失。该文档完全是错误的,是麻烦的预兆。

长话短说,这是一个错误。这不是一个奇怪的错误,应用程序清单文档非常糟糕,尤其是对于 comInterfaceExternalProxyStub。好几次用张俊峰的名字,都是在一句话里我不能重复的。

您可以在 connect.microsoft.com 上报告。奇怪的是,以前没有关于此的报告,但可以肯定的是,大多数程序员要么不需要它,要么没有尝试或很快放弃,并要求用户安装 COM 组件作为先决条件。这是很正常的,也许您也应该采取这种方法。除此之外,手动编辑清单并删除多余的行是一种解决方法。

不要忘记尝试最明显的解决方法,comInterfaceExternalProxyStub 并不经常需要,并且在您使用程序集参考中的Isolated 属性时不会生成。绝大多数程序员这样做的方式和我之前给你的建议。只要您不使用工作线程中的 COM 组件,就不需要代理。

【讨论】:

  • 感谢您的详细回复,我很高兴这是一个错误,而不是我在做一些愚蠢的事情:/ 不幸的是,我 am 使用工作线程中的 COM 组件。我试图通过使用后期构建过程将我的“好”.manifest 复制到适当的位置来变得聪明,但这只会破坏清单签名。令人沮丧的是,我需要寻找一个不同的包来与我的应用程序集成;要求用户单独安装 COM 组件不是一种选择。再次感谢。
【解决方案2】:

如果您对该解决方案感到满意,您应该能够阻止 Visual Studio 自动生成清单文件:

但是,可以使用项目的 Generate Manifest 属性 禁用项目清单的生成。当此属性设置为 Yes 时,将生成此项目的清单。否则,链接器在解析应用程序代码的依赖关系时会忽略汇编信息,并且不会生成清单。

Source (MSDN)

如果这不起作用(正如您所建议的那样),您可能会尝试更改您的标签。比较生成的“空”标签和您的标签表明您的标签缺少numMethods 属性。 (diff)

【讨论】:

  • 不幸的是,看起来 ClickOnce 总是想“重新生成”清单文件,即使我告诉它不要这样做。我尝试添加numMethods,但它仍然重复该行:(
猜你喜欢
  • 2014-04-22
  • 2017-10-04
  • 2018-12-07
  • 1970-01-01
  • 2020-02-10
  • 1970-01-01
  • 1970-01-01
  • 2013-09-21
  • 2013-11-26
相关资源
最近更新 更多