Disclaimer: I'm completely clueless about .net and COM.
免责声明:我对.net和COM完全无能为力。
I have a vendor's application that appears to be written in .net and I'm trying to wrap it with a web form (a cgi-bin Perl script) so I can eventually launch this vendor's app from a separate computer. I'm on a Windows Server 2003 R2 SE SP1 system and I'm using Apache 2.2 for the web server and ActivePerl 5.10.0.1004 for the cgi script. My cgi script calls the vendor's app that resides on the same machine using the Perl backtick operator.
我有一个供应商的应用程序似乎是用.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`;
...
Right now I'm just running IE web browser locally on the server machine and accessing "http://localhost/cgi-bin/myPerlScript.pl". The vendor's app fails and logs a debug message that includes the following stack trace (I changed a couple names so as to not give away the vendor's identity):
现在我只是在服务器机器上本地运行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)
...
When I run the vendors app from the Windows command line on the server machine with the exact same arguments that the cgi script is passing it runs just fine, so there's something about invoking their app via the web script that is causing a problem. This problem is likely security related because the whole thing runs just fine on a Windows XP Pro machine (both command line and web invocation). I actually developed my web script there and got it completely working there before I tried moving it to the Windows Server 2003 machine. So what's different about the Windows Server 2003 machine that would keep the vendor's .net app from being executed successfully by a web cgi script?
当我从服务器计算机上的Windows命令行运行供应商应用程序时,cgi脚本传递的参数完全相同,它运行得很好,所以有一些关于通过Web脚本调用他们的应用程序导致问题。这个问题可能与安全性有关,因为整个事情在Windows XP Pro机器上运行得很好(命令行和Web调用)。我实际上在那里开发了我的web脚本并在我尝试将其移动到Windows Server 2003机器之前完全在那里工作。那么Windows Server 2003机器有什么不同,它会阻止供应商的.net应用程序被web cgi脚本成功执行?
Can I fix this problem somehow to make it work on my server or will the vendor have to make a change to their .net app and ship out a new version? I'm probably the only person in the world who is trying to execute this vendor's app from a separate program, so I hate to bother the vendor with the issue if there's a workaround that I can implement myself here on my server machine. Plus, I'm in kind of a hurry and I don't want to wait 4 or 6 months for the vendor to put in a fix and deploy a new version.
我可以以某种方式修复此问题以使其在我的服务器上运行,或者供应商是否必须对其.net应用程序进行更改并发布新版本?我可能是世界上唯一一个试图从一个单独的程序执行这个供应商的应用程序的人,所以如果有一个解决方法我可以在我的服务器机器上实现自己,我讨厌打扰供应商。另外,我很匆忙,我不想等待4到6个月的时间让供应商进行修复并部署新版本。
Thanks for any advise you can give.
感谢您提出的任何建议。
3 个解决方案
#1
It seems to me that you have permission problem. It looks like your .NET application try to use a COM object and it has not enough permission to do this.
在我看来,你有权限问题。看起来您的.NET应用程序尝试使用COM对象,但它没有足够的权限来执行此操作。
Every COM object (COM server) has launch/activation and access permission (just start dcomcnfg
and look at DCOM configuration of some well known Applications). With respect of dcomcnfg
(Component Services) you can not only see but also change this permissions (select an application and open properties dialog in the context menu. Then choose "Security" tab, choose Customize in the "Launch and Activation Permission" block and then click "Edit"). Typical problem is that INTERACTIVE users have launch/activation permission to the most COM objects, but processes running as service are not a member of this group. So you have to customize permission by granting for an some account (used by your Apache web server) or a group (like a IIS_IUSRS
) the same launch permission which has INTERACTIVE users. This permission information will be saved in a subkey of the HKEY_CLASSES_ROOT\AppID
key (see binary AccessPermission
registry value).
每个COM对象(COM服务器)都具有启动/激活和访问权限(只需启动dcomcnfg并查看一些众所周知的应用程序的DCOM配置)。关于dcomcnfg(组件服务),您不仅可以查看,还可以更改此权限(在上下文菜单中选择应用程序和打开属性对话框。然后选择“安全”选项卡,在“启动和激活权限”块中选择自定义,然后单击“编辑”)。典型问题是INTERACTIVE用户对大多数COM对象具有启动/激活权限,但作为服务运行的进程不是该组的成员。因此,您必须通过向具有INTERACTIVE用户的相同启动权限授予某个帐户(由您的Apache Web服务器使用)或组(如IIS_IUSRS)来自定义权限。此权限信息将保存在HKEY_CLASSES_ROOT \ AppID密钥的子项中(请参阅二进制AccessPermission注册表值)。
To identify the COM object which makes problem I'll recommend you Process Monitor (see http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx) and Process Explorer (see http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx). Process Monitor can helps you to find out exactly which other processes your program ($vendorsExecutable
) try to start. One from the last accesses to HKEY_CLASSES_ROOT
are used to start a COM object. You will find out which process it is. Don't forget to start this tools under an account with full administrative rights (on a server such problem typically not exist). To find the information which you need more quickly use filter to a process name and searching features of Process Monitor.
要识别出问题的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的功能。
If you do such work at the first time it can look very complex. It is not easy, but everything have well defined logic and I am sure, that you solve this problem.
如果你第一次做这样的工作,它看起来很复杂。这并不容易,但一切都有明确的逻辑,我相信,你解决了这个问题。
#2
The typical cause would be that you did not install a prerequisite. It's hard to say which, because COM classes are used by so many applications.
典型的原因是您没有安装先决条件。很难说哪个,因为COM类被很多应用程序使用。
One way to find out the missing class is the sysinternals tool process monitor. It can be used to montior registry usage. This helps you track exactly what class the script is trying to load. Named COM classes reside under
查找缺少的类的一种方法是sysinternals工具进程监视器。它可以用于监控注册表的使用。这有助于您准确跟踪脚本尝试加载的类。命名的COM类位于
HKEY_LOCAL_MACHINE\SOFTWARE\Classes
and their underlying GUID entry is in
和他们的基础GUID条目在
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
If Apache is looking for an entry there but doesn't find it, that might be the COM class the perl script is missing.
如果Apache在那里寻找一个条目但却找不到它,那可能就是缺少perl脚本的COM类。
#3
Please tell me if this helps: You receive a "0x80040154 (Class not registered)" error message when you register an ATL server
请告诉我这是否有帮助:注册ATL服务器时收到“0x80040154(Class not registered)”错误消息
Depending on which tools the vendor has developed his application, it might be caused because of a DLL registration, which is actually not registered on your Windows Server 2003.
根据供应商开发其应用程序的工具,可能是由于DLL注册引起的,实际上没有在Windows Server 2003上注册。
#1
It seems to me that you have permission problem. It looks like your .NET application try to use a COM object and it has not enough permission to do this.
在我看来,你有权限问题。看起来您的.NET应用程序尝试使用COM对象,但它没有足够的权限来执行此操作。
Every COM object (COM server) has launch/activation and access permission (just start dcomcnfg
and look at DCOM configuration of some well known Applications). With respect of dcomcnfg
(Component Services) you can not only see but also change this permissions (select an application and open properties dialog in the context menu. Then choose "Security" tab, choose Customize in the "Launch and Activation Permission" block and then click "Edit"). Typical problem is that INTERACTIVE users have launch/activation permission to the most COM objects, but processes running as service are not a member of this group. So you have to customize permission by granting for an some account (used by your Apache web server) or a group (like a IIS_IUSRS
) the same launch permission which has INTERACTIVE users. This permission information will be saved in a subkey of the HKEY_CLASSES_ROOT\AppID
key (see binary AccessPermission
registry value).
每个COM对象(COM服务器)都具有启动/激活和访问权限(只需启动dcomcnfg并查看一些众所周知的应用程序的DCOM配置)。关于dcomcnfg(组件服务),您不仅可以查看,还可以更改此权限(在上下文菜单中选择应用程序和打开属性对话框。然后选择“安全”选项卡,在“启动和激活权限”块中选择自定义,然后单击“编辑”)。典型问题是INTERACTIVE用户对大多数COM对象具有启动/激活权限,但作为服务运行的进程不是该组的成员。因此,您必须通过向具有INTERACTIVE用户的相同启动权限授予某个帐户(由您的Apache Web服务器使用)或组(如IIS_IUSRS)来自定义权限。此权限信息将保存在HKEY_CLASSES_ROOT \ AppID密钥的子项中(请参阅二进制AccessPermission注册表值)。
To identify the COM object which makes problem I'll recommend you Process Monitor (see http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx) and Process Explorer (see http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx). Process Monitor can helps you to find out exactly which other processes your program ($vendorsExecutable
) try to start. One from the last accesses to HKEY_CLASSES_ROOT
are used to start a COM object. You will find out which process it is. Don't forget to start this tools under an account with full administrative rights (on a server such problem typically not exist). To find the information which you need more quickly use filter to a process name and searching features of Process Monitor.
要识别出问题的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的功能。
If you do such work at the first time it can look very complex. It is not easy, but everything have well defined logic and I am sure, that you solve this problem.
如果你第一次做这样的工作,它看起来很复杂。这并不容易,但一切都有明确的逻辑,我相信,你解决了这个问题。
#2
The typical cause would be that you did not install a prerequisite. It's hard to say which, because COM classes are used by so many applications.
典型的原因是您没有安装先决条件。很难说哪个,因为COM类被很多应用程序使用。
One way to find out the missing class is the sysinternals tool process monitor. It can be used to montior registry usage. This helps you track exactly what class the script is trying to load. Named COM classes reside under
查找缺少的类的一种方法是sysinternals工具进程监视器。它可以用于监控注册表的使用。这有助于您准确跟踪脚本尝试加载的类。命名的COM类位于
HKEY_LOCAL_MACHINE\SOFTWARE\Classes
and their underlying GUID entry is in
和他们的基础GUID条目在
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
If Apache is looking for an entry there but doesn't find it, that might be the COM class the perl script is missing.
如果Apache在那里寻找一个条目但却找不到它,那可能就是缺少perl脚本的COM类。
#3
Please tell me if this helps: You receive a "0x80040154 (Class not registered)" error message when you register an ATL server
请告诉我这是否有帮助:注册ATL服务器时收到“0x80040154(Class not registered)”错误消息
Depending on which tools the vendor has developed his application, it might be caused because of a DLL registration, which is actually not registered on your Windows Server 2003.
根据供应商开发其应用程序的工具,可能是由于DLL注册引起的,实际上没有在Windows Server 2003上注册。