-
Здравствуйте! Проблема на ровном месте. В Delphi 7 создаю COM объект через New / ActiveX - Com object. Появляется окно, заполняю имя объекта, получаю окно Project.tlb. Ввожу методы интерфейса, компилирую, запускаю. После запуска приложения GUID класса сервера прописывается в реестре HKEY_CLASSES_ROOT\CLSID Все прекрасно.
Делаю такие-же действия на D2009, после запуска приложения GUID не прописывается в реестре. К тому-же, в форме редактирования полей интерфейса имеется кнопочка [Register type library]. В D7 она погашена, а в D2009 активна и регистрирует интерфейс. Хотелось бы сделать, как в D7, чтобы приложение при запуске автоматически регистрировало интерфейс. Что нужно сделать для этого в D2009?
-
CoRegisterClassObject() при запуске
-
собственно это и происходит в конечном итоге при запуске com-сервера procedure TComServer.Initialize;
begin
try
UpdateRegistry(FStartMode <> smUnregServer);
except
on E: EOleRegistrationError do
if FStartMode = smRegServer then raise;
end;
if FStartMode in [smRegServer, smUnregServer] then Halt;
ComClassManager.ForEachFactory(Self, FactoryRegisterClassObject);
end;
-
Спасибо, попробую
-
Не знаю, как в D2009, а в D2010 этот код выглядит так: procedure TComServer.Initialize;
begin
try
if((FStartMode = smRegServer) or (FStartMode = smUnregServer)) then
UpdateRegistry(FStartMode <> smUnregServer);
except
on E: EOleRegistrationError do
if (E.ErrorCode <> TYPE_E_REGISTRYACCESS) or (FStartMode = smRegServer) then
raise;
end;
if FStartMode in [smRegServer, smUnregServer] then
Halt;
ComClassManager.ForEachFactory(Self, FactoryRegisterClassObject);
end; Т.е. при обычном запуске ничего само не регистрируется, для регистрации надо запускать с ключом /regserver. И это правильно, наконец-то COM-серверы на Delphi стали соответствовать стандартам COM в этом смысле. > Хотелось бы сделать, как в D7, чтобы приложение при запуске > автоматически регистрировало интерфейс.
А вот этого не надо. Я понимаю, что вы уже привыкли к неправильному стилю работы, но пора от него отвыкать. Тем более что в Windows 7 и Vista у пользователя всё равно не должно хватать прав для таких действий вне инсталлятора.
-
Я делаю так Пробуеш подключиться к серверу если не удалось то регистрируем его с ключом /regserver и снова подключается. Для регистрации использую registration('c:\com_scv.exe);. Может по другому можно но на win8 другое не всегда работает.
function registration(nameProcces:string):boolean; function Vista_Win7_i_td:boolean; var temp1, temp2, temp3: integer; OsVer: OSVERSIONINFO; begin result:=false; OsVer.dwOSVersionInfoSize := SizeOf( OSVERSIONINFO ); GetVersionEx( OsVer ); temp1 := OsVer.dwMajorVersion; temp2 := OsVer.dwMinorVersion; temp3 := OsVer.dwPlatformId; result:=temp1>5; end;
// завершить процес который запущен из определеной директории function KillTask_Dir(ExeFileName:string; DIR_Ychitivaem:boolean):integer; const PROCESS_TERMINATE=$0001; var ContinueLoop: BOOL; FSnapshotHandle: THandle; FProcessEntry32: TProcessEntry32; pm :MODULEENTRY32; FProcessEntry32_szExeFile,ExeFileName_:string; bm , delete_proc :Boolean; hm :LongInt; begin try result := 0; FSnapshotHandle := CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); FProcessEntry32.dwSize := Sizeof(FProcessEntry32); ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32); // перебераем все рпоцесы while integer(ContinueLoop) <> 0 do begin // отризаем директории и делаем все большими буквами для сравнения FProcessEntry32_szExeFile:=UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) ; ExeFileName_:=UpperCase(ExtractFileName(ExeFileName)); delete_proc:=false; // названия поцеса совподает if FProcessEntry32_szExeFile=ExeFileName_ then begin if DIR_Ychitivaem then begin ExeFileName_:=UpperCase(ExeFileName); // удалить процес если запущен из указаной директоии hm:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,FProcessEntry32.th32ProcessID); pm.dwSize:=SizeOf(MODULEENTRY32); bm:=Module32First(hm,pm); // сканируем какие файлы использует процес while bm do begin FProcessEntry32_szExeFile:=UpperCase(String(pm.szExePath)); // если наш файл из указаной директории то завершаем процес if FProcessEntry32_szExeFile=ExeFileName_ then begin delete_proc:=true; Break; end; pm.dwSize:=SizeOf(MODULEENTRY32); bm:=Module32Next(hm,pm); end; CloseHandle(hm); //FProcessEntry32_szExeFile:=UpperCase(FProcessEntry32.szExeFile); ExeFileName_:=UpperCase(ExeFileName) end else begin // названия совпала значит удаляем процус delete_proc:=true; end; // завершаем поцес if delete_proc then Result := Integer(TerminateProcess(OpenProcess(PROCESS_TERMINATE, BOOL(0),FProcessEntry32.th32ProcessID), 0)); end; ContinueLoop := Process32Next(FSnapshotHandle,FProcessEntry32); end; CloseHandle(FSnapshotHandle); except CloseHandle(FSnapshotHandle); CloseHandle(hm); end; end; var name_drv:string; begin result:=false; if nameProcces='' then exit; if FileExists(nameProcces) then begin try // процес запущен тогда завершаем его KillTask_Dir(nameProcces,true); sleep(300); // запускаем его и заверщаем чтоб зарегистрировался сервер if Vista_Win7_i_td then ShellExecute(Application.Handle,'runas',PChar(nameProcces),' /regserver',PChar(ExtractFileDir(nameProcces)),SW_SHOWNORMAL) else ShellExecute(Application.Handle,'open',PChar(nameProcces),' /regserver',PChar(ExtractFileDir(nameProcces)),SW_SHOWNORMAL); sleep(500); KillTask_Dir(nameProcces,true); sleep(300); result:=true; except end; end; end;
-
мадуля какиета из этих uses SysUtils, Windows, Messages, Classes, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, ComCtrls, TlHelp32, ShellAPI, ActiveX,
|