delphi实现com+远程(包括本地)调用
来源:互联网 发布:js点击显示隐藏div 编辑:程序博客网 时间:2024/05/16 09:01
曾经为com+分布式调用烦恼,几经周折获得解决,公布出来,互相学习借鉴
在server2003(做服务端部署机器)中测试通过,调用CreateRemoteObject(RemoteHost, AUser, APwd: WideString;ClassID: TGUID): IDispatch即可。
unit Core_ComCreate;
{
说明:远程com+对象创建,激活,验证单元
}
interface
uses SysUtils, ActiveX, ComObj, Windows, Classes;
type
PCoServerInfo = ^TCoServerInfo;
TCoServerInfo = record
dwReserved1: Longint;
pwszName: LPWSTR;
pAuthInfo: Pointer;
dwReserved2: Longint;
end;
PUnShort = ^Word;
PCoAuthIdentity = ^TCoAuthIdentity;
TCoAuthIdentity = record
User: PUnShort;
UserLength: ULONG;
Domain: PUnShort;
DomainLength: Ulong;
password: PUnShort;
PasswordLength: ulong;
Flags: ulong;
end;
TCoAuthInfo = record
dwAuthnSvc: DWORD;
dwAuthzSvc: DWORD;
pwszServerPrincName: WideString;
dwAuthnLevel: Dword;
dwImpersonationLevel: dword;
pAuthIdentityData: PCoAuthIdentity;
dwCapabilities: DWORD;
end;
TSocInfo = class(Tobject)
public
FCid: TCoAuthIdentity;
FCai: TCoAuthInfo;
ServerInfo: TCoServerInfo;
end;
TComManager = class(TComponent)
private
FCai: TCoAuthInfo;
FCid: TCoAuthIdentity;
FSvInfo: TCoServerInfo;
FUserName: WideString;
FPassword: WideString;
FRemoteHost: WideString;
//设置访问权限
protected
public
//创建对象
function CreateObject(ClassID: TGUID): IDispatch;
//接口类型转换
procedure Convert(Itf: IDispatch; IID: TGUID; out Obj);
constructor Create(AOwner: TComponent); override;
public
//远程主机所用登录名
property UserName: WideString read FUserName write FUserName;
//远程主机所用登录密码
property Password: WideString read FPassword write FPassword;
//远程主机,可填IP或机器名
property RemoteHost: WideString read FRemoteHost write FRemoteHost;
end;
function CreateRemoteObject(RemoteHost, AUser, APwd: WideString;
ClassID: TGUID): IDispatch;
procedure SetBlanket(Itf: IInterface; CAI: TCoAuthInfo); overload;
procedure SetBlanket(Itf: IInterface; RemoteHost, AUser, APwd: WideString); overload;
implementation
const
RPC_C_AUTHN_NONE: Integer = 0;
RPC_C_AUTHN_WINNT: Int64 = 10;
RPC_C_AUTHN_DEFAULT: Int64 = $FFFFFFFF;
//Authentication level constants
RPC_C_AUTHN_LEVEL_DEFAULT: Integer = 0;
RPC_C_AUTHN_LEVEL_NONE: Integer = 1;
RPC_C_AUTHN_LEVEL_CONNECT: Integer = 2;
RPC_C_AUTHN_LEVEL_CALL: Integer = 3;
RPC_C_AUTHN_LEVEL_PKT: Integer = 4;
RPC_C_AUTHN_LEVEL_PKT_INTEGRITY: Integer = 5;
RPC_C_AUTHN_LEVEL_PKT_PRIVACY: Integer = 6;
//Impersonation level constants
RPC_C_IMP_LEVEL_ANONYMOUS: Integer = 1;
RPC_C_IMP_LEVEL_IDENTIFY: Integer = 2;
RPC_C_IMP_LEVEL_IMPERSONATE: Integer = 3;
RPC_C_IMP_LEVEL_DELEGATE: Integer = 4;
//Constants for the capabilities
API_NULL: Integer = 0;
S_OK: Integer = 0;
EOAC_NONE: Integer = $0;
EOAC_MUTUAL_AUTH: Integer = $1;
EOAC_CLOAKING: Integer = $10;
EOAC_SECURE_REFS: Integer = $2;
EOAC_ACCESS_CONTROL: Integer = $4;
EOAC_APPID: Integer = $8;
{ TComManager }
procedure TComManager.Convert(Itf: IDispatch; IID: TGUID; out Obj);
begin
OleCheck(Itf.QueryInterface(IID, Obj));
SetBlanket(IUnknown(Obj), FCai);
end;
constructor TComManager.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FillMemory(@FCid, sizeof(FCid), 0);
FillMemory(@FSvInfo, sizeof(FSvInfo), 0);
FillMemory(@FCAI, sizeof(FCAI), 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 := nil;
dwCapabilities := $0800;
end;
FCai.pAuthIdentityData := @FCid;
end;
function TComManager.CreateObject(ClassID: TGUID): IDispatch;
begin
Result := CreateRemoteObject(FRemoteHost, FUserName, FPassword, ClassID);
end;
function GetACAI(RemoteHost, AUser, APwd: WideString): TCoAuthInfo;
var
CID: TCoAuthIdentity;
begin
with CID do begin
User := PUnShort(@AUser[1]);
UserLength := Length(AUser);
Domain := PUnShort(@RemoteHost[1]);
DomainLength := Length(RemoteHost);
Password := PUnShort(@APwd[1]);
PasswordLength := Length(APwd);
Flags := 2; //Unicode
end;
with Result do begin
dwAuthnSvc := 10; //RPC_C_AUTHN_WINNT
dwAuthzSvc := 0; // RPC_C_AUTHZ_NONE
dwAuthnLevel := 0; //RPC_C_AUTHN_LEVEL_DEFAULT
dwImpersonationLevel := 3;
pAuthIdentityData := @CID;
dwCapabilities := $0800;
end;
end;
procedure SetBlanket(Itf: IInterface; CAI: TCoAuthInfo); overload;
begin
with CAI do
CoSetProxyBlanket(Itf, dwAuthnSvc, dwAuthzSvc, pwidechar(pAuthIdentityData^.Domain),
dwAuthnLevel, dwImpersonationLevel, pAuthIdentityData, dwCapabilities);
end;
procedure SetBlanket(Itf: IInterface; RemoteHost, AUser, APwd: WideString); overload;
begin
SetBlanket(Itf, GetACAI(RemoteHost, AUser, APwd));
end;
function CreateRemoteObject(RemoteHost, AUser, APwd: WideString;ClassID: TGUID): IDispatch;
const
LocalFlags = CLSCTX_LOCAL_SERVER or CLSCTX_REMOTE_SERVER or CLSCTX_INPROC_SERVER;
RemoteFlags = CLSCTX_REMOTE_SERVER;
var
Size, Flags: DWORD;
IID_IUnknown: TGUID;
MQI: MULTI_QI;
LocalMachine: array[0..MAX_COMPUTERNAME_LENGTH] of char;
CID: TCoAuthIdentity;
CAI: TCoAuthInfo;
CSI: TCoServerInfo;
begin
FillMemory(@CID, SizeOf(CID), 0);
FillMemory(@CSI, SizeOf(CSI), 0);
FillMemory(@CAI, sizeof(CAI), 0);
with CAI do begin
dwAuthnSvc := 10; //RPC_C_AUTHN_WINNT
dwAuthzSvc := 0; // RPC_C_AUTHZ_NONE
dwAuthnLevel := 0; //RPC_C_AUTHN_LEVEL_DEFAULT
dwImpersonationLevel := 3;
pAuthIdentityData := @CID;
dwCapabilities := $0800;
end;
with CID do begin
User := PUnShort(@AUser[1]);
UserLength := Length(AUser);
Domain := PUnShort(@RemoteHost[1]);
DomainLength := Length(RemoteHost);
Password := PUnShort(@APwd[1]);
PasswordLength := Length(APwd);
Flags := 2; //Unicode
end;
CSI.pwszName := PWideChar(RemoteHost);
if AUser <> '' then
CSI.pAuthInfo := @CAI;
IID_IUnknown := IUnknown;
MQI.IID := @IID_IUnknown;
MQI.Itf := nil;
MQI.hr := 0;
if Length(RemoteHost)> 0 then
begin
Size := Sizeof(LocalMachine); // Win95 is hypersensitive to size
if GetComputerName(LocalMachine, Size)and(AnsiCompareText(LocalMachine, RemoteHost) = 0)
or(RemoteHost='127.0.0.1') then
begin
Result:=CreateComObject(ClassID) as IDispatch;
Flags := LocalFlags;
Exit;
end
else Flags := RemoteFlags;
end else Flags := LocalFlags;
OleCheck(CoCreateInstanceEx(ClassID, nil, Flags, @CSI, 1, @MQI));
OleCheck(MQI.hr);
SetBlanket(MQI.Itf, CAI);
OleCheck(MQI.Itf.QueryInterface(IDispatch, Result));
SetBlanket(Result, CAI);
end;
end.
在server2003(做服务端部署机器)中测试通过,调用CreateRemoteObject(RemoteHost, AUser, APwd: WideString;ClassID: TGUID): IDispatch即可。
unit Core_ComCreate;
{
说明:远程com+对象创建,激活,验证单元
}
interface
uses SysUtils, ActiveX, ComObj, Windows, Classes;
type
PCoServerInfo = ^TCoServerInfo;
TCoServerInfo = record
dwReserved1: Longint;
pwszName: LPWSTR;
pAuthInfo: Pointer;
dwReserved2: Longint;
end;
PUnShort = ^Word;
PCoAuthIdentity = ^TCoAuthIdentity;
TCoAuthIdentity = record
User: PUnShort;
UserLength: ULONG;
Domain: PUnShort;
DomainLength: Ulong;
password: PUnShort;
PasswordLength: ulong;
Flags: ulong;
end;
TCoAuthInfo = record
dwAuthnSvc: DWORD;
dwAuthzSvc: DWORD;
pwszServerPrincName: WideString;
dwAuthnLevel: Dword;
dwImpersonationLevel: dword;
pAuthIdentityData: PCoAuthIdentity;
dwCapabilities: DWORD;
end;
TSocInfo = class(Tobject)
public
FCid: TCoAuthIdentity;
FCai: TCoAuthInfo;
ServerInfo: TCoServerInfo;
end;
TComManager = class(TComponent)
private
FCai: TCoAuthInfo;
FCid: TCoAuthIdentity;
FSvInfo: TCoServerInfo;
FUserName: WideString;
FPassword: WideString;
FRemoteHost: WideString;
//设置访问权限
protected
public
//创建对象
function CreateObject(ClassID: TGUID): IDispatch;
//接口类型转换
procedure Convert(Itf: IDispatch; IID: TGUID; out Obj);
constructor Create(AOwner: TComponent); override;
public
//远程主机所用登录名
property UserName: WideString read FUserName write FUserName;
//远程主机所用登录密码
property Password: WideString read FPassword write FPassword;
//远程主机,可填IP或机器名
property RemoteHost: WideString read FRemoteHost write FRemoteHost;
end;
function CreateRemoteObject(RemoteHost, AUser, APwd: WideString;
ClassID: TGUID): IDispatch;
procedure SetBlanket(Itf: IInterface; CAI: TCoAuthInfo); overload;
procedure SetBlanket(Itf: IInterface; RemoteHost, AUser, APwd: WideString); overload;
implementation
const
RPC_C_AUTHN_NONE: Integer = 0;
RPC_C_AUTHN_WINNT: Int64 = 10;
RPC_C_AUTHN_DEFAULT: Int64 = $FFFFFFFF;
//Authentication level constants
RPC_C_AUTHN_LEVEL_DEFAULT: Integer = 0;
RPC_C_AUTHN_LEVEL_NONE: Integer = 1;
RPC_C_AUTHN_LEVEL_CONNECT: Integer = 2;
RPC_C_AUTHN_LEVEL_CALL: Integer = 3;
RPC_C_AUTHN_LEVEL_PKT: Integer = 4;
RPC_C_AUTHN_LEVEL_PKT_INTEGRITY: Integer = 5;
RPC_C_AUTHN_LEVEL_PKT_PRIVACY: Integer = 6;
//Impersonation level constants
RPC_C_IMP_LEVEL_ANONYMOUS: Integer = 1;
RPC_C_IMP_LEVEL_IDENTIFY: Integer = 2;
RPC_C_IMP_LEVEL_IMPERSONATE: Integer = 3;
RPC_C_IMP_LEVEL_DELEGATE: Integer = 4;
//Constants for the capabilities
API_NULL: Integer = 0;
S_OK: Integer = 0;
EOAC_NONE: Integer = $0;
EOAC_MUTUAL_AUTH: Integer = $1;
EOAC_CLOAKING: Integer = $10;
EOAC_SECURE_REFS: Integer = $2;
EOAC_ACCESS_CONTROL: Integer = $4;
EOAC_APPID: Integer = $8;
{ TComManager }
procedure TComManager.Convert(Itf: IDispatch; IID: TGUID; out Obj);
begin
OleCheck(Itf.QueryInterface(IID, Obj));
SetBlanket(IUnknown(Obj), FCai);
end;
constructor TComManager.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FillMemory(@FCid, sizeof(FCid), 0);
FillMemory(@FSvInfo, sizeof(FSvInfo), 0);
FillMemory(@FCAI, sizeof(FCAI), 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 := nil;
dwCapabilities := $0800;
end;
FCai.pAuthIdentityData := @FCid;
end;
function TComManager.CreateObject(ClassID: TGUID): IDispatch;
begin
Result := CreateRemoteObject(FRemoteHost, FUserName, FPassword, ClassID);
end;
function GetACAI(RemoteHost, AUser, APwd: WideString): TCoAuthInfo;
var
CID: TCoAuthIdentity;
begin
with CID do begin
User := PUnShort(@AUser[1]);
UserLength := Length(AUser);
Domain := PUnShort(@RemoteHost[1]);
DomainLength := Length(RemoteHost);
Password := PUnShort(@APwd[1]);
PasswordLength := Length(APwd);
Flags := 2; //Unicode
end;
with Result do begin
dwAuthnSvc := 10; //RPC_C_AUTHN_WINNT
dwAuthzSvc := 0; // RPC_C_AUTHZ_NONE
dwAuthnLevel := 0; //RPC_C_AUTHN_LEVEL_DEFAULT
dwImpersonationLevel := 3;
pAuthIdentityData := @CID;
dwCapabilities := $0800;
end;
end;
procedure SetBlanket(Itf: IInterface; CAI: TCoAuthInfo); overload;
begin
with CAI do
CoSetProxyBlanket(Itf, dwAuthnSvc, dwAuthzSvc, pwidechar(pAuthIdentityData^.Domain),
dwAuthnLevel, dwImpersonationLevel, pAuthIdentityData, dwCapabilities);
end;
procedure SetBlanket(Itf: IInterface; RemoteHost, AUser, APwd: WideString); overload;
begin
SetBlanket(Itf, GetACAI(RemoteHost, AUser, APwd));
end;
function CreateRemoteObject(RemoteHost, AUser, APwd: WideString;ClassID: TGUID): IDispatch;
const
LocalFlags = CLSCTX_LOCAL_SERVER or CLSCTX_REMOTE_SERVER or CLSCTX_INPROC_SERVER;
RemoteFlags = CLSCTX_REMOTE_SERVER;
var
Size, Flags: DWORD;
IID_IUnknown: TGUID;
MQI: MULTI_QI;
LocalMachine: array[0..MAX_COMPUTERNAME_LENGTH] of char;
CID: TCoAuthIdentity;
CAI: TCoAuthInfo;
CSI: TCoServerInfo;
begin
FillMemory(@CID, SizeOf(CID), 0);
FillMemory(@CSI, SizeOf(CSI), 0);
FillMemory(@CAI, sizeof(CAI), 0);
with CAI do begin
dwAuthnSvc := 10; //RPC_C_AUTHN_WINNT
dwAuthzSvc := 0; // RPC_C_AUTHZ_NONE
dwAuthnLevel := 0; //RPC_C_AUTHN_LEVEL_DEFAULT
dwImpersonationLevel := 3;
pAuthIdentityData := @CID;
dwCapabilities := $0800;
end;
with CID do begin
User := PUnShort(@AUser[1]);
UserLength := Length(AUser);
Domain := PUnShort(@RemoteHost[1]);
DomainLength := Length(RemoteHost);
Password := PUnShort(@APwd[1]);
PasswordLength := Length(APwd);
Flags := 2; //Unicode
end;
CSI.pwszName := PWideChar(RemoteHost);
if AUser <> '' then
CSI.pAuthInfo := @CAI;
IID_IUnknown := IUnknown;
MQI.IID := @IID_IUnknown;
MQI.Itf := nil;
MQI.hr := 0;
if Length(RemoteHost)> 0 then
begin
Size := Sizeof(LocalMachine); // Win95 is hypersensitive to size
if GetComputerName(LocalMachine, Size)and(AnsiCompareText(LocalMachine, RemoteHost) = 0)
or(RemoteHost='127.0.0.1') then
begin
Result:=CreateComObject(ClassID) as IDispatch;
Flags := LocalFlags;
Exit;
end
else Flags := RemoteFlags;
end else Flags := LocalFlags;
OleCheck(CoCreateInstanceEx(ClassID, nil, Flags, @CSI, 1, @MQI));
OleCheck(MQI.hr);
SetBlanket(MQI.Itf, CAI);
OleCheck(MQI.Itf.QueryInterface(IDispatch, Result));
SetBlanket(Result, CAI);
end;
end.
- delphi实现com+远程(包括本地)调用
- 本地调用, “本地调用”和远程调用!
- EJB3-远程、本地调用
- EJB的远程调用与本地调用http://fay19860916.blog.163.com/blog/static/1186491192009819220664/
- delphi 使用superobject实现jsonrpc的http远程调用
- 怎样用DELPHI调用COM组件
- 在Delphi.net中调用COM/COM+
- XmlSerializer 序列化(包括 结合反射,实现远程调用dll中一方法解决方案)
- EJB远程调用和本地调用
- 【EJB基础】远程调用和本地调用
- DELPHI实现远程屏幕抓取
- VS2005调用Delphi编写的COM程序
- DELPHI中COM组件编写及调用
- delphi调用vs2003写COM组件
- Delphi 调用COM(VC编写)
- Delphi(Lazarus)怎样不注册调用COM
- Qt调用Delphi编写的COM组件
- Spring实现远程调用
- JSP中page、request、session、 application的作用域
- eclipse 汉化 svn安装
- 各国iPhone5系列最新裸机价格
- androidmanifest.xml中声明相关权限
- .yml是什么文件
- delphi实现com+远程(包括本地)调用
- Caocao's Bridges hdu4738 (网络赛 杭州赛区) hdu 4738
- 雅虎三道面试题
- NoSQL新趋势:实时分析和数据库整合
- win32多线程程序设计笔记(第五章)
- vi与vim区别
- toj3072 Train Order
- 2013华为你知道多少?
- 区域赛 (求割桥)