delphi - unelevated program starts an elevated updater, updater should wait for finishing of program -


i have 2 apps, program.exe , updater.exe, both written in delphi5. program runs without admin-rights (and without manifest), updater has manifest "requireadministrator" because must able write @ program-folder update program.exe.

the problem launch updater , let him wait until program closed. i've found different ways @ web, none works (in cases 1st app starts 2nd app , wait ending of 2nd app, in case 2nd app should wait ending of 1nd app).

updater should wait, thats easy
updater.exe

{$r manifest.res} label.caption:='wait program.exe closing'; repeat     sleep(1000); until file not open programhandle := read handle file waitforsingleobject(programhandle,infinite); label.caption:='program.exe closed'; updates 

way 1
starting updater createprocess:
program.exe

fillchar(siinfo, sizeof(siinfo), 0); siinfo.cb := sizeof(siinfo);  saprocessattributes.nlength := sizeof(saprocessattributes); saprocessattributes.lpsecuritydescriptor := nil; saprocessattributes.binherithandle := true;  sathreadattributes.nlength := sizeof(sathreadattributes); sathreadattributes.lpsecuritydescriptor := nil; sathreadattributes.binherithandle := true;  if createprocess(nil,            pchar('updater.exe'),            @saprocessattributes,            @sathreadattributes,            true, normal_priority_class, nil,            pchar(extractfilepath(application.exename)),            siinfo, piinfo) begin duplicatehandle(getcurrentprocess, getcurrentprocess,                 piinfo.hprocess, @myhandle,                 process_query_information, true,                 duplicate_same_access) write myhandle in file end; close program 

doesn't anything, works when updater has no manifest requireadministrator into. if run program explizit admin-rights, works too.

way 2 starting updater shellexecuteex:
program.exe

  fillchar(info, sizeof(info), chr(0));   info.cbsize := sizeof(info);   info.fmask := see_mask_nocloseprocess;   info.lpverb := pchar('runas');   info.lpfile := pchar('update.exe');   info.lpdirectory := nil;   info.nshow := sw_restore;   shellexecuteex(@info);    myhandle:=openprocess(process_all_access, false, getcurrentprocessid())));   write myhandle in file   close program 

doesnt' work, myhandle has different value each time run procedure (without restarting program), updater can't work it.

so have no idea how start updater.exe , write handle of program.exe in file.

im not familiar these parts of programing ... has idea proplem?

your code not working because handle table per process, means second process have same handle pointing kernel object. below, there 1 of many possible solutions:

when creating process 2, pass pid of process 1 parameter:

procedure createupdater; var   info: tshellexecuteinfo; begin     fillchar(info, sizeof(tshellexecuteinfo), 0);   info.cbsize := sizeof(tshellexecuteinfo);   info.fmask  := see_mask_nocloseprocess;   info.lpverb := pchar('runas');   info.lpfile := pchar('update.exe');   info.lpparameters := pchar(inttostr(getcurrentprocessid));   info.lpdirectory := nil;   info.nshow := sw_restore;   shellexecuteex(@info);   //note: missing error checking! end; 

inside updater, wait process1 terminate:

procedure waitforandclose; var   pid: string;   ahandle: cardinal;   ret: longbool;   exitnumber: dword; begin   pid:= paramstr(1);   if pid <> ''   begin     ahandle:= openprocess(process_query_information, false, strtoint(pid));       //note: missing error checking!     try       repeat         ret:= getexitcodeprocess(ahandle, exitnumber);         //note: missing error checking!         sleep(1000); //define time poolling       until (exitnumber <> still_active);           closehandle(ahandle);     end;     //terminate process;     application.terminate;           end; end; 

you can use waitforsingleobject avoid polling:

waitforsingleobject(ahandle, infinite); //note: missing error checking! 

but need synchronize access open process:

ahandle:= openprocess(synchronize, false, strtoint(pid)); //note: missing error checking! 

note: there no error checking here. should read docs , check errors.

note 2: i attention fact leaking handle. when use see_mask_nocloseprocess caller responsible close handle of calee. in case think don't need mask @ all. remove it.


Comments

Popular posts from this blog

javascript - gulp-nodemon - nodejs restart after file change - Error: listen EADDRINUSE events.js:85 -

Fatal Python error: Py_Initialize: unable to load the file system codec. ImportError: No module named 'encodings' -

javascript - oscilloscope of speaker input stops rendering after a few seconds -