能否从.NET与64位COM服务器(Photoshop)进行交互?

11

我一直在尝试编写与Photoshop交互的代码,既添加了COM引用,又使用了后期绑定。后来我才意识到,这些代码确实可以工作,但无法与64位版本的Photoshop一起使用。

我在64位Photoshop中遇到的异常如下:

COMException was unhandled

由于以下错误,检索具有CLSID {D9389EDE-AEF8-4092-9377-075E94B7CB9A} 的组件的COM类工厂失败:80080005 服务器执行失败(HRESULT Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).

我的应用程序是否能够与64位版本的Photoshop进行通信?或者它只能限于与32位版本进行通信吗?

我在寻找解决方案时发现了这个,但我不知道如何在COM引用或后期绑定中使用CLSCTX_ACTIVATE_64_BIT_SERVER标志,也许它是解决方案。

异常出现在此处:

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

1
总有一天我会弄清楚为什么SO用户坚决拒绝记录他们遇到的异常。但我离那一天还很远。将您的EXE项目的目标平台设置更改为Any CPU。 - Hans Passant
1
你的 Photoshop COM 对象是在进程内还是进程外创建的(相对于你的代码)?在进程内将需要构建兼容平台的 .Net,而进程外的平台则不应该有影响。 - morechilli
是的,拒绝了。你被提示过了,但仍然没有记录异常。没有得到答案是标准结果。 - Hans Passant
4
@a2h - 当人们问不完整的问题时,只有这种态度才会显现出来。 - Security Hound
6个回答

1

.NET应用程序的可执行文件(.exe)如果标记为AnyCPU,则始终会在运行处理器架构的本机位数下运行,该编译器编译成MSIL。因此,任何在64位平台上运行的MSIL程序集都将以64位模式运行,在32位平台上运行时将以32位模式运行。

在您的情况下,您可以选择编译为AnyCPU,但如果您必须强制使用64位互操作性,请使用x64。当然,这在32位的计算机上不起作用。这将从注册表的64位视图(包括InProc)

您还必须注意指针如何转换。如果要编写自己的互操作代理,请确保使用IntPtr来处理句柄。


未来的读者们:我终于得到了一份Visual Studio 2010的副本;我一直在使用Express,所以我无法选择AnyCPU。这意味着,不幸的是,我没有验证过适用于Express用户的答案。请随意创建一个答案或指出已经存在的Express用户的答案,我会注意到它。 - unrelativity

1

使用不同环境中的COM时需要检查的几个事项:

  1. 切换COM引用的“嵌入互操作类型”(参见图1)
  2. 检查平台目标(参见图2)

Image 1 - Reference Property Image 2 - Platform Target


0

根据我们所拥有的少量信息:

引用自: 當CoCreateInstance返回0x80080005(CO_E_SERVER_EXEC_FAILURE)時


...如果客戶端從進程開始的時候失敗了沒有調用CoRegisterClassObject(),或者根本沒有為給定的類工廠調用CoRegisterClassObjects(),那麼客戶端將在CoCreateInstance(...)中收到CO_E_SERVER_EXEC_FAILURE錯誤。這可能由於多種原因引起:

1)機器負載過高,進程啟動並在120秒內執行CoRegisterClassObjects()

2)COM服務器未註冊正確的類ID。

3)COM服務器目前正在停止,CoCreateInstance和COM服務器停止部分之間存在競爭條件。

4)COM服務器啟動方式存在安全問題(此頁面似乎暗示拼寫錯誤的密碼或缺少“作為批處理作業”權限以“以......”COM服務器運行,但無論如何,我建議您為特定配置重新驗證此信息)


0
64/32位版本的问题稍微有点复杂,因为您可能正在32位操作系统上运行32位Photoshop。为了测试,我建议将项目目标设置为x64,并尝试运行Photoshop64。如果可以,那么您甚至可以将代码编译两次(2个DLL),根据Photoshop版本加载它们。

0

我对于Photoshop API并不是很了解,所以我会尝试以更一般的方式回答你的问题。

32位应用程序无法将64位代码加载到其内存空间中,反之亦然。这意味着唯一的混合方法是通过某种形式的进程间通信。

如果它是作为一个独立进程的COM服务器,COM将会为您处理这种进程间通信。因此,如果Photoshop的COM对象实现为独立进程对象,那么一切都会正常工作。鉴于你遇到的问题,我猜想它们使用的是相互之间无法混合的进程内对象。在这种情况下,您需要创建自己的独立进程服务器来包装您想使用的Photoshop对象。然后,您可以从32位和64位代码中都使用这个独立进程包装器。

另外,为了澄清其他帖子中的一些内容,在.NET中,您需要确保Platform Target设置为您要完成的任务所需的选项。 x86将使您的代码始终以32位运行。x64将使其始终以64位运行。任何CPU将使其在32位操作系统上以32位运行,在64位操作系统上以64位运行。


0

转到组件服务>计算机>我的电脑>DCOM 配置>Photoshop RGBColor>identity>交互式用户。 然后在安全选项卡中设置管理员帐户的权限


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接