📄 mconnect.pas
字号:
procedure TDispatchConnection.SetServerGUID(const Value: string);
var
ServerName: PWideChar;
begin
if not (csLoading in ComponentState) then
SetConnected(False);
if Value = '' then
FillChar(FServerGUID, SizeOf(FServerGUID), 0)
else
begin
FServerGUID := StringToGUID(Value);
if ProgIDFromCLSID(FServerGUID, ServerName) = 0 then
begin
FServerName := ServerName;
CoTaskMemFree(ServerName);
end;
end;
end;
procedure TDispatchConnection.SetServerName(const Value: string);
begin
if Value <> FServerName then
begin
if not (csLoading in ComponentState) then
begin
SetConnected(False);
if CLSIDFromProgID(PWideChar(WideString(Value)), FServerGUID) <> 0 then
FillChar(FServerGUID, SizeOf(FServerGUID), 0);
end;
FServerName := Value;
end;
end;
function TDispatchConnection.GetConnected: Boolean;
begin
Result := (not VarIsNull(AppServer) and (IDispatch(AppServer) <> nil));
end;
procedure TDispatchConnection.SetConnected(Value: Boolean);
var
Username, Password: string;
Login: Boolean;
begin
Login := LoginPrompt and Value and not Connected and not (csDesigning in ComponentState);
if Login then
begin
if Assigned(OnGetUsername) then OnGetUsername(Self, Username);
if Assigned(RemoteLoginDialogProc) then
if not RemoteLoginDialogProc(Username, Password) then
SysUtils.Abort;
end;
inherited SetConnected(Value);
if Login and Connected then
if Assigned(OnLogin)
then OnLogin(Self, Username, Password);
end;
procedure TDispatchConnection.DoDisconnect;
begin
if not VarIsNull(AppServer) then
SetAppServer(NULL);
end;
function TDispatchConnection.GetServer: IAppServer;
var
QIResult: HResult;
begin
Connected := True;
QIResult := IDispatch(AppServer).QueryInterface(IAppServer, Result);
if QIResult <> S_OK then
Result := TDispatchAppServer.Create(IAppServerDisp(IDispatch(AppServer)));
end;
function TDispatchConnection.GetServerCLSID: TGUID;
begin
if IsEqualGuid(FServerGuid, GUID_NULL) then
begin
if FServerName = '' then
raise Exception.CreateResFmt(@SServerNameBlank, [Name]);
Result := ProgIDToClassID(FServerName);
end else
Result := FServerGuid;
end;
{ TCOMConnection }
procedure TCOMConnection.SetConnected(Value: Boolean);
begin
if (not (csReading in ComponentState)) and
(Value and not Connected) and
IsEqualGuid(GetServerCLSID, GUID_NULL) then
raise Exception.CreateResFmt(@SServerNameBlank, [Name]);
inherited SetConnected(Value);
end;
procedure TCOMConnection.DoConnect;
begin
SetAppServer(CreateComObject(GetServerCLSID) as IDispatch);
end;
{ TDCOMConnection }
constructor TDCOMConnection.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
end;
procedure TDCOMConnection.SetComputerName(const Value: string);
begin
if Value <> FComputerName then
begin
SetConnected(False);
FComputerName := Value;
end;
end;
function TDCOMConnection.IsComputerNameStored: Boolean;
begin
Result := (FObjectBroker = nil) and (ComputerName <> '');
end;
procedure TDCOMConnection.DoConnect;
begin
if (FObjectBroker <> nil) then
begin
repeat
if FComputerName = '' then
FComputerName := FObjectBroker.GetComputerForGUID(GetServerCLSID);
try
SetAppServer(CreateRemoteComObject(ComputerName, GetServerCLSID) as IDispatch);
FObjectBroker.SetConnectStatus(ComputerName, True);
except
FObjectBroker.SetConnectStatus(ComputerName, False);
FComputerName := '';
end;
until Connected;
end else if (ComputerName <> '') then
SetAppServer(CreateRemoteComObject(ComputerName, GetServerCLSID) as IDispatch) else
inherited DoConnect;
end;
{ TOLEnterpriseConnection }
procedure TOLEnterpriseConnection.SetComputerName(const Value: string);
begin
if Value <> FComputerName then
begin
SetConnected(False);
FComputerName := Value;
end;
if Value <> '' then
FBrokerName := '';
end;
procedure TOLEnterpriseConnection.SetBrokerName(const Value: string);
begin
if Value <> FBrokerName then
begin
SetConnected(False);
FBrokerName := Value;
end;
if Value <> '' then
FComputerName := '';
end;
procedure TOLEnterpriseConnection.DoConnect;
var
Reg: TRegistry;
procedure WriteValue(ValueName, Value: String);
begin
if not Reg.ValueExists(ValueName) then
Reg.WriteString(ValueName, Value);
end;
const
AgentDLL = 'oleaan40.dll';
var
InprocKey, Inproc2Key, DllName, TempStr, TempStr2, ProgID: String;
begin
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.OpenKey('Software\OpenEnvironment\InstallRoot', False) then
begin
DllName := Reg.ReadString('');
Reg.CloseKey;
if Reg.OpenKey('Software\OpenEnvironment\OLEnterprise\AutomationAgent', False) then
begin
if not IsPathDelimiter(DllName, Length(DllName)) then DllName := DllName + '\';
DllName := DllName + Reg.ReadString('');
Reg.CloseKey;
end else
begin
if not IsPathDelimiter(DllName, Length(DllName)) then DllName := DllName + '\';
DllName := DllName + AgentDLL;
end;
end else
DllName := AgentDLL; { AgentDLL must be in the path }
Reg.RootKey := HKEY_CLASSES_ROOT;
InprocKey := Format('CLSID\%s\InprocServer32', [ServerGUID]);
Inproc2Key := Format('CLSID\%s\_InprocServer32', [ServerGUID]);
if (ComputerName = '') and (BrokerName = '') then {Run via COM}
begin
if Reg.OpenKey(InprocKey, False) then
begin
TempStr := Reg.ReadString('');
Reg.CloseKey;
if (AnsiPos(AgentDLL, AnsiLowerCase(TempStr)) > 0) or
(AnsiPos(AnsiLowerCase(ExtractFileName(DllName)), AnsiLowerCase(TempStr)) > 0) then
begin
if Reg.OpenKey(Inproc2Key, False) then
begin
TempStr2 := Reg.ReadString('');
Reg.WriteString('',TempStr);
Reg.CloseKey;
Reg.OpenKey(InprocKey, False);
Reg.WriteString('',TempStr2);
Reg.CloseKey;
end else
Reg.DeleteKey(InprocKey);
end;
end;
end else
begin
if Reg.OpenKey(InprocKey, False) then
begin
TempStr := Reg.ReadString('');
Reg.CloseKey;
if (AnsiPos(AgentDLL, AnsiLowerCase(TempStr)) = 0) and
(AnsiPos(AnsiLowerCase(ExtractFileName(DllName)), AnsiLowerCase(TempStr)) = 0) then
Reg.MoveKey(InprocKey, Inproc2Key, True);
end;
Reg.OpenKey(InprocKey, True);
Reg.WriteString('',DllName);
Reg.WriteString('ThreadingModel','Apartment');
Reg.CloseKey;
Reg.RootKey := HKEY_LOCAL_MACHINE;
Reg.OpenKey('Software\OpenEnvironment\OLEnterprise\Dap\DCEApp',True);
if BrokerName <> '' then
begin
Reg.WriteString('Broker',Format('ncacn_ip_tcp:%s',[BrokerName]));
WriteValue('LogLevel', '0');
WriteValue('LogFile','');
WriteValue('UseNaming','1');
WriteValue('UseSecurity','1');
end else
Reg.WriteString('Broker','none');
Reg.CloseKey;
Reg.RootKey := HKEY_CLASSES_ROOT;
if Reg.OpenKey(Format('CLSID\%s\ProgID',[ServerGUID]), False) then
begin
ProgID := Reg.ReadString('');
Reg.CloseKey;
end else
begin
ProgID := ServerName;
if ProgID = '' then
ProgID := ServerGUID else
begin
Reg.OpenKey(Format('%s\CLSID',[ProgID]), True);
Reg.WriteString('',ServerGUID);
Reg.CloseKey;
end;
Reg.OpenKey(Format('CLSID\%s\ProgID',[ServerGUID]), True);
Reg.WriteString('',ProgID);
Reg.CloseKey;
end;
Reg.OpenKey(Format('CLSID\%s\Dap\DCEClient\%s',[ServerGUID, ProgID]), True);
WriteValue('ComTimeout','default');
Reg.WriteString('DisableNaming',IntToStr(Ord(BrokerName = '')));
WriteValue('ExtendedImport','1');
WriteValue('ImportName','%cell%/applications/services/%service%');
WriteValue('ProtectionLevel','');
WriteValue('Protseq','ncacn_ip_tcp');
if BrokerName <> '' then
Reg.DeleteValue('ServerBinding') else
Reg.WriteString('ServerBinding',Format('ncacn_ip_tcp:%s',[ComputerName]));
WriteValue('ServerPrincipal','');
WriteValue('SetAuthentication','1');
WriteValue('TimerInterval','10');
WriteValue('VerifyAvailability','0');
Reg.CloseKey;
Reg.CreateKey(Format('CLSID\%s\NotInsertable',[ServerGUID]));
Reg.CreateKey(Format('CLSID\%s\Programmable',[ServerGUID]));
end;
finally
Reg.Free;
end;
inherited DoConnect;
end;
{ TSharedConnection }
constructor TSharedConnection.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
RCS;
end;
procedure TSharedConnection.SetParentConnection(const Value: TDispatchConnection);
begin
if Value <> FParentConnection then
begin
if Assigned(FParentConnection) then
FParentConnection.UnregisterClient(Self);
if Assigned(Value) then
begin
Value.RegisterClient(Self, ConnectEvent);
Value.FreeNotification(Self);
end;
FParentConnection := Value;
end;
end;
procedure TSharedConnection.ConnectEvent(Sender: TObject;
Connecting: Boolean);
begin
if not Connecting or (ChildName <> '') then
Connected := Connecting;
end;
function TSharedConnection.GetConnected: Boolean;
begin
Result := (not VarIsNull(AppServer) and (IDispatch(AppServer) <> nil));
end;
procedure TSharedConnection.DoConnect;
begin
if not Assigned(FParentConnection) then
raise Exception.Create(SNoParentConnection);
if FChildName = '' then
raise Exception.Create(SBlankChildName);
FParentConnection.Connected := True;
SetAppServer(GetDispatchPropValue(IDispatch(FParentConnection.AppServer), FChildName));
end;
procedure TSharedConnection.DoDisconnect;
begin
SetAppServer(NULL);
end;
procedure TSharedConnection.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (AComponent = ParentConnection) then
ParentConnection:= nil;
end;
destructor TSharedConnection.Destroy;
begin
ParentConnection := nil;
inherited;
end;
function TSharedConnection.GetServer: IAppServer;
var
QIResult: HResult;
begin
Connected := True;
QIResult := IDispatch(AppServer).QueryInterface(IAppServer, Result);
if QIResult <> S_OK then
Result := TDispatchAppServer.Create(IAppServerDisp(IDispatch(AppServer)));
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -