代码之家  ›  专栏  ›  技术社区  ›  Kurt W. Leucht

InteropServices在Windows Server 2003上从Web CGI脚本执行.NET应用时发生异常

  •  0
  • Kurt W. Leucht  · 技术社区  · 15 年前

    免责声明:我对.NET和COM一无所知。

    我有一个供应商的应用程序似乎是用.NET编写的,我正试图用一个Web表单(一个cgi-bin-perl脚本)来包装它,这样我最终可以从一台单独的计算机上启动这个供应商的应用程序。我使用的是Windows Server 2003 R2 SE SP1系统,Web服务器使用的是Apache2.2,CGI脚本使用的是ActivePerl5.10.0.1004。我的CGI脚本使用perl backtick操作符调用驻留在同一台机器上的供应商应用程序。

    ...
    $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命令行运行Vendors应用程序时,使用与CGI脚本传递的参数完全相同的参数,它运行得很好,因此通过Web脚本调用他们的应用程序会导致问题。这个问题可能与安全相关,因为整个系统在Windowsxppro机器上运行得很好(命令行和Web调用)。实际上,我在那里开发了我的Web脚本,并在我尝试将它移到WindowsServer2003机器之前使它完全在那里工作。那么,WindowsServer2003机器有什么不同,它可以防止供应商的.NET应用程序被web cgi脚本成功执行?

    我可以通过某种方式解决这个问题,使它在我的服务器上运行吗?或者供应商必须更改他们的.NET应用程序并发布一个新版本吗?我可能是世界上唯一一个试图从一个单独的程序中执行这个供应商的应用程序的人,所以如果有一个我可以在我的服务器机器上实现的解决方案,我不想用这个问题来打扰供应商。另外,我有点着急,我不想等4到6个月,让供应商进行修复并部署新版本。

    谢谢你的建议。

    3 回复  |  直到 14 年前
        1
  •  2
  •   Oleg    14 年前

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

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

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

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

        2
  •  1
  •   Andomar    15 年前

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

    找到缺失类的一种方法是SysInternals工具 process monitor .它可以用来监视注册表的使用情况。这有助于准确跟踪脚本试图加载的类。命名的COM类位于

    HKEY_LOCAL_MACHINE\SOFTWARE\Classes
    

    它们的基础guid项位于

    HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
    

    如果Apache在那里寻找一个条目,但没有找到它,那么可能是Perl脚本缺少的COM类。

        3
  •  0
  •   Will Marcouiller    14 年前

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

    根据供应商开发其应用程序的工具,这可能是由于DLL注册导致的,该注册实际上未在Windows Server 2003上注册。