三层 dcom配置,客户端提示: interface not supported
DCOM配置
如果在Windows NT环境下正常运行应用服务器,必须进行DCOM配置。配置方法如下:
1. 运行NT服务器上的dcomcnfg程序,进行DCOM配置。
2. 进入DCOM的总体默认属性页面,将“在这台计算机上启用分布式COM”打上勾,将默认身份级别改为“无”。
3. 进入DCOM的总体默认安全机制页面,确认默认访问权限和默认启动权限中的默认值无EveryOne,如果不去掉EveryOne,应用服务器不能正常启动。
4.在常规页面中,双击你的应用服务器,打开你的应用服务器DCOM属性设置。
5.将常规页面中的身份验证级别改为“无”。
6.位置页面中选上“在这台计算机上运行应用程序”。
7.将安全性页面设置中,均选择“使用自定义访问权限”,编辑每一个权限,将EveryOne加入用户列表中。
8.身份标识页面中,选择“交互式用户”。
9.NT的GUEST用户不能禁用。
我是按照这样的方式配置的,可客户端总是 : interface not supported.
我查过很多的资料,试过很多方法(在客户端注册 server,甚至delphi都装了)
有做过dcom的,希望能不吝赐教。如果分数不够可以再开贴。
其实 interface not supported 是个非常有名的(delphi)dcom三层问题,引起的原因也很多,大家都来讨论讨论,共同提高。
问题点数:200、回复次数:29Top
1 楼zhuminghua()回复于 2006-08-26 17:30:48 得分 0
沙发,关注Top
2 楼CoolSlob()回复于 2006-08-27 08:22:01 得分 0
1, 组件服务->计算机->我的电脑->COM+应用程序->(你的COM名称)->新建一个角色(名称任意)->用户->添加用户(everyone)
2, 在客户端注册midas.dll
CSDN论坛浏览器:浏览、发帖、回复、结贴自动平均给分,下载地址:http://CoolSlob.ys168.comTop
3 楼FigoZhu(谢慕安)回复于 2006-08-28 10:38:35 得分 0
帮顶,接分。Top
4 楼dabaicai(烈士暮年)回复于 2006-08-28 14:24:52 得分 0
DCOM最简单的安全控制,(如果你服务器端和客户端没有加入并登录一个域的话)在你的服务器端,增加一个(guest)用户,用户名和密码是你客户端机器的登录名和密码,就可以访问了
这个方面的问题很麻烦,那就是你以后的每个客户端用户名不能相同,比如有些机器用的是administrator,就必须重命名这个用户(用户管理中可以更改),如果客户端多的话,你的服务器端会增加很多用户Top
5 楼bluz()回复于 2006-08-28 14:41:04 得分 0
首先确认创建COM对象是用.CreateRemote不是用create
其次把你的COM SERVER和客户程序装在同一台电脑看是否可以访问
最后在不同机器上测试Top
6 楼hare007(hare)回复于 2006-08-29 01:19:26 得分 0
谢谢大家,在同一台机器上,没问题的。如果真的如 “dabaicai(不再做菜鸟) ”所说的话,可真是个不小的问题啊,客户端如果是98,那就更麻烦了。还不如,换成socket呢,真不知道,用过dcom的是怎么整的。Top
7 楼dabaicai(烈士暮年)回复于 2006-08-29 08:58:01 得分 0
几年前我们做的东西,后来就用socksvr代替了,给客户用的时候还要一个个加,太麻烦Top
8 楼hare007(hare)回复于 2006-08-29 09:38:36 得分 0
是啊,如果客户修改登陆名称,或者密码,也是个麻烦事,可扩展性、维护性比较差Top
9 楼dabaicai(烈士暮年)回复于 2006-08-29 09:59:36 得分 0
所以一般情况下,比较大的企业会有域服务器,所有的机器都是登录域的,那样的话就没有这个问题Top
10 楼bluz()回复于 2006-08-29 12:14:17 得分 0
并非如此,DCOM安全性上并没有要求客户端必须用服务器上的用户名和密码,你可以在dcomcnfg里面设置启动程序的时候用某个NT用户,例如dcomuser,这样用户仍然是用匿名连接到dcom所在的服务器,但是启动程序用dcomuser,这样就有足够的权限Top
11 楼hare007(hare)回复于 2006-08-29 16:33:26 得分 0
现在,我的客户端能让服务器自动启动,但是总是出现:interface not supported 如果用服务器上的用户登陆客户端,就能成功。Top
12 楼bluz()回复于 2006-08-29 18:43:16 得分 0
那说明匿名用户在服务器上的权限不够,还是改用普通用户好了Top
13 楼hare007(hare)回复于 2006-08-30 10:41:00 得分 0
to:bluz()
匿名权限不够,那怎么设置匿名权限?如果客户端注销后用guest用户登陆,然后连接服务器是没问题的。Top
14 楼wind235(passerWind)回复于 2006-08-30 11:12:45 得分 0
我最近也非常郁闷了。
是关于COM+的配置。
Server是XP client是2000。
client端非要以Server端登陆用户登陆才创建组件。
其它用户都不行,当然这是才工作组中,还没有试过域
在工作组中,有什么其它方法吗? XP不存在这样的问题。Top
15 楼bluz()回复于 2006-08-30 13:14:25 得分 0
你可以在打开dcomcnfg,再打开你的程序的属性页,在最后一个“标识”页上,选择“下列用户”,选一个非guest用户就可以了Top
16 楼MEFULEU(没有作不到,只有想不到)回复于 2006-08-30 17:26:04 得分 0
DCOM和多层应用系统的配置
客户端配置如下:
1. 先把服务器在客户端运行,系统会自动注册,然后点”开始”->”运行”,输入”dcomcnfg”,然后回车,启动dcom配置。
2. 常规页面中,双击你的应用服务器,打开你的应用服务器DCOM属性设置。
3. 将常规页面中的身份验证级别改为“无”。
4. 身份标识页面中,选择“交互式用户”。
5. 位置页面中选上“在数据所在的计算机上运行应用程序”。
6. 进入DCOM的总体默认属性页面,将“在这台计算机上启用分布式COM”打上勾,将默认身份级别改为“无”。
服务器端配置如下:
1. 运行NT服务器上的dcomcnfg程序,进行DCOM配置。
2. 进入DCOM的总体默认属性页面,将“在这台计算机上启用分布式COM”打上勾,将默认身份级别改为“无”。
3. 进入DCOM的总体默认安全机制页面,确认默认访问权限和默认启动权限中的默认值无EveryOne,如果不去掉EveryOne,应用服务器不能正常启动。
4.在常规页面中,双击你的应用服务器,打开你的应用服务器DCOM属性设置。
5.将常规页面中的身份验证级别改为“无”。
6.位置页面中选上“在这台计算机上运行应用程序”。
7.将安全性页面设置中,均选择“使用自定义访问权限”,编辑每一个权限,将EveryOne加入用户列表中。
8.身份标识页面中,选择“交互式用户”。
9.NT的GUEST用户不能禁用。Top
17 楼MEFULEU(没有作不到,只有想不到)回复于 2006-08-30 17:28:31 得分 0
客户端需要运行regsvr32 midas.dll,regsvr32 stdvcl40.dll
服务端需要运行dcomcnfg进入“分布式COM配置属性”
1 “默认属性”页面,将“在这台计算机上启用分布式COM”打勾,将“默认身份验证级别”改为“无”。默认模拟级别"匿名"
2 “默认安全机制”页面,确认默认访问权限和默认启动权限中的默认值无EveryOne,如果有将其删除。
3 “应用程序”页面,双击你的应用服务器,打开你的应用服务器Dcom属性
4 “常规”页面的“身份验证级别”为“默认值”。
5 “位置”页面的“在这台计算机上运行应用程序”打勾。
6 “安全”页面中,均选择“使用自定义访问权限”,编辑每一个权限,将EveryOne加入用户列表中。
7 “身份标识”页面中,选择“交互用户”。
客户端需要运行dcomcnfg进入“分布式COM配置属性”
1 “默认属性”页面,将“在这台计算机上启用分布式COM”打勾,将“默认身份验证级别”改为“无”。默认模拟级别"匿名"Top
18 楼JB7(bovey)回复于 2006-08-30 21:47:44 得分 0
DDCOM的设置问题,不如有SOCKET吧.Top
19 楼wind235(passerWind)回复于 2006-08-31 09:03:26 得分 0
midas.dll???什么东东 delphi中需要?Top
20 楼d0347(旭日升群枭)回复于 2006-10-15 20:16:23 得分 0
用 TSocketConnection 吧 ,
但服务器需要启动c:\Program Files\Borland\Delphi7\Bin\scktsrvr.exe
客户端需要注册 midas.dll, midas.dll在system32文件夹下面(有装delphi的电脑都有)Top
21 楼gzlcd()回复于 2006-10-16 09:46:37 得分 0
即使是用Socket 方式连接,在服务器端仍然要设置角色!否则有可能COM+ 对象不能激活.Top
22 楼quicksand201(流沙)回复于 2006-10-24 01:11:26 得分 0
[首页] [开发语言 - Delphi]
DCOM,连接服务器的问题
2006-02-16 14:22:18
发贴人: bloodsucker
使用三层数据库,
客户端使用DCOM,连接服务器,
现在我把两台机子连接起来,
一台作为客户端,一台作为服务器,
但是当客户端DCOM 的SERVER NAME 选择其他主机时,
却告之 RPC不可用 或者 拒绝访问。
这怎么解决?
2006-02-16 16:24:00
回复人: xtjsxtj
2000下的配置:
DCOM配置
如果在Windows NT环境下正常运行应用服务器,必须进行DCOM配置。配置方法如下:
1.运行NT服务器上的dcomcnfg程序,进行DCOM配置。
2.进入DCOM的总体默认属性页面,将“在这台计算机上启用分布式COM”打上勾,将默认
身份级别改为“无”。
3.进入DCOM的总体默认安全机制页面,确认默认访问权限和默认启动权限中的默认值无EveryOne,
如果不去掉EveryOne,应用服务器不能正常启动。
4.在常规页面中,双击你的应用服务器,打开你的应用服务器DCOM属性设置。
5.将常规页面中的身份验证级别改为“无”。
6.位置页面中选上“在这台计算机上运行应用程序”。
7.将安全性页面设置中,均选择“使用自定义访问权限”,编辑每一个权限,将EveryOne加入用
户列表中。
8.身份标识页面中,选择“交互式用户”。
9.NT的GUEST用户不能禁用。
注意:关键所在,在控制面板--用户和密码里administrators用户的属性--隶属于里添加power users,其它用户也这样做,guest用户绝对不可以禁用
2006-02-16 16:25:35
回复人: xtjsxtj
以远程计算机上的用户身份访问Com+应用
DELPHI程序员开发com+应用的速度是非常快的,其主要原因是其较好地封装了com+的windows底层功能,
开发人员通过较为简单的类继承就避开了复杂的com+底层技术细节,使开发人员将精力放在应用本身的
功能上面。Delphi在封装com+应用时采取了许多折衷,在保留通用性的同时也避开了一些实现起来困难
但是应用面不太广的com+底层特性。这些避开的特性中最令delphi com开发人员关心的就是安全特性。
从delphi 5开始,有许多人都面临过这样的问题:com应用开发出来并且在本机上运行一切正常,
但是一旦分发出去实施远程访问时,就无法正常运行了。我自己有段时间在看到“拒绝访问”错误提示时
会本能的头晕。其实认真追究起来,还是因为自己对windows安全技术了解不多造成的。多年来我一直
没有发现国内有windows安全方面比较系统的资料和书籍,直到Keith Brownr的<windows安全性编程>
中文版的出现。正是基于这本书我才有了下面的一些试验,也知道了为什么我老是被拒绝的原因。
下面的讨论只是我在解决自身现有代码的安全访问问题时,总结出的几个小经难方法。
建议愿意了解windows安全性的朋友去看一看<windows安全性编程>一书,你会发现windows的安全不再神秘。
这篇文章将会说明如何以远程工作站上的用户身份激活com+对象,并以此用户身份访问Interface。
1、Delphi默认com+对象的远程激活
Delph中远程com+对象激活一般通过TdispatchConnection及其子类来实现,实际代码中多用
TDCOMConnection或TsocketConnectoion这两个组件,TDCOMConnection组件最终调用CoCreateInstanceEx
创建com+对象。CoCreateInstanceEx(const clsid: TCLSID; unkOuter: IUnknown; dwClsCtx: Longint;
ServerInfo:PCoServerInfo;dwCount: Longint; rgmqResults: PMultiQIArray): HResult。
TDCOMConnection在调用CoCreateInstanceEx时为pCoServerInfo参数中的pAuthInfo传递了Null值,
因此TdcomConnection在创建Com对象时使用的是本地计算机登录者的用户令牌。假若A计算机上的登录用户
Auser使用TDCOMConnection类连接远程计算机B上的com+对象,则B计算机会使用Auser的用户名/密码在B计
算机上建立登录会话并最终创建com+对象。但是一台windows工作站上的本地用户只能在本地登录而无法在
别的计算机上登录,因此A计算机上的Auser就无法在B工作站上建立登录会话,当然也就无法创建com+对象,
此时远程工作站B会尝试用Guest帐户建立会话并使用该账户激活com+对象。在这种情况下,如果B工作站上
的Guest账户没有启用或Guest没有激活com+对象的权限,你就会看见令人头晕的提示“拒绝访问”。看到这里
你是不对现在网上最“流行”的dcom配置方法有所悟了呢。那个方法就是允许everyone访问、激活com对象、
并且将“默认身份验证级别”设置成无。这种方法能够使你的com应用可以“用了”,但是,它可以上“任何人”
访问。而且这种设置你将无法利用com+基于角色的安全访问控制功能。Top
23 楼quicksand201(流沙)回复于 2006-10-24 01:12:14 得分 0
2、怎样不用GUEST账户激活
这个问题的实际上应该是:怎样用远程工作站上的用户激活远程com对象。解决这个问题其实很简单:
只要你在调用CoCreateInstanceEx时为它指定远程工作站上的用户名和密码,只要用户名/密码通过远程
计算机的验证,并且该用户被授予了“远程激活”com+对象的权限,那么远程工作站会用该用户身份激活com+
对象。
看一下代码:
var
mts:IMTSXjpimsDB;
ov:Variant;
i:integer;
cai:_CoAuthInfo;
cid:_CoAuthIdentity;
csi:COSERVERINFO;
mqi:MULTI_QI;
iid_unk:TGUID;
idsp:IDispatch;
wUser,wDomain,wPsw:WideString;
begin
wUser:=eduser.text;//用户名
wDomain:=edSvr.Text;//远程计算机名
wPsw:=edPsw.Text;//密码
cid.user:=pUnshort(@wUser[1]);
cid.UserLength:=length(wUser);
cid.Domain:=pUnshort(@wDomain[1]);
cid.DomainLength:=length(wDomain);
cid.password:=pUnshort(@wPsw[1]);
cid.PasswordLength:=length(wPsw);
cid.Flags:=2;
//以上填充_CoAuthIdentity结构
cai.dwAuthnSvc:=10;//winNt默认的鉴证服务
cai.dwAuthzSvc:=0;
cai.pwszServerPrincName:=wDomain;
cai.dwAuthnLevel:=0;
cai.dwImpersonationLevel:=3;//必须设置成模拟
cai.pAuthIdentityData:=@cid;
cai.dwCapabilities:=$0800;
//以上填充_CoAuthInfo结构
FillChar(csi, sizeof(csi), 0);
csi.dwReserved1:=0;
csi.pwszName:=pwidechar(wdomain);
csi.pAuthInfo:=@cai;
//以上填充COSERVERINFO结构
iid_unk:=IUnknown;
mqi.IID:=@iid_unk;mqi.Itf:=nil;mqi.hr:=0;
Screen.Cursor:=crHourGlass; olecheck(CoCreateInstanceEx(CLASS_MTSXjpimsDB,nil,
CLSCTX_REMOTE_SERVER,@csi,1,@mqi));
这段代码中除了最后实际调用CoCreateInstanceEx外,前面的代码都是设置参数。这些参数的含义请大家
参考msdn,除了用户名、主机名、密码外,只有一个重要要部分要说明:cai.dwImpersonationLevel必须
设置成允许模拟(值为3),否则远程计算机将无法按提供的用户/密码建议网络会话。
3、不修改现有代码,可以实现用远程用户身份激活吗?
当然可以,我扩展了TDcomConnection类,为其加入了用户名和密码,并修改其默认的DoConnect方法,
使其在调用CoCreateInstanceEx时用指定的用户名和密码填充参数。代码如下:
2006-02-16 16:26:07
回复人: xtjsxtj
unit SecDComConnection;
interface
uses
windows,SysUtils, Classes,ActiveX, DB, DBClient, MConnect,comobj,Midas;
type
{typedef struct _SEC_WINNT_AUTH_IDENTITY
unsigned short __RPC_FAR* User;
unsigned long UserLength;
unsigned short __RPC_FAR* Domain;
unsigned long DomainLength;
unsigned short __RPC_FAR* Password;
unsigned long PasswordLength;
unsigned long Flags;
SEC_WINNT_AUTH_IDENTITY, *PSEC_WINNT_AUTH_IDENTITY;
}
{typedef struct _COAUTHIDENTITY
USHORT * User;
ULONG UserLength;
USHORT * Domain;
ULONG DomainLength;
USHORT * Password;
ULONG PasswordLength;
ULONG Flags;
COAUTHIDENTITY;}
{#define RPC_C_AUTHN_NONE 0
#define RPC_C_AUTHN_DCE_PRIVATE 1
#define RPC_C_AUTHN_DCE_PUBLIC 2
#define RPC_C_AUTHN_DEC_PUBLIC 4
#define RPC_C_AUTHN_GSS_NEGOTIATE 9
#define RPC_C_AUTHN_WINNT 10
#define RPC_C_AUTHN_GSS_SCHANNEL 14
#define RPC_C_AUTHN_GSS_KERBEROS 16
#define RPC_C_AUTHN_MSN 17
#define RPC_C_AUTHN_DPA 18
#define RPC_C_AUTHN_MQ 100
#define RPC_C_AUTHN_DEFAULT 0xFFFFFFFFL
}
{#define RPC_C_AUTHZ_NONE 0
#define RPC_C_AUTHZ_NAME 1
#define RPC_C_AUTHZ_DCE 2
#define RPC_C_AUTHZ_DEFAULT 0xFFFFFFFF }
{
#define RPC_C_AUTHN_LEVEL_DEFAULT 0
#define RPC_C_AUTHN_LEVEL_NONE 1
#define RPC_C_AUTHN_LEVEL_CONNECT 2
#define RPC_C_AUTHN_LEVEL_CALL 3
#define RPC_C_AUTHN_LEVEL_PKT 4
#define RPC_C_AUTHN_LEVEL_PKT_INTEGRITY 5
#define RPC_C_AUTHN_LEVEL_PKT_PRIVACY 6 }
{SEC_WINNT_AUTH_IDENTITY_UNICODE=2 }
pUnShort=^Word;
pCoAuthIdentity=^_CoAuthIdentity;
_CoAuthIdentity=record
user:pUnShort;
UserLength:ULONG;
Domain:pUnShort;
DomainLength:Ulong;
password:pUnShort;
PasswordLength:ulong;
Flags:ulong;
end;
_CoAuthInfo=record
dwAuthnSvc:DWORD;
dwAuthzSvc:DWORD;
pwszServerPrincName:WideString;
dwAuthnLevel:Dword;
dwImpersonationLevel:dword;
pAuthIdentityData:pCoAuthIdentity;
dwCapabilities:DWORD;
end;
Top
24 楼quicksand201(流沙)回复于 2006-10-24 01:12:26 得分 0
TSecDComConnection = class(TDCOMConnection)
private
FCai:_CoAuthInfo;
FCid:_CoAuthIdentity;
FSvInfo:COSERVERINFO;
FUser:WideString;
FPassWord:WideString;
procedure SetPassword(const Value: wideString);
procedure SetUser(const Value: wideString);
procedure SetSvInfo(const Value: COSERVERINFO);
protected
procedure DoConnect; override;
public
property SvInfo:COSERVERINFO read FSvInfo write SetSvInfo;
constructor Create(AOwner: TComponent); override;
procedure MySetBlanket(itf:IUnknown;const vCai:_CoAuthInfo);
function GetServer: IAppServer; override;
published
property User:wideString read FUser write SetUser;
Property Password:wideString read FPassword write SetPassword;
end;
procedure Register;
implementation
constructor TSecDCOMConnection.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FillMemory(@Fcai,sizeof(Fcai),0);
FillMemory(@FCid,sizeof(FCid),0);
FillMemory(@FSvInfo,sizeof(FSvInfo),0);
with FCai do begin
dwAuthnSvc:=10;//RPC_C_AUTHN_WINNT
dwAuthzSvc:=0;// RPC_C_AUTHZ_NONE
dwAuthnLevel:=0;//RPC_C_AUTHN_LEVEL_DEFAULT
dwImpersonationLevel:=3;
pAuthIdentityData:=@fcid;
dwCapabilities:=$0800;
end;
end;
procedure TSecDCOMConnection.DoConnect;
var
tmpCmpName:widestring;
IID_IUnknown:TGUID;
iiu:IDispatch;
Mqi:MULTI_QI;
qr:HRESULT;
begin
if (ObjectBroker) <> nil then
begin
repeat
if ComputerName = '' then
ComputerName := ObjectBroker.GetComputerForGUID(GetServerCLSID);
try
SetAppServer(CreateRemoteComObject(ComputerName, GetServerCLSID) as IDispatch);
ObjectBroker.SetConnectStatus(ComputerName, True);
except
ObjectBroker.SetConnectStatus(ComputerName, False);
ComputerName := '';
end;
until Connected;
end
else if (ComputerName <> '') then
begin
with fcid do begin
user:=pUnshort(@fuser[1]);
UserLength:=length(fuser);
tmpCmpName:=ComputerName;
Domain:=pUnshort(@tmpCmpName[1]);
DomainLength:=length(TmpCmpName);
password:=pUnShort(@FPassword[1]);
PasswordLength:=length(FPassword);
Flags:=2;//Unicode
end;
FSvInfo.pwszName:=pwidechar(tmpCmpName);
FSvinfo.pAuthInfo:=@Fcai;
IID_IUnknown:=IUnknown;
mqi.IID:=@IID_IUnknown;mqi.Itf:=nil;mqi.hr:=0;
olecheck(CoCreateInstanceEx(GetServerCLSID,nil,CLSCTX_REMOTE_SERVER,@FSvinfo,1,@mqi));
olecheck(mqi.hr);
MySetBlanket(mqi.Itf,Fcai);
qr:=mqi.Itf.QueryInterface(idispatch,iiu);
olecheck(qr);
MySetBlanket(IUnknown(iiu),FCai);
SetAppServer(iiu);
end
else
inherited DoConnect;
end;
function TSecDComConnection.GetServer: IAppServer;
var
QIResult: HResult;
begin
Connected := True;
QIResult := IDispatch(AppServer).QueryInterface(IAppServer, Result);
if QIResult <> S_OK then
begin
Result := TDispatchAppServer.Create(IAppServerDisp(IDispatch(AppServer)));
end;
MySetBlanket(IUnknown(Result),FCai);
end;
procedure TSecDCOMConnection.MySetBlanket(itf: IUnknown;
const vCai: _CoAuthInfo);
begin
with vCai do
CoSetProxyBlanket(Itf,dwAuthnSvc,dwAuthzSvc,pwidechar(pAuthIdentityData^.Domain),
dwAuthnLevel,dwImpersonationLevel,pAuthIdentityData,dwCapabilities);
end;
procedure TSecDCOMConnection.SetPassword(const Value: wideString);
begin
FPassword := Value;
end;
procedure TSecDCOMConnection.SetSvInfo(const Value: COSERVERINFO);
begin
FSvInfo := Value;
end;
procedure TSecDCOMConnection.SetUser(const Value: wideString);
begin
FUser := Value;
end;
procedure Register;
begin
RegisterComponents('DataSnap', [TSecDComConnection]);
end;
end.Top
25 楼xhhero()回复于 2006-11-05 21:26:11 得分 0
upTop
26 楼d0347(旭日升群枭)回复于 2006-11-15 19:52:57 得分 0
quicksand201(流沙) 好强哦^_^
不过我比较怕麻烦,都是用SocketTop
27 楼wzg1031(0223)回复于 2006-11-16 11:34:15 得分 0
前不久也遇到此问题,你在服务器端和客户端,将组件服务中-》安全设置页中的授权不选中就行了Top
28 楼wxch(wxch)回复于 2007-02-20 08:57:35 得分 0
可以使用TSocketConnection,然后在客户机上注册regsvr32 midas.dll。Top
29 楼yifan1008(一帆)回复于 2007-04-11 14:01:32 得分 0
在客服端注册表添加
HKEY_CLASSES_ROOT\Hrm_Server.MainRDM (服务端的名称)
HKEY_CLASSES_ROOT\Hrm_Server.MainRDM\Clsid
{2CBB7AF1-765B-4C27-BAD1-61F9C8C6F7E9} CLASS_ : TGUID (服务端的TGUID)Top




