COM Interop Problem on 64 bit system with Windows Forms LocalServer RRS feed

  • Question

  • I have a Windows Forms application which exposes a coclass with oneinterface throug COM.

    In order to have it run as Local Server and not as inproc, I have post-build actions involving 64-bit regasm, then using 64-bit Reg.exe to replace the InprocServer32 registry entry with a LocalServer32 entry.

    BTW it was impossible to have VStudio invoke the 64-bit REG.EXE even putting the whole path to windows\system32\reg.exe in the build action. VStudio always wants to start the 32 bit reg.exe. The only way to do it was to make a copy of the 64bit reg.exe and put it under another  name in the ouputdir-folder.

    Also, I put a call to RegistrationServices.RegisterTypeForComClients in the Main method before the Application.Run(new MainForm()) call.

    RegistrationServices svcs = new RegistrationServices();
    int sCookie = svcs.RegisterTypeForComClients(typeof(Test), RegistrationClassContext.LocalServer, RegistrationConnectionType.MultipleUse);

    When I do this in 32-bit system (using 32-bit regasm and reg.exe) this works fine. 

    The behahvior is as following: When the COM client creates the COM object, and the Windows Forms app is already running, it directly hands out the COM object. If the server application is not yet running, it is started and then creates the COM object.

    This is expected, as the RegisterTypeForComClients is supposed to be equivalent to CoRegisterClassObject of the Windows COM API.

    When I do the same with 64-bit processes, then it only works when the Windows Forms application is already started.

    When it is not started, the COM layer starts the Windows Forms application but it doesn't return. I tried VBA as client as well as a simple C++ console app using COM API calls. In both cases it works fine, when the Server app is already started, but doesn't work when COM starts it on behalf of the client.

    The funny thing is, that when I change the registry key  from LocalServer32 to LocalServer, then it works, COM succeeds in starting the Server an CoCreateInstance succeeds.

    This however is not an option for me, because what I am actually trying to achieve is to have an RTDServer running, and the RTD function of Excel doesn't work when there is only a LocalServer and no LocalServer32 registry key.

    As already mentioned, everything works fine in 32 bit.

    So, what could be the reason for this weird behavior?

    I can supply test projects which demonstrate the problem, if anyone is interested.

    BTW, there is a caveat testing the whole thing related to UAC. I mentioned that it always works when the COM Server application is already started. This is not entirely correct. When I start the app from the debugger and have VStudio running as admin, and use VBA from an officeapp as client, then it doesnt work. This is because, the security of client and server app don't match. In this case the VBA client starts a new instance of the Server app, which leads to the mentioned deadlock under Win 64. When I start the server app by doubleclicking it in Windows Explorer, it works as the security settings match. I still can debug, by attaching to the process, though.

    Tuesday, June 26, 2012 2:26 PM

All replies

  • Are you compiling as Any CPU?  Have you tried to compile for the specific platform?  Does it make a difference?

    When the 64-bit executable is activated by COM, what Windows account is used to run the application?  Is this username different from the username of the consuming process?

    Jose R. MCP
    Code Samples

    Tuesday, June 26, 2012 3:01 PM
  • Thanks for your reply. Actually it makes the difference.

    When I compile the Windows Forms app with the "Any CPU" switch, I have the problem described.

    When I compile with x64 target, it works even when the application is started by COM. Why should it make such a difference? Because in both cases it runs a 64-bit process. And why would it work with the "Any CPU" switch, when the registry key is renamed LocalServer?

    As for the accounts, they are both the same, being the account of the logged-on user.

    Tuesday, June 26, 2012 3:14 PM
  • Are the consumer applications 32- or 64-bit applications?  I mean the C++ test consumer app and the VBA one.

    When you compile for Any CPU, is the process being activated a 64-bit process or a 32-bit process?  Does this behavior change depending on the bitness of the consumer process?

    Jose R. MCP
    Code Samples

    Tuesday, June 26, 2012 3:19 PM
  • The client apps are 64-bit applications. Both, as I have Office 64 bit and compiled my c++ client for x64 target. Also verified using Task manager everything is 64 bit. The server process also is always activated as 64bit process, even when I use LocalServer as registry key. It doesnt matter wether I use platform target "any cpu" or "x64". I didn't test 32 bit scenarios under win64 yet, as currently I am investigating pure 64 bit situations.

    I think that as long as the registry entries are in the 64bit section of the registry, the process when compiled for "Any CPU" is launched as 64 bit.

    Anyway, to summarize 

    1. on Win32 it works

    2. on Win64 it works when the Server is already started, or when the registry key LocalServer32 is renamed to LocalServer or when the server app is compile with "x64" as target.

    3. on Win64 it doesn't work when the Server process is compiled for "any cpu" and COM layer needs to start the server process. The server app is started but CoCreateInstance doesn't return.

    I have uploaded the test files http://www.infozoom.de/download/WindowsFormsApplication1.rar Not there is a file "Myreg.exe" which is just a copy of the 64bit Reg.exe. It is used with the post build actions.

    Tuesday, June 26, 2012 3:37 PM
  • It's strongly recommended to specify 32bit or 64bit instead of using "Any CPU" when you build the application. AnyCPU may cause some trouble in these symptoms. Please check the blog: http://blogs.msdn.com/b/rmbyers/archive/2009/06/08/anycpu-exes-are-usually-more-trouble-then-they-re-worth.aspx.

    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.

    Tuesday, July 31, 2012 9:08 AM
  • FWIW, I've just come across what appears to be the same issue (the symptoms are so similar).

    In my situation I have a .net EXE configured to be run from the shell by having the application registered as a DropTarget, as mentioned here http://blogs.msdn.com/b/oldnewthing/archive/2010/05/03/10006065.aspx

    If the application is built for x86 everything is generally fine on both 32 & 64-bit OS's.

    If the application is x64, it's generally fine (in 64-bit OS's of course).

    If the application is AnyCPU, it mostly fails on 64-bit OS's. The application launches, but never gets the file selection drop, and after some time Explorer reports "This file does not have a program associated with it for performing this action" , and kills the process it started.

    Now, I say that it mostly fails as AnyCPU because sometimes (I'm not really sure why/when) it works fine! It seems to be ok after I've switched from a working x64 to AnyCPU build, but I'm really not confident on it.

    Similarly, I've had both the x86 and x64 versions fail in the same way - though like the success with AnyCPU, I'm not sure what causes the different behaviours - it seems to be switching from the currently working processor build to the opposite type.

    I don't have any solution (other than to stick with an x86 only build), but I thought I'd record my experiences here if anyone else encounters the situation.

    Friday, August 3, 2012 10:14 AM