在执行某些操作之前,C#如何检查COM对象是否可用?

4

在使用COM对象(InteropServices)之前,如何检查其是否存在(已注册/可用/可以正常运行)?

我的应用程序需要使用其他应用程序的COM对象,但在执行某些操作之前,我希望检查是否可以创建COM对象。

如果COM对象位于同一目录中,则不会出现问题,但它们并不在同一目录中。

例如,我想检查是否存在类似以下内容的内容:

CDNBase.ApplicationClass App = new CDNBase.ApplicationClass();

这可能会导致可捕获的异常或其他问题。然后我可以创建漂亮的消息框并阻止一些事件,直到它被修复。

像检查命名空间是否存在之类的其他解决方案也可以(我猜:D)。

我尝试使用try / catch,但失败了,谷歌没有给我带来任何特别的东西,所以我在寻求您的帮助。

提前感谢。

2个回答

2
没有人喜欢看到错误消息。但这是一个特殊情况,不要这样做。COM激活一直很难进行故障排除。但最近的发展,如64位操作系统、注册表虚拟化、注册表重定向和UAC,已经大大增加了可能出现问题的方式。
你的客户IT团队最不需要的就是另外一层代码,它会默默地改变激活规则或抑制诊断信息。当它不能正常工作并且他们找不到原因时,他们会对你提出严厉的批评。
首先问问自己,当交互操作无法工作时,你的程序是否仍然有用。如果没有,那就什么也不要做,让异常终止你的程序,但确保异常详细信息清晰可见。
如果它仍然有用,那么只需在程序中添加一个配置选项,让它在不尝试交互操作的情况下绕过它。

嗯,我需要将一个应用程序(www)与其他exe集成。因此,我编写了SOAP Web服务,并几乎完成了使用此.exe的COM执行某些操作的小型集成应用程序;) 简而言之:拥有可工作的COM至关重要。如果没有它们,我可能只能关闭我的应用程序:D 但是感谢您的答案,因为我在开发更大的应用程序方面没有太多经验。 - cichy
1
没错,就让它崩溃吧,不要修复问题。 - Hans Passant

1
你是否尝试过捕获 ComException
try
{
...
}
catch(System.Runtime.InteropServices.COMException ex)
{
    // log error message
    throw;
}

更新:抱歉,我并不是建议压制异常。已经更新。

或者,您可以在注册表中搜索组件的 ClassID

HKEY_CLASSES_ROOT\CLSID\{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\InprocServer32 

默认值将包含指向 DLL 的完整文件系统路径。


是的,但无法在同一方法中捕获异常。 它以其他方式工作: 在buttonClickMethod(或任何其他我启动此代码的地方)中,我有: this.runSynch(); 在runSynch()开头,我声明需要检查的COM,因此我有: runSynch(..){ CDNBase ... App = new CDNBase ... //(其余代码...) } 而在buttonClickMethod中,我有: try {runSynch} catch(FileNotFoundException ex){msgBox ..} 所以它按照我想要的方式工作;) 干杯 - cichy
这种方法本身就容易出错:你需要处理32/64位的差异(例如,32位COM对象已安装,但这是一个64位进程)。考虑一下外部进程实现怎么样?而且,仅仅因为存在该键并不意味着有实现文件存在,或者该进程可以访问它。 - Richard
该死,因为你,我看到了在开始考虑编写优秀应用程序之前我还需要学习多少。;) - cichy

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