Possible to interact with a 64-bit COM server (Pho

2020-05-26 16:39发布

问题:

I've been trying to write some code to interact with Photoshop, both by adding a COM reference and by late binding. It took me a while to realise that the code did work, but not with the 64-bit version of Photoshop.

The exception I get with 64-bit Photoshop is as follows:

COMException was unhandled

Retrieving the COM class factory for component with CLSID {D9389EDE-AEF8-4092-9377-075E94B7CB9A} failed due to the following error: 80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).

Is it possible for my application to communicate with the 64-bit version of Photoshop? Or is it limited to just communicating with the 32-bit version?

I've come across this in one of my numerous attempts to find a solution, but I don't see how I could put the CLSCTX_ACTIVATE_64_BIT_SERVER flag into use with either a COM reference or late binding, well, supposing that it is the solution.

The exception occurs here:

Type photoshopType = Type.GetTypeFromProgID("Photoshop.Application");
if (photoshopType != null)
{
    object photoshop = Activator.CreateInstance(photoshopType);

回答1:

.NET application executables (.exe) will always run in the native bitness of the running processor architecture if marked for AnyCPU, which compiles down to MSIL. So any MSIL assembly running on a 64-bit platform will run 64-bit, and on a 32-bit platform will run 32-bit.

In your case you'd either want to compilre for AnyCPU, but if you must force a 64-bit interop use x64. This won't work on a 32-bit machine, of course. This will natively read from the 64-bit view of the registry (including InProc

You must also be careful of how pointers are marshaled. Be sure to use IntPtr for handles if writing your own interop proxy.



回答2:

Couple of things to check for using COM from/to different environments:

  1. Toggle the "Embed Interop Types" for the COM reference (see image 1)
  2. Check the Platform Target (see image 2)



回答3:

Assuming from the little information we have:

Quoted from: When CoCreateInstance returns 0x80080005 (CO_E_SERVER_EXEC_FAILURE)


... If the client fails to call CoRegisterClassObject() from the moment the process was started, or fails to call CoRegisterClassObjects() at all for the given class factory, then the client will receive the CO_E_SERVER_EXEC_FAILURE error in CoCreateInstance(...). This can happen for a variety of reasons:

1) The machine has a high CPU load and the process takes a long time to start and execute the CoRegisterClassObjects() in less than 120 seconds.

2) The COM server doesn't register for the right class IDs.

3) The COM server is currently stopping and there is a race condition between CoCreateInstance and the COM server stopping part.

4) There is a security problem in the way the COM server is started (this page seems to suggest misspelled passwords or lacking the "Login as Batch Job" privilege for "Run As.." COM servers, but anyway I would suggest re-verifying this information for your specific configuration)



回答4:

I don't much about the Photoshop API, so I am going to try to answer your question a little more generally.

32 bit applications can not load 64 bit code into their address space and vice versa. This means the only way to mix them is through some form of inter process communication.

COM will handle this inter-process communication for you if it is an out of process COM server. So if the Photoshop COM objects are implemented as out of process objects, then everything would work fine. Since it is not working for you I am assuming they use in process objects which can not be mixed between 32 and 64 bit. In this case you would need to create your own out of process server that wraps the Photoshop objects you want to use. You could then use this out of process wrapper from both 32 and 64 bit code.

Also to clarify some of the other posts, in .NET you need to make sure the Platform Target is set to what you need for what you are trying to accomplish. x86 will make your code always run as 32 bit. x64 will make it always run as 64 bit. Any CPU will make it run as 32 bit on a 32 bit OS and 64 bit on a 64 bit OS.



回答5:

the problem of 64/32 bit versions is a little more complicated, as you might be running a 32bit photoshop on a 32 bit OS. I would try for the sake of testing to set the project target to x64 and if that can run the photoshop64, than you might even make your code compile twice (2 dlls) and load them according to the photoshop version.



回答6:

go to component services>computers>My Computer>DCOM Config>Photoshop RGBColor>identity>The interactive user. and set on security tab permission for administrator account