共用方式為


SxS Managed COM With Manifest Resource (WinXP and Win2K3)

This article is now superseded by the "Registration-Free Activation of .NET-Based Components: A Walkthrough" MSDN article. Please see the MSDNography links section.

Comments

  • Anonymous
    February 07, 2005
    The comment has been removed

  • Anonymous
    February 07, 2005
    Like the steps above show, I'd recommend you first get your interop working in the normal case where your typelibrary is registered. In step 4 create a VB6 app, reference the .tlb generated when you registered your .NET assembly for COM Interop and use it as normal. If you can get to step 5 (and this is nothing to do with SxS yet) then the remaining steps will apply to a VB6 app, which is of course native, just as they do to the console app. The only difference between your VB6 client and my console app is how they initialise COM. My console app is MTA, your VB6 app will be STA. With SxS if client/server aren't in compatible apartments then you have to put an extra section in your assembly manifest:

    <comInterfaceExternalProxyStub

    name="ISxSCPPSTABlue"

    iid="{4992BDCD-18E3-4907-89C8-5A6F57787820}"

    proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"

    numMethods="1"

    baseInterface="{00000000-0000-0000-C000-000000000046}"

    tlbid = "{E04C5ACA-356B-4D47-9A02-532D92BEAAE5}"

    />

    The above defines IDispatch so is appropriate for VB6. Just change the name and IID attributes above.
    Alternatively, make sure your .NET assembly runs in an STA with an STAThreadAttribute. When I get chance I'll cover these situations in docs.

  • Anonymous
    February 07, 2005
    Okay, I'm sheepish but not too proud to ask: from where do I derive the 'name' and 'iid' attributes in my case?

  • Anonymous
    February 07, 2005
    I'd say first try the route of building your .NET assembly as STA first. If that won't fly then come back here. :-)

    So, the reason you need the comInterfaceExternalProxyStub element is the same reason you need the manifest file - i.e. to supply the COM runtime with the information it would otherwise get from the registry. In this case the information is how to marshall interfaces between the client's apartment and the server's apartment. If these are compatible then you don't need this element whic is why I suggest building the .NET app as STA.

    The 'name' attribute is the name of the interface(s) which you wish to use on your .NET class. The 'iid' attribute is the IID of this interface. I forgot to say that you'll also need to set the 'tlbid' attribute which is the LIBID of the .tlb which describes your .NET classes. How do you find these values? I'd say the best thing is to use Guid attributes in your .NET classes so you know up front what the IID and LIBID will be. Failing that, there's the OLE/COM Object Viewer. The object viewer in VB6 may also give this info, but if not then search for the OLE/COM Object Viewer.

    Hope that helps.

  • Anonymous
    February 09, 2005
    Well.... I truly can't travel the path of making my .NET assembly single-threaded, so I aimed straight at the next option, and I'm pretty sure I missed.

    Ever heard of the law of leaky abstractions (http://www.joelonsoftware.com/articles/LeakyAbstractions.html)? You're dealing with an individual who's unfamiliar with the lower-level operations of the code I write. So that's why I keep giving you the blog equivalent of a blank stare when you try to help me - sorry!

    Would it be inappropriate for me to paste the contents of OLEViewer into these comments, so you could see specifically what I'm working with? That's about the only way I see for us to get on the same page...

  • Anonymous
    February 09, 2005
    Sure, go for it.

  • Anonymous
    February 09, 2005
    It looks like .NET assemblies registered for COM are Both-threaded which means no marshalling takes place whether the object is called from an MTA or an STA. So your VB client, calling from an STA, will be fine with the assembly manifest as I first showed it, i.e. no need for the extra comInterfaceExternalProxyStub element.

    I'd say go ahead with my original set of steps and just build a VB6 client instead of a C++ one. For reference, I rebuilt my C++ client but made it STA (as VB is) and it worked without changing the manifest.

    Cheers,
    Steve

  • Anonymous
    February 15, 2005
    Steve -

    It's not working.... I've followed the steps you outlined and the best I can get is what I had before. I run the VB6 executable, and get a messagebox that says this:

    "This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem."

    That's about all I can get. Would it be worthwhile for you to see the three objects (EXE, Manifest and DLL)?

  • Anonymous
    February 16, 2005
    There are multiple possible points of failure in getting SxS to work, most resulting in the error message you quote. For example if you omit #include <windows.h> in step 10, you'll see it.

    What I suggest is two things. First, do your experiments on Win2K3 and check the System event log. Win2K3 gives better messages than XP's which are unhelpful. Second, I really urge you to get a functioning frame of reference for SxS by following the steps given in this article. Get some practice in what does and doesn't work before we 'move the goalposts' by moving to VB6. You see, I only have the proofs published here, I have no proofs involving VB6. I do plan to do that work in due course, but I'm maxed out right now. Another option for you is to raise a case with MS Product Support.

    I do sympathise with your frustration - getting this far has been a struggle for me. But I will get round to VB6 in time and I intend to cover it in the eventual MSDN article.

  • Anonymous
    February 16, 2005
    The comment has been removed

  • Anonymous
    February 16, 2005
    > the #include <windows.h> isn't relevant to a VB project anyway, right?

    So, you said initially "my environment is almost exclusively VB6 apps that need to interop with .NET assemblies." The only step in this article which is potentially relevant to VB6 is step 4. To make VB6 relevant you'd create a VB6 app instead of a C++ app in step 4, reference the .tlb generated when you registered your .NET assembly for COM Interop and use it as normal.

    All the other steps have to be done as written. The build.cmd file is to build your .NET assembly. So although #include <windows.h> isn't relevant to VB6, it is relevant to this article and it's not one of the bits which are replaced by replacing the C++ client with a VB6 client.

    I mentioned the #include <windows.h> as an example of something which, if forgotten, will prevent the experiment from working.

    As I said before, If you can get to step 5 (and this is nothing to do with SxS yet) then the remaining steps will apply to a VB6 app.

  • Anonymous
    February 17, 2005
    Sorry to produce a red herring with my comment regarding relevance.

    I'll see what I can do about locating all the files necessary to support the #include, and will run the experiment again. I'll keep you posted on how it goes. Thanks for sticking with me.

  • Anonymous
    February 20, 2005
    The comment has been removed

  • Anonymous
    June 01, 2009
    PingBack from http://portablegreenhousesite.info/story.php?id=9815

  • Anonymous
    June 09, 2009
    PingBack from http://cellulitecreamsite.info/story.php?id=2571