Answer the question
In order to leave comments, you need to log in
How to implement the use of one dll library by two programs at the same time?
Hello!
I am writing a program to update another program.
How it all works:
1) In the main program, there is a "Check for Update" button, when clicked, a request is made to the server (site), where the text file is located (the current version is written in it) and the archive with the update. (The file is a temporary test solution).
2) The program compares the current version (a constant in the code or an entry in the registry) with the server's response, and if the versions differ, it launches another program - the updater. (!)
3) The updater downloads the archive from the server
4) If the archive was downloaded successfully, we complete the main program and unpack the archive
5) If the archive was unpacked successfully, run the main program and delete the archive, after which the updater closes (!)
Programs work with the server via https, so the main exe and the updater exe contain libeay32.dll and ssleay32.dll (all in one folder)
So one program does not work while another is running - and it seems to me that these libraries are already involved in the first one.
Separately, everything seems to work, but there is a gag at the moments when one program should start another.
The idea came to me to put an updater with copies of these libraries in a separate update folder, but it seems to me that this is not a solution that is not entirely correct.
What am I doing wrong and how should I do it right?
Thank you.
UPD: I'll attach the code
There is nothing on the form except a single progress bar to display the download progress (from non-visual components: IdSSLIOHandlerSocketOpenSSL1, IdHTTP1, IdAntiFreeze1)
//Сама программа (Project > View Source)
uses
Vcl.Forms,
Vcl.Dialogs,
Windows,
Registry,
System.Classes,
System.SysUtils,
Unit1 in 'Unit1.pas' {Form1},
IdMultipartFormData,
IdBaseComponent,
IdComponent,
IdTCPConnection,
IdTCPClient,
IdHTTP,
IdHashMessageDigest,
IdSSLOpenSSL,
IdSSL,
IdIOHandler,
IdIOHandlerSocket,
IdIOHandlerStack;
{$R *.res}
Var HM :THandle;
function Check: boolean;
begin
HM:=OpenMutex(MUTEX_ALL_ACCESS, false, 'Proj');
Result:=(HM<>0);
if HM=0 then HM:=CreateMutex(nil, false, 'Proj');
end;
function checkUpdate: boolean;
var
Stream: TIdMultipartFormDataStream;
HTTPClient: TidHTTP;
response: WideString;
cur_ver: string;
Reg: TRegistry;
begin
Reg:=TRegistry.Create;
Reg.RootKey := HKEY_CURRENT_USER;
Reg.OpenKey('\SOFTWARE\'+app_name_tech, true);
result:=false;
if reg.ValueExists('AppVer') then cur_ver := Reg.ReadString('AppVer');
HTTPClient := TidHTTP.Create;
try
Stream := TIdMultipartFormDataStream.Create;
Stream.AddFormField('query_type', 'update');
Stream.AddFormField('v', cur_ver);
response:= HTTPClient.Post(app_serv+'/updater.php ', Stream); // Отправим запрос
result:=StrToBool(response);
HTTPClient.Disconnect;
//FreeAndNil(response);
finally
Stream.Free;
HTTPClient.Free;
end;
end;
begin
If Check then //проверка не запущена ли уже программа
exit;
Application.Initialize;
Application.MainFormOnTaskbar := True;
if CheckUpdate() then
begin
Application.CreateForm(TForm1, Form1);
Application.Run;
end
else
begin
ShowMessage('Обновление не требуется');
end;
end.
// далее Unit1
function UnZipFile(sourceFile, destPath: String): Boolean;
var
ZipFile: TZipFile;
begin
ZipFile := TZipFile.Create;
try
if ZipFile.IsValid(sourceFile) then begin
ZipFile.ExtractZipFile(sourceFile, destPath);
ZipFile.Close;
result:= true;
end;
finally
ZipFile.Free;
end;
end;
procedure save_in_dir(dir, url: string; MyHTTP: TIdHTTP);
var
MyStream: TMemoryStream;
fname: string;
begin
MyStream := TMemoryStream.Create;
fname := url;
// Получаем имя файла из url. Имя файла - текст за последним включением "/"
while Pos('/', fname) <> 0 do
begin
Delete(fname, 1, Pos('/', fname));
end;
// Сам процесс сохранения файла
MyHTTP.Get(url, MyStream);
MyHTTP.Disconnect;
MyStream.SaveToFile(dir + '\' + fname);
MyStream.Free;
end;
procedure TForm1.FormActivate(Sender: TObject);
// тут странный момент - форма "не успевает" отобразиться (я пробовал и OnCreate и OnShow), то есть за время работы программы появляются только всплывающие окна описанные ниже.
var
Reg: TRegistry;
Stream: TMemoryStream;
begin
root_dir := ExtractFilePath(ParamStr(0));
save_in_dir(root_dir, app_serv + '/update/update.zip', IdHTTP1);
// когда скачалось
if progressbar1.position=progressbar1.max then //(как по другому определить завершение загрузки не знаю)
begin
Application.Messagebox('Загрузка обновления прошла успешно.', 'Загрузка обновления..', mb_iconinformation or mb_ok);
if FileExists(root_dir+'update.zip') then //есть ли файл
begin
try
//вырубаем основную программу
KillProcess(root_dir+'main.exe');//KillTask('main.exe'); //этот момент проверить не могу, так как не получается запустить "одновременно 2 программы". При запуске в режиме отладки тут ошибок не возникало)
except
on e:Exception do ShowMessage('Не удалось вырубить основную программу');//ShowMessage(E.ClassName+' ошибка с сообщением : '+E.Message);
end;
//распаковать архив
if UnZipFile(root_dir+'update.zip', root_dir) then
begin
//удалить архив
DeleteFile(root_dir+'update.zip');
//прописать новую версию
Reg:=TRegistry.Create;
Reg.RootKey := HKEY_CURRENT_USER;
Reg.OpenKey('\SOFTWARE\'+app_name_tech, true);
Reg.WriteString('app_ver', app_ver);
ShowMessage('Обновление установлено!');
//запустить основное приложение
try
ShellExecute(0, PChar('open'), PChar(root_dir+'main.exe'), nil, nil, SW_SHOWDEFAULT);
except
on e:Exception do ShowMessage(E.ClassName+' ошибка с сообщением : '+E.Message);
end;
//закрыть обновлятор
//Application.Destroy;
halt;
end
else
begin
ShowMessage('Не удалось обновиться! Не удалось распаковать архив');
end;
end
else//если файла нет
begin
ShowMessage('Не удалось обновиться! Архив не найден');
end;
end;
end;
procedure TForm1.IdHTTP1Work(ASender: TObject; AWorkMode: TWorkMode;
AWorkCount: Int64);
begin
ProgressBar1.Position:=AWorkCount;
end;
procedure TForm1.IdHTTP1WorkBegin(ASender: TObject; AWorkMode: TWorkMode;
AWorkCountMax: Int64);
begin
ProgressBar1.Max:=AWorkCountMax;
end;
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question