从Windows Server 2003上的Web CGI脚本执行.net应用程序时的InteropServices COMException

时间:2009-05-20 22:03:49

标签: .net security exception com invoke

免责声明:我对.net和COM完全不了解。

我有一个供应商的应用程序似乎是用.net编写的,我试图用一个Web表单(一个cgi-bin Perl脚本)来包装它,所以我最终可以从一台单独的计算机上启动这个供应商的应用程序。我在Windows Server 2003 R2 SE SP1系统上,我使用Apache 2.2作为Web服务器,使用ActivePerl 5.10.0.1004作为cgi脚本。我的cgi脚本使用Perl反引号运算符调用驻留在同一台机器上的供应商的应用程序。

...
$result = "Result: " . `$vendorsPath/$vendorsExecutable $arg1 $arg2`;
...

现在,我只是在服务器计算机上本地运行IE Web浏览器并访问“http://localhost/cgi-bin/myPerlScript.pl”。供应商的应用程序失败并记录包含以下堆栈跟踪的调试消息(我更改了几个名称,以便不泄露供应商的身份):

...
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Runtime.InteropServices.COMException (0x80043A1D): 0x80040154 - Class not registered
   --- End of inner exception stack trace ---
   at System.RuntimeType.InvokeDispMethod(String name, BindingFlags invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers, Int32 culture, String[] namedParameters)
   at System.RuntimeType.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters)
   at VendorsTool.Engine.Core.VendorsEngine.LoadVendorsServices(String fileName, String& projectCommPath)
...

当我从服务器计算机上的Windows命令行运行供应商应用程序时,cgi脚本传递的参数完全相同,它运行得很好,所以有一些关于通过Web脚本调用他们的应用程序导致问题。这个问题可能与安全性有关,因为整个事情在Windows XP Pro机器上运行得很好(命令行和Web调用)。我实际上在那里开发了我的web脚本并在我尝试将其移动到Windows Server 2003机器之前完全在那里工作。那么Windows Server 2003机器有什么不同,它会阻止供应商的.net应用程序被web cgi脚本成功执行?

我可以以某种方式修复此问题以使其在我的服务器上运行,或者供应商是否必须对其.net应用程序进行更改并发布新版本?我可能是世界上唯一一个试图从一个单独的程序执行这个供应商的应用程序的人,所以如果有一个可以在我的服务器机器上实现的解决方法,我讨厌打扰供应商。另外,我很匆忙,我不想等待4到6个月的时间让供应商进行修复并部署新版本。

感谢您提供任何建议。

3 个答案:

答案 0 :(得分:2)

在我看来,你有许可问题。看起来您的.NET应用程序试图使用COM对象,但它没有足够的权限来执行此操作。

每个COM对象(COM服务器)都具有启动/激活和访问权限(只需启动dcomcnfg并查看一些众所周知的应用程序的DCOM配置)。关于dcomcnfg(组件服务),您不仅可以查看,还可以更改此权限(在上下文菜单中选择应用程序并打开属性对话框。然后选择“安全”选项卡,在“启动和激活”中选择“自定义”权限“阻止然后单击”编辑“)。典型问题是INTERACTIVE用户对大多数COM对象具有启动/激活权限,但作为服务运行的进程不是该组的成员。因此,您必须通过向具有INTERACTIVE用户的相同启动权限授予某个帐户(由您的Apache Web服务器使用)或组(如IIS_IUSRS)来自定义权限。此权限信息将保存在HKEY_CLASSES_ROOT\AppID密钥的子项中(请参阅二进制AccessPermission注册表值)。

要识别出问题的COM对象,我建议你 Process Monitor (参见http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx)和 Process Explorer (参见http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx )。 Process Monitor 可以帮助您准确了解您的计划($vendorsExecutable)尝试启动的其他流程。从HKEY_CLASSES_ROOT的最后一次访问中的一次用于启动COM对象。你会发现它是哪个过程。不要忘记在具有完全管理权限的帐户下启动此工具(在服务器上通常不存在这样的问题)。要更快地找到所需信息,请使用过滤器过程名称和搜索Process Monitor的功能。

如果你第一次做这样的工作,它看起来很复杂。这并不容易,但一切都有明确定义的逻辑,我相信,你解决了这个问题。

答案 1 :(得分:1)

典型的原因是您没有安装先决条件。很难说哪个,因为COM类被很多应用程序使用。

查找缺少的类的一种方法是sysinternals工具process monitor。它可以用于监控注册表的使用。这有助于您准确跟踪脚本尝试加载的类。命名的COM类位于

HKEY_LOCAL_MACHINE\SOFTWARE\Classes

及其基础GUID条目位于

HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID

如果Apache在那里寻找一个条目但找不到它,那可能就是缺少perl脚本的COM类。

答案 2 :(得分:0)

请告诉我这是否有帮助:You receive a "0x80040154 (Class not registered)" error message when you register an ATL server

根据供应商开发其应用程序的工具,可能是由于DLL注册引起的,实际上没有在Windows Server 2003上注册。