能否利用socketconnection使用远程com(Dcom)组件?(300分)

  • 主题发起人 主题发起人 远帆
  • 开始时间 开始时间

远帆

Unregistered / Unconfirmed
GUEST, unregistred user!
Dcom组件可以远程调用,不过配置起来实在是麻烦。
datasnap里面的几个链接组件socketconn、webconn都可以远程调用remote datamodule中的
方法。所以我想不知道能不能利用socketconn调用远程com(dcom)中的方法呢?
如果能,请告诉我怎么做,如果不能也请告诉我为什么。
 
当然可以了,和DCOM一样的调用方法呀!
 
什么意思?好像不能在socketconn的下拉列表框中看到com服务器啊?
 
楼主说的是远程的MTS组件吧,
用socketConnection可以吗,我真的不太相信
 
to Tassadar:
  请你指点,我到现在还没有弄清remote datamodule是个什么东西。
 
你可以新建立一个Remote DataModule,但不要放任何数据控件.
他就相当于帮你建立了一个接口.你可以通过Type library editor在这个接口中添加方法属性等.远程是可以调用的.在服务端运行SockSrvr就可以通过SocketConnection连接了.
RemoteDataModule在接口中已经帮你实现了几个方法,使用来访问DataSetProvider组件用的.
 
谢谢LeeChange,我就是说的是这个意思,不过我不想去建一个RemoteDataModule,能不能
在Com或Dcom的接口中采用某种方式摹仿RemoteDataModule,让客户能够能过socketconn调
用?
或者更改socketsrvr(不记得不是这个名字,我现在用的机子上没有这些东东),让它能够
支持一般的com或dcom?
我想socketconn既然可以远程调用remotedatamodule中的方法,应该也是可以调用com中的
啊,不知是不是什么地方做了人为的限制?
 
呵呵,Remote DataModule模仿了Com(实际他就是一个Com),而不是Com去模仿RDM,你完全可以不建立RDM而直接New一个Com Object或者Automation Object.一样可以在接口里添属性写方法,一样可以远程调用。为了SockSrvr能够找到他,必须调用EnableSocketTransport函数,参数写对象的GUID.该函数位于DataBkr单元。
SockSrvr.exe在Delphi的bin路径下。
 
嗯,我知道remotedatamodule是com,我感觉remote datamodule是borland帮助我们封装了
一些数据集传递函数的com。
我看过资料说SockSrvr只能显示EnableSocketTransport(安全)的Com(不知是不
是?)
如果是这样的话,其实不用改什么,只需要运行SockSrvr时把“只显示安全???”属性
去掉就行了。但是我这样试了一下,也没有多列出什么组件。(我没有自已新编什么组件
来试验,不过我想系统中COM组件够多的,如果这样就行了,SockSrvr应该会列出很多)
 
帆兄,最近可好?
 
还可以吧,我准备到东莞去了。这个问题你知不知道怎么解决的?
 
必须是Categories为{13E85B3C-9508-11D2-AB63-00C04FA35CFA}(MIDAS_Appserver的GUID)的Object才能被几个Connection控件找到.我翻到了如下代码.
class procedure TRemoteDataModule.UpdateRegistry(Register: Boolean;
const ClassID, ProgID: string);
var
CatReg: ICatRegister;
Rslt: HResult;
CatInfo: TCATEGORYINFO;
Description: string;
begin
Rslt := CoCreateInstance(CLSID_StdComponentCategoryMgr, nil,
CLSCTX_INPROC_SERVER, ICatRegister, CatReg);
if Succeeded(Rslt) then
begin
if Register then
begin
CatInfo.catid := CATID_MIDASAppServer;
CatInfo.lcid := $0409;
StringToWideChar(MIDAS_CatDesc, CatInfo.szDescription,
Length(MIDAS_CatDesc) + 1);
OleCheck(CatReg.RegisterCategories(1, @CatInfo));
//下面这句是关键
OleCheck(CatReg.RegisterClassImplCategories(StringToGUID(ClassID), 1, @CATID_MIDASAppServer));
end else
begin
OleCheck(CatReg.UnRegisterClassImplCategories(StringToGUID(ClassID), 1, @CATID_MIDASAppServer));
DeleteRegKey(Format(SClsid + SCatImplBaseKey, [ClassID]));
end;
end else
begin
if Register then
begin
CreateRegKey('Component Categories/' + GUIDToString(CATID_MIDASAppServer), '409', MIDAS_CatDesc);
CreateRegKey(Format(SClsid + SCatImplKey, [ClassID, GUIDToString(CATID_MIDASAppServer)]), '', '');
end else
begin
DeleteRegKey(Format(SClsid + SCatImplKey, [ClassID, GUIDToString(CATID_MIDASAppServer)]));
DeleteRegKey(Format(SClsid + SCatImplBaseKey, [ClassID]));
end;
end;
if Register then
begin
Description := GetRegStringValue(SClsid + ClassID, '');
CreateRegKey('AppID/' + ClassID, '', Description);
CreateRegKey(SClsid + ClassID, 'AppID', ClassID);
end else
DeleteRegKey('AppID/' + ClassID);
end;
如果想自己让一个Com对象能被Connection组件发现,可以调用这个函数,或者直接在注册表里加.
 
ISy_ComDataModuleDisp(IDispatch(socketconnection.AppServer)).过程或函数名 ;
其中:ISy_ComDataModule 是定义的接口名
 
你是说只要用CatReg.RegisterClassImplCategories方法注册一下就行了?
非常感谢,我回头去试一试。
以前用Dcom的方式做了一个系统,后来配置实在是烦死人,真是难以想像以后到客户那边去
怎么弄,呵呵~要是能够用Socket调用那就实在太爽了。
不过LeeChange兄,你是如何找到的?呵呵~千万不要告诉我直接看TRemoteDataModule.UpdateRegistry就知道了:)
 
To Carson_zzd:
你的那个是什么意思?
 
呵呵,Connection控件找到是一回事,能调用又是一回事.还有待实践的检验.
我是先找到了下面这个函数,就是Connection控件用来罗列Server列表用的.
procedure GetMIDASAppServerList(List: TStringList;
const RegCheck: string);
var
EnumGUID: IEnumGUID;
Fetched: Cardinal;
Guid: TGUID;
Rslt: HResult;
CatInfo: ICatInformation;
I, BufSize: Integer;
ClassIDKey: HKey;
S: string;
Buffer: array[0..255] of Char;
begin
List.Clear;
Rslt := CoCreateInstance(CLSID_StdComponentCategoryMgr, nil,
CLSCTX_INPROC_SERVER, ICatInformation, CatInfo);
if Succeeded(Rslt) then
begin
//关键是这句**************************************************************
[red]OleCheck(CatInfo.EnumClassesOfCategories(1, @CATID_MIDASAppServer, 0, nil, EnumGUID));[/red]
while EnumGUID.Next(1, Guid, Fetched) = S_OKdo
begin
if RegCheck <> '' then
begin
S := SClsid + GuidToString(Guid) + '/';
if GetRegStringValue(S, RegCheck) <> SFlagOn then
continue;
end;
List.Add(ClassIDToProgID(Guid));
end;
end else
begin
if RegOpenKey(HKEY_CLASSES_ROOT, 'CLSID', ClassIDKey) <> 0 then
try
I := 0;
while RegEnumKey(ClassIDKey, I, Buffer, SizeOf(Buffer)) = 0do
begin
S := Format(SCatImplKey, [Buffer, GUIDToString(CATID_MIDASAppServer)]);
if RegQueryValue(ClassIDKey, PChar(S), nil, BufSize) = 0 then
if RegCheck <> '' then
begin
BufSize := 256;
SetLength(S, BufSize);
if RegQueryValueEx(ClassIDKey, PChar(RegCheck), nil, nil,
PByte(PChar(S)), @BufSize) = ERROR_SUCCESS then
SetLength(S, BufSize - 1) else
S := '';
if GetRegStringValue(S, RegCheck) <> SFlagOn then
continue;
end;
List.Add(ClassIDToProgID(StringToGUID(Buffer)));
Inc(I);
end;
finally
RegCloseKey(ClassIDKey);
end;
end;
end;
 
好,谢谢你,我暂时不发分。
待我回去试验一下,把结果返馈一下,再发。
 
SocketConnection 的本质就是把DCOM调用转化为本地COM调用,
不但支持所有的DCOM调用,而且还支持回调(Callback,服务器端调用客户端)
Borland实现了,TStreamConnection的虚拟类,
可以在此基础上实现自己的连接类型,甚至在串行口上实现DCOM调用都是可能的
 
哦,谢谢你们。看Com已经有好长一段时间了,到现在也才只是摸到一点门,感觉比VCL的那
一套要复杂。看来还是要多看看delphi提供的源码(看着com里面自动生成的一大堆东西我
就感到有些头疼)。
 
前些日子一直没有时间试验,所以也没有发分。现在试验通过,谢谢大家!
 
后退
顶部