65.9K
CodeProject 正在变化。 阅读更多。
Home

进程内服务器和 DCOMCNFG 工具

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (4投票s)

1999年12月9日

viewsIcon

76028

讨论 DLL 代理以及旧的进程内组件如何参与分布式环境

进程内服务器永远不能在没有父进程的情况下运行。就这样。然而,自从 Windows NT 4.0 Service Pack 2 发布以来,只要有一个代理可用以提供所需的地址空间,进程内服务器就可以被远程调用。其中一个代理是文件 dllhost.exe,它可以被远程调用,然后被指示加载任何进程内组件,为该组件提供一个代理父进程和安全上下文。但是,您如何设置安全权限、身份、客户端的身份验证级别以及客户端使用的协议和端点集,以用于此类进程内组件?设置此内容的一种简单方法是使用 DCOMCNFG 实用程序。但是,默认情况下,DCOMCNFG 实用程序不会列出驻留在进程内服务器中的组件。它只会列出在系统上注册的组件可执行文件。

运行 OLEViewer 并选择任何进程内 DLL 服务器对象。选择“实现”选项卡,然后选中“使用代理进程”复选框。提供自定义代理的路径或默认的 <\winnt\system32\dllhost.exe> 代理。选择“注册表”选项卡(这将添加 DllSurrogate 命名值,位于 AppID 键下)。

现在运行 DCOMCNFG 实用程序。进程内 DLL 服务器对象将显示在应用程序列表中。基本上,我们让 DCOMCNFG 实用程序相信,进程内 DLL 服务器对象不再是独立的,并且它有一个父进程,当它被远程调用时它将被驻留在这个父进程中。

示例项目

1. 选择 ATL COM AppWizard 并将 DLLSurr 作为项目的名称。确保选择服务器类型为动态链接库 (DLL)。
2. 添加一个名为 ATest 的新 ATL 对象。

构建并注册服务器。在 OLEViewer 中选择组件 ATest(Object Classes->All Objects->ATest)。选择“实现”选项卡,然后选中“使用代理进程”复选框。提供默认代理的路径,例如 <\winnt\system32\dllhost.exe>。选择“注册表”选项卡(这将添加 DllSurrogate 命名值,位于 AppID 键下)。现在运行 DCOMCNFG 并选择 ATest。选择“属性”、“安全”,然后编辑“使用自定义访问权限”并选择一个 NT 用户名(出于演示目的,您可能需要选择您的 NT 用户名)。从“访问类型”组合框中选择“拒绝访问”。一路单击“确定”以关闭 DCOMCNFG 实用程序。

启动服务器的客户端代码

#include "stdafx.h"
#include <comdef.h>
#import "..\DLLSurr.tlb" no_namespace named_guids

{
    // This block of code assumes that you have already
    // initialized COM libraries somewhere in your project.

    try
    {
        // For demo purpose, assume that the component is
        // launched on a local m/c.

        // Try to inject the component server into dllhost.exe's
        // address space
        IATestPtr ptrTest = NULL;
        HRESULT hr = ptrTest.CreateInstance(CLSID_ATest,
                NULL, CLSCTX_LOCAL_SERVER /*This flag is important*/);
        if(FAILED(hr))
        {
            TRACE("Failed to create ATest component.\n");
            _com_issue_error(hr);
        }
    }
    catch(_com_error& e)
    {
        TRACE(e.ErrorMessage() + _bstr_t("\n")); // Probably, the trace should
                                                 // be <Access is denied>!
        if(e.ErrorInfo())
            TRACE(e.Description() + "\n");
    }

    // At this point, if you see the processes list in the Task Manager,
    // you will find dllhost.exe sitting there. Kill that process before
    // you change any security settings in the DCOMCNFG utility for the
    // component.
}

或者,您也可以在 OLEViewer 中测试服务器。从菜单中,选择“对象...CoCreateInstance 标志”,选择 CLSCTX_LOCAL_SERVER 并取消选择所有其他项目。右键单击组件名称,选择“创建实例于...”,然后输入您的机器名称。

结论

本文简要讨论了 DLL 代理以及如何使旧的进程内组件参与分布式环境。

有趣的是,Microsoft SQL Server 扩展存储过程(它们只是 DLL)在 SQL Server 地址空间中运行,并且行为不当的扩展存储过程可能会导致 SQL Server 崩溃。

参考文献

1. Inside Distributed COM, Guy Eddon 和 Henry Eddon,Microsoft Press 1998。
2. MSDN 库 1999 年 4 月。

系统要求

Microsoft Visual C++ 6.0 w/ sp3, NT 4.0 w/ sp4。

© . All rights reserved.