.manifest 文件中生成重复行
Duplicate lines being generated in .manifest file
摘要:
我的项目使用了一个需要自行注册的 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" />
换句话说,缺少属性值的重复行,这在应用程序启动时自然会引发错误。
如果我从原始清单中删除 "source" 行中的任何一行,则虚拟副本和正确的行都会从生成的清单中消失 - 即注释掉 ICapturer
行,并且两者不会生成该行及其副本。
引用的组件将 "Embed Interop" 和 "Isolated" 设置为 false(见下面的屏幕截图)。
考虑到 Visual Studio 总是想要生成清单(即使我已经要求它专门使用我的文件),我怎样才能停止生成重复的行?
原始问题文本:
在我的 previous question 之后,我很难用我的 ClickOnce 应用程序部署 COM 组件。我现在已经解决了这个问题,但它涉及编辑生成的 .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" />
...所以重复部分缺少 "name" 属性。
理想情况下,我只想使用我已知的良好清单文件,因此我创建了它并将其添加到我的项目中:
然而,即使告诉 Visual Studio 不要生成清单文件,并根据该特定清单文件在我的项目中创建一个新的清单文件,它仍然坚持摆弄它。
如何生成一个完全符合我要求的清单文件,而不 Visual Studio 添加和破坏它?
编辑:我检查过,引用的 DLL 上的隔离标志为假:
EDIT2:有趣的是,如果我注释掉项目清单文件中的任一 comInterfaceExternalProxyStub
部分,则生成的文件中将省略这两行。看起来我的清单中这些行的存在以某种方式在生成的文件中生成了两行 - 它们几乎相同,但它们缺少 "Name" 属性。因此,为了说明:在 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
行,则生成的清单中不会出现任何行。
如果您对该解决方案感到满意,您应该能够阻止 Visual Studio 自动生成清单文件:
However it is possible to disable generation of the manifest for a project using the Generate Manifest property of the project. When this property is set to Yes, the manifest for this project is generated. Otherwise the linker ignores assembly information when resolving dependencies of the application code, and does not generate the manifest.
如果这不起作用(正如您所建议的那样),您可以尝试更改标签。比较生成的 "empty" 标签和您的标签会发现您的标签缺少 numMethods
属性。 (diff)
我看到了。从问题中不清楚的是,当 Click-Once 发布者 重写 您的清单并添加 click-once 特定的 goo 时,这会出错。
我研究了一段时间的解决方法,有不止一种方法可以做到这一点。例如,您可以将组件清单分开并在主清单中使用 <dependency>
。没有区别。 Click-Once 清单中 <file>
元素的 documented schema 非常奇怪,请注意它如何将 comInterfaceExternalProxyStub
声明为 file
的子元素。移动它以匹配模式不起作用,它会导致元素完全消失。该文档只是 flat-out 错误,是麻烦的先兆。
长话短说,这是一个错误。这不是一个奇怪的错误,应用程序清单文档非常糟糕,对于 comInterfaceExternalProxyStub 尤其如此。好几次用张俊峰的名字都是在一句话里,这里不能重复
您可以在 connect.microsoft.com 举报。奇怪的是,以前没有关于此的报告,但可以肯定的是,大多数程序员要么不需要它,要么没有尝试,要么很快放弃,并要求用户安装 COM 组件作为先决条件。这是很正常的,也许您也应该采用这种方法。除此之外,手动编辑清单并删除多余的行是一种解决方法。
并且不要忘记尝试最明显的解决方法,comInterfaceExternalProxyStub 并不经常需要,并且在您使用程序集参考中的 Isolated
属性 时不会生成。绝大多数程序员的做法以及我之前给你的建议。只要您不从工作线程使用 COM 组件,就不需要代理。
摘要:
我的项目使用了一个需要自行注册的 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" />
换句话说,缺少属性值的重复行,这在应用程序启动时自然会引发错误。
如果我从原始清单中删除 "source" 行中的任何一行,则虚拟副本和正确的行都会从生成的清单中消失 - 即注释掉 ICapturer
行,并且两者不会生成该行及其副本。
引用的组件将 "Embed Interop" 和 "Isolated" 设置为 false(见下面的屏幕截图)。
考虑到 Visual Studio 总是想要生成清单(即使我已经要求它专门使用我的文件),我怎样才能停止生成重复的行?
原始问题文本:
在我的 previous question 之后,我很难用我的 ClickOnce 应用程序部署 COM 组件。我现在已经解决了这个问题,但它涉及编辑生成的 .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" />
...所以重复部分缺少 "name" 属性。
理想情况下,我只想使用我已知的良好清单文件,因此我创建了它并将其添加到我的项目中:
然而,即使告诉 Visual Studio 不要生成清单文件,并根据该特定清单文件在我的项目中创建一个新的清单文件,它仍然坚持摆弄它。
如何生成一个完全符合我要求的清单文件,而不 Visual Studio 添加和破坏它?
编辑:我检查过,引用的 DLL 上的隔离标志为假:
EDIT2:有趣的是,如果我注释掉项目清单文件中的任一 comInterfaceExternalProxyStub
部分,则生成的文件中将省略这两行。看起来我的清单中这些行的存在以某种方式在生成的文件中生成了两行 - 它们几乎相同,但它们缺少 "Name" 属性。因此,为了说明:在 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
行,则生成的清单中不会出现任何行。
如果您对该解决方案感到满意,您应该能够阻止 Visual Studio 自动生成清单文件:
However it is possible to disable generation of the manifest for a project using the Generate Manifest property of the project. When this property is set to Yes, the manifest for this project is generated. Otherwise the linker ignores assembly information when resolving dependencies of the application code, and does not generate the manifest.
如果这不起作用(正如您所建议的那样),您可以尝试更改标签。比较生成的 "empty" 标签和您的标签会发现您的标签缺少 numMethods
属性。 (diff)
我看到了。从问题中不清楚的是,当 Click-Once 发布者 重写 您的清单并添加 click-once 特定的 goo 时,这会出错。
我研究了一段时间的解决方法,有不止一种方法可以做到这一点。例如,您可以将组件清单分开并在主清单中使用 <dependency>
。没有区别。 Click-Once 清单中 <file>
元素的 documented schema 非常奇怪,请注意它如何将 comInterfaceExternalProxyStub
声明为 file
的子元素。移动它以匹配模式不起作用,它会导致元素完全消失。该文档只是 flat-out 错误,是麻烦的先兆。
长话短说,这是一个错误。这不是一个奇怪的错误,应用程序清单文档非常糟糕,对于 comInterfaceExternalProxyStub 尤其如此。好几次用张俊峰的名字都是在一句话里,这里不能重复
您可以在 connect.microsoft.com 举报。奇怪的是,以前没有关于此的报告,但可以肯定的是,大多数程序员要么不需要它,要么没有尝试,要么很快放弃,并要求用户安装 COM 组件作为先决条件。这是很正常的,也许您也应该采用这种方法。除此之外,手动编辑清单并删除多余的行是一种解决方法。
并且不要忘记尝试最明显的解决方法,comInterfaceExternalProxyStub 并不经常需要,并且在您使用程序集参考中的 Isolated
属性 时不会生成。绝大多数程序员的做法以及我之前给你的建议。只要您不从工作线程使用 COM 组件,就不需要代理。