Deploying COM components with ClickOnce applicatio

2020-03-05 06:22发布

We're developing a C# WPF (.Net 4.0) application that requires screen "recording". We've evaluated ByteScout's Screen Capture SDK (free trial available), and it does exactly what we need to it.

However, the problem is that our application is designed to be deployed by ClickOnce, to our clients' machines (not on our network), and who will likely be logged in as limited, non-administrative users. The SDK has a redistributable component, but this requires to be installed separately - no good for ClickOnce.

ByteScout seemingly address this need in their documentation, under the section "Registration-free deployment":

/*
 * REGISTRRATION FREE SCENARIO DEPLOYMENT: allows to just copy DLLs from the SDK without installing them
 * See SAMPLE.EXE.manfest as the sample. 
 * 1) Rename "SAMPLE.EXE.manifest" into the actual application name (e.g. "MyApp.exe.manifest")
 * 2) Edit this .manifest file and replace "SAMPLE.EXE" with your application name (e.g. "MyApp.exe")
 * 3) Copy put this .manifest file into the same folder where your MyApp.exe is located
 * 4) Copy all dlls from /x86/ folder into the same folder as your application
 * So you will have files in the folder:
 * - MyApp.exe
 * - MyApp.exe.manifest
 * - BytescoutVideoMixerFilter.dll
 * - BytescoutScreenCapturingFilter.dll
 * - BytescoutScreenCapturing.dll
 * 5) Now you should be able run MyApp.exe without Screen Capturing SDK installed

So: I created an app.manifest file - my project didn't have or need one before - and added in the following from the SAMPLE.EXE.manifest mentioned above:

<file name="BytescoutScreenCapturing.dll">
    <comClass
        description="Capturer Class"
        clsid="{48967118-C4C9-435C-94D8-001247B9A52A}"
        threadingModel="Apartment"
        progid="BytescoutScreenCapturing.Capturer"
        tlbid="{8EDAD3BB-AE5F-43B4-A2F1-B04F4130F2E0}" />
    <comClass
        description="C:\Documents and Settings\Administrator\My Documents\Capture From Entire Screen\bin\Debug\BytescoutScreenCapturing.dll"
        clsid="{DCAFCA37-546E-4D0A-9C02-D3221E65FCA9}"
        threadingModel="Both" />

    <typelib tlbid="{8EDAD3BB-AE5F-43B4-A2F1-B04F4130F2E0}"
        version="1.0"
        helpdir="C:\Documents and Settings\Administrator\My Documents\Capture From Entire Screen\bin\Debug\" />

</file>

<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}" />

<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}" />

<file name="BytescoutScreenCapturingFilter.dll">

    <comClass
        description="Bytescout Screen Capturing Filter"
        clsid="{0F5D4CE4-2166-4FF7-9AA1-91330D35978A}"
        threadingModel="Both" />

    <comClass
        description="Screen Capturing Property Page"
        clsid="{22DD33B0-30C4-420D-A955-844E2B85A1F3}"
        threadingModel="Both" />

    <comClass
        description="Screen Capturing Property Page"
        clsid="{9D153AAA-0477-4C2E-B827-211F10561B44}"
        threadingModel="Both" />

    <comClass
        description="Screen Capturing Property Page"
        clsid="{26882CF7-F62F-47DB-9A3C-D1191591BD04}"
        threadingModel="Both" />

</file>

<file name="BytescoutVideoMixerFilter.dll">

    <comClass
        description="Bytescout Video Mixer Filter"
        clsid="{4407F28D-97C2-41C5-A23F-2FAE465CE7BB}"
        threadingModel="Both" />

</file>

So my app now has:

  • A reference to BytescoutScreenCapturingLib, with "Embed Interop Types" set to "True"
  • The three DLLs - BytescoutScreenCapturing.dll,BytescoutScreenCapturingFilter.dll and BytescoutVideoMixerFilter.dll added to the project as "Content", with "Copy to Output Directory" set to "Copy Always"
  • The above app.manifest file.

The project builds fine, but when I now run it the app crashes. Looking in the Event Viewer, I see the error:

Activation context generation failed for "myapp.exe.Manifest".
Error in manifest or policy file "myapp.exe.Manifest" on line 89. The value "" of attribute "resourceid" in element "typelib" is invalid.

Bytescout also have a sample Console Application, and I've having the same issue with this: the project builds fine, but it fails with the above error. I've tried engaging with their support, but I'm not getting much responses apart from "try reading the documentation".

I've tried "self-registering" the COM components; I don't have much (or indeed, any) experience with COM, but all the sample code I've tried doesn't appear to (A) work and (B) work without Adminstrative privileges or (C) both. I'm not sure if it's something that COULD work in my scenario.

Can anyone advise on how to proceed please? All we need is the DLLs to be "registered" and available for use within my code, without having to install them.

EDIT: If I edit the generated myapp.exe.Manifest file, and set "resourceID" to be "1", I get a further error:

Activation context generation failed for "myapp.exe.Manifest".
Error in manifest or policy file "myapp.exe.Manifest" on line 103. The value "" of attribute "tlbid" in element "comClass" is invalid.

If I remove the app.manifest file from my project, and set the Isolated setting on the reference DLL to True, the error on startup changes to:

Activation context generation failed for "myapp.exe.Manifest".
 Dll redirector contributor unable to add file map entry for file BytescoutScreenCapturing.dll; Two or more components referenced directly or indirectly by the application manifest have files by the same name.

标签: c# com clickonce
0条回答
登录 后发表回答