问题
SUMMARY:
My project uses a COM component which needs to be self-registered. The project has it's own custom myapp.exe.manifest
file, which includes the two lines:
<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" />
However, building the project generates these files in the actual live .manifest
file:
<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" />
In other words, a duplicate line with missing attribute values, which naturally throws an error when the app starts.
If I remove either one of the "source" lines from the original manifest, both the dummy duplicate and the correct line disappear from the generated manifest - i.e. comment out the ICapturer
line, and both that line and its duplicate aren't generated.
The referenced component has both "Embed Interop" and "Isolated" set to false (see screenshot below).
Given that Visual Studio will always want to generate the manifest (even though I've asked it to specifically use my file), how can I stop the duplicated lines being generated?
ORIGINAL QUESTION TEXT:
Following on from my previous question, I had a hard time getting COM component deployed with my ClickOnce application. I've resolved this issue now, but it involved editing the generated .manifest
file to include some parameters that were being omitted.
I've put the custom manifest file into my project, but every time I build it, it regenerates a manifest that is almost, but not quite, the same. I have sections that are repeated: for example, in my app.manifest
I have:
<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" />
but the generated exe.manifest
has:
<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" />
... so duplicated sections with missing "name" attributes.
Ideally, I'd like to just use my known, good manifest file, so I created that and added to my project:
However, even after telling Visual Studio NOT to generate a manifest file, and creating a fresh one in my project based on that specific manifest file, it insists on fiddling with it.
How can I generate a manifest file that is exactly what I tell it to be, without Visual Studio adding things to it and breaking it?
EDIT: I've checked, and the Isolated flag on the Reference'd DLL is False:
EDIT2: Interestingly, if I comment out either of the comInterfaceExternalProxyStub
sections in project's manifest file, BOTH lines are omitted from the generated file. It does seem that the presence of those lines in my manifest is somehow generating TWO lines in the generated file - they're almost identical, but they're missing the "Name" attribute. So, to illustrate: having this one line in 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" />
generates these TWO lines in the actual build:
<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" />
If I comment out the comInterfaceExternalProxyStub
line in app.manifest
, NEITHER line appears in the generated manifest.
回答1:
I see it. What is not clear from the question is that this goes wrong when the Click-Once publisher rewrites your manifest and adds the click-once specific goo.
I poked at a workaround for a while, there is more than one way to do this. You can for example keep the component manifest separate and use <dependency>
in the main manifest. Made no difference. The documented schema for the <file>
element in a Click-Once manifest is very strange, note how it declares comInterfaceExternalProxyStub
as a child of file
. Moving it to match the schema did not work, it causes the element to disappear completely. This documentation is just flat-out wrong, a harbinger of trouble.
Long story short, this is a bug. It is not a strange bug, the application manifest documentation is excessively poor and especially so for comInterfaceExternalProxyStub. The several times I used Junfeng Zhang's name it was in a sentence with words I cannot repeat here.
You can report it at connect.microsoft.com. No previous reports for this, oddly, but surely most programmers either did not need it or did not try or gave up quickly and asked the user to install the COM component as a prerequisite. That is quite normal and perhaps the approach you should take as well. Other than that, editing the manifest by hand and deleting the extra lines is a workaround.
And don't forget to try to the most obvious workaround, comInterfaceExternalProxyStub is not often needed and won't be generated when you use the Isolated
property in the assembly reference. The way the vast majority of programmers do it and the advice I gave you earlier. As long as you don't use the COM component from a worker thread then the proxy is not needed.
回答2:
If you're happy with that solution, you should be able to prevent Visual Studio from generating a manifest file automatically:
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.
Source (MSDN)
If that doesn't work (as you seem to suggest) you might try to change your tags. Comparing the generated "empty" tags and your tags reveals that yours are missing the numMethods
attribute. (diff)
来源:https://stackoverflow.com/questions/34441785/duplicate-lines-being-generated-in-manifest-file