内容:
我的项目使用需要自行注册的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
行,以及该行和它的两行不生成重复。
引用的组件将“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" />
...所以重复的部分缺少“名称”属性。
理想情况下,我想使用我已知的好清单文件,所以我创建了它并添加到我的项目中:
但是,即使告诉Visual Studio不生成清单文件,并根据该特定清单文件在我的项目中创建一个新文件,它仍然坚持使用它。
如何在没有Visual Studio添加内容并破坏它的情况下生成一个与我告诉它完全相同的清单文件?
编辑:我已经检查过,Reference'd DLL上的Isolated标志是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" />
如果我在comInterfaceExternalProxyStub
中注释掉app.manifest
行,则生成的清单中会出现NEITHER行。
答案 0 :(得分:3)
我明白了。从问题中不清楚的是,当Click-Once发布者重写您的清单并添加点击一次特定的goo时,这会出错。
我找了一段时间的解决方法,有不止一种方法可以做到这一点。例如,您可以将组件清单分开,并在主清单中使用<dependency>
。没有区别。 Click-Once清单中<file>
元素的documented schema非常奇怪,请注意它如何将comInterfaceExternalProxyStub
声明为file
的子项。移动它以匹配模式不起作用,它会导致元素完全消失。这份文件完全没错,是一个麻烦的先兆。
长话短说,这是一个错误。这不是一个奇怪的错误,应用程序清单文档非常差,特别是对于comInterfaceExternalProxyStub。我曾多次使用张俊峰的名字,这句话中的一句话我不能在这里重复。
您可以在connect.microsoft.com上报告。奇怪的是,没有以前的报告,但肯定大多数程序员要么不需要它,要么没有快速尝试或放弃,并要求用户安装COM组件作为先决条件。这很正常,也许你应该采取的方法。除此之外,手动编辑清单并删除额外的行是一种解决方法。
并且不要忘记尝试最明显的解决方法,通常不需要comInterfaceExternalProxyStub,并且在程序集引用中使用Isolated
属性时不会生成comInterfaceExternalProxyStub。绝大多数程序员的方式和我之前给你的建议。只要您不使用工作线程中的COM组件,就不需要代理。
答案 1 :(得分:1)
如果您对该解决方案感到满意,您应该能够阻止Visual Studio自动生成清单文件:
但是,可以使用项目的 Generate Manifest属性禁用项目清单的生成。当此属性设置为“是”时,将生成此项目的清单。否则,链接器在解析应用程序代码的依赖关系时会忽略程序集信息,并且不会生成清单。
如果这不起作用(如您所示),您可能会尝试更改标记。比较生成的&#34;空&#34;标签和标签显示您的numMethods
属性遗失。 (diff)