Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Обращение к удаленном OLE-объекту


Страницы:   1 2

GrBob ©   (2006-06-27 11:07:00) 

Здравствуйте.
На удаленном компьютере есть OLE-объект, у которого известно только название. (ну и соответственно легко получается CLSID, в реестре на данном компьютере информация об объекте есть). Вопрос: можно ли как-нибудь к нему обраться? CreateOLEObject работает только на текущей машине, а CreateRemoteComObject возвращает интерфейс, название которого я не знаю. (Как его получить?)
Заранее спасибо за ответы.


GrBob   (2006-06-30 09:24:00) [21]

Огромное спасибо, тут я более-менее разобрался, осталось узнать как вызывать методы, а не только менять свойства.
PS. Методы возвращают другие COM-объекты.
Жду с большим нетерпением подсказки, наконец я хоть немного продвинулся.


AbrosimovA   (2006-06-29 15:53:00) [22]

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ComObj, AxCtrls, ExtCtrls, ComCtrls;

type
 TForm1 = class(TForm)
   btnReadProp: TButton;
   ListBox1: TListBox;
   ServNameEdit: TEdit;
   Label1: TLabel;
   Label4: TLabel;
   btnExec: TButton;
   Timer1: TTimer;
   ValuePropEdit: TEdit;
   btnReadInterf: TButton;
   btnConnect: TButton;
   BtnRemConnect: TButton;
   StatusBar1: TStatusBar;
   procedure btnReadPropClick(Sender: TObject);
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
   procedure btnExecClick(Sender: TObject);
   procedure ListBox1Click(Sender: TObject);
   procedure Timer1Timer(Sender: TObject);
   procedure FormCreate(Sender: TObject);
   procedure btnReadInterfClick(Sender: TObject);
   procedure BtnRemConnectClick(Sender: TObject);
 private
  ServerName: string[255];
  procedure SetInvoke(const ID: integer; const Command: OleVariant);
 public
 end;

var
 Form1: TForm1;
 Srv: IDispatch;
 ID,DID: integer;
 iIndex: integer;

implementation

{$R *.dfm}
uses ActiveX;

//Перечисление свойств
procedure EnumProperties(Dispatch: IDispatch; Entries: TStrings);
var iDispID,i: integer;
   NameRefs: array[0..0] of PWideChar;
   HR: HResult;
begin
Entries.Clear;
Entries.NameValueSeparator:='-';
EnumDispatchProperties(Dispatch, GUID_NULL, VT_EMPTY, Entries);
for i:=0 to Entries.Count-1 do begin
  NameRefs[0]:=PWideChar(WideString(Entries[i]));
  HR:=Dispatch.GetIDsOfNames(GUID_NULL, @NameRefs, 1,
    LOCALE_SYSTEM_DEFAULT, @iDispID);
  if HR=S_OK then
   Entries.Strings[i]:= Format('%d-%s',[iDispID,Entries[i]]);
end
end;

//Перечисление интерфейсов
procedure EnumInterface(Dispatch: IDispatch; Entries: TStrings; Functions: Boolean);
var
 TypeInfo: ITypeInfo;
 TypeAttr: PTypeAttr;
 FuncDesc: PFuncDesc;
 Vardesc: PVarDesc;
 hr: HResult;
 iMethode: Integer;
 nNames  : integer;
 sNameLst: TBSTRList;
begin
 Dispatch.GetTypeInfoCount(iMethode);
 if iMethode > 0 then
 begin
   hr := Dispatch.GetTypeInfo(0,GetUserDefaultLCID,TypeInfo);
   OleCheck(hr);
   hr := TypeInfo.GetTypeAttr(TypeAttr);
   OleCheck(hr);
   if Functions then
   begin
     for iMethode := 0 to TypeAttr.cFuncs-1 do
     begin
       hr := TypeInfo.GetFuncDesc(iMethode, FuncDesc);
       OleCheck(hr);
       hr := TypeInfo.GetNames(FuncDesc.memid, @sNameLst,1,nNames);
       OleCheck(hr);
       Entries.Add(Format('%d-%s', [FuncDesc.memid, sNameLst[0]]));
     end;
   end
   else
   begin
     for iMethode := 0 to TypeAttr.cVars-1 do
     begin
       hr := TypeInfo.GetVarDesc(iMethode, Vardesc);
       OleCheck(hr);
       hr := TypeInfo.GetNames(Vardesc.memid, @sNameLst,1,nNames);
       OleCheck(hr);
       Entries.Add(Format('%d-%s', [Vardesc.memid, sNameLst[0]]));
     end;
   end;
 end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Srv:=nil;
end;

function GetDispIDFromName(const Disp: IDispatch; const PropertyName: WideString;
           var iDispID: Integer): OleVariant;
var
PName: PWideChar;
ExcepInfo: TExcepInfo;
DispParams: TDispParams;
Status: HResult;
begin
if Disp = nil then Exit;
PName := PWideChar(PropertyName);
if PropertyName = '' then
  Result := DISPID_UNKNOWN
else
  Disp.GetIDsOfNames(GUID_NULL, @PName, 1, GetThreadLocale, @iDispID);
FillChar(DispParams, SizeOf(DispParams), 0);

Status := Disp.Invoke(iDispID, GUID_NULL, 0, DISPATCH_PROPERTYGET, DispParams,
  @Result, @ExcepInfo, nil);
if Status <> S_OK then
  DispatchInvokeError(Status, ExcepInfo);
end;

procedure TForm1.SetInvoke(const ID: integer; const Command: OleVariant);
var
 vSet        : OLEVariant;
 aDispParams : TDispParams;
 aDispId     : TDispId;
 aEI         : TExcepInfo;
 iError      : UINT;
 ptinfo: ITypeInfo;
begin
 vSet := Command;
 FillChar(aDispParams, SizeOf (aDispParams), 0);
 with aDispParams do begin
   rgvarg := @vSet;
   cArgs := 1;
   cNamedArgs := 1;
 end;
 aDispId := DISPID_PROPERTYPUT;
 aDispParams.rgdispidNamedArgs := @aDispId;
 OleCheck (Srv.Invoke (ID, GUID_NULL, LOCALE_SYSTEM_DEFAULT,
           DISPATCH_PROPERTYPUT, aDispParams, NIL, @aEI, @iError));
end;

procedure TForm1.ListBox1Click(Sender: TObject);
begin
iIndex:=Listbox1.ItemIndex;
if (iIndex<>-1)and(Tag=1) then
 ValuePropEdit.Text:=GetDispIDFromName(Srv, Listbox1.Items.ValueFromIndex[iIndex],DID)
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
btnExec.Enabled:=(iIndex<>-1)and(Tag=1);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
iIndex:=-1;
end;

//интерфейсы
procedure TForm1.btnReadInterfClick(Sender: TObject);
begin
Tag:=2;
ListBox1.Clear;
ValuePropEdit.Clear;
if Assigned(Srv) then EnumInterface(Srv,ListBox1.Items,True)
end;

//свойства
procedure TForm1.btnReadPropClick(Sender: TObject);
begin
 Tag:=1;
 ListBox1.Clear;
 ValuePropEdit.Clear;
 if Assigned(Srv) then begin
  EnumProperties(Srv,ListBox1.Items);
 end;
end;

//Изменение свойств
procedure TForm1.btnExecClick(Sender: TObject);
begin
if (ValuePropEdit.Text = '')or(Tag=2) then Exit;
try
 SetInvoke(DID, ValuePropEdit.Text);
except
end
end;

//Запуск  
procedure TForm1.BtnRemConnectClick(Sender: TObject);
var CLSID: TGUID;
begin
 //для Word.Application
 CLSID:=StringToGUID('{000209FF-0000-0000-C000-000000000046}');
 try
  Srv:=CreateRemoteComObject('Server5',CLSID) as IDispatch;
 except
  Exit;
 end;
 btnReadProp.Enabled:=True;
 btnReadInterf.Enabled:=True;
end;

end.


GrBob   (2006-06-28 16:47:00) [23]

Дело в том, что мне его нужно запустить на удаленной машине. CreateOLEObject делает это только на локальной, все замечательно работает. А вот CreateRemoteCOMObject возвращает интерфейс, который нужно чему-то присвоить. Просто IInterface'у его не присвоишь, вернее потом методы не повызываешь.
Согласен, возможно интерфейс знать и не нужно совсем, но тогда как запустить OLE сервер на удаленном компьютере и еще им управлять при этом? :)


tesseract   (2006-06-28 13:56:00) [24]

Если есть GUID - на кой его по имени знать?


GrBob   (2006-06-27 15:15:00) [25]


> enuminterfaces??


??


> описание интерфейса есть?


Я знаю его методы и свойства. Мне нужно узнать как он называется. (I...)


tesseract   (2006-06-27 14:57:00) [26]


> а CreateRemoteComObject возвращает интерфейс, название которого
> я не знаю. (Как его получить?)


enuminterfaces??

описание интерфейса есть?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо