2013-05-07 7 views
5

Sto costruendo un programma di installazione con Inno Setup e vorrei che i file estratti fossero eseguiti come amministratore. C'è un modo per forzare i file estratti (cioè il file batch) da eseguire come amministratore? In tal caso, quali elementi di codice devo includere per eseguire questo.Inno Setup Esegui il file batch estratto come amministratore

Il registro di installazione mostra qualcosa di simile al seguente:

2013-05-07 17:34:25.303 -- Run entry -- 
2013-05-07 17:34:25.303 Run as: Current user 
2013-05-07 17:34:25.303 Type: Exec 
2013-05-07 17:34:25.303 Filename: C:\Temp\is-U4VID.tmp\Filename.bat 
2013-05-07 17:34:25.412 Process exit code: 0 

I file che sto avendo problemi con l'esecuzione come utente admin sono incluse nella sezione [Run].

+1

La cosa migliore da fare è riscrivere qualsiasi cosa si stia facendo nel file batch in codice Inno. Il codice può fare tutto ciò che un file batch può fare e altro. – Miral

+0

@Miral - Non sono sicuro di come eliminare i file e avviare e interrompere i servizi con Inno Setup. Di conseguenza, ho dovuto usare file batch. – John

risposta

8

Se si utilizza [Run] sezione quindi assicurarsi di utilizzare runascurrentuser bandiera (Se viene specificato questo flag, il processo generato erediterà Setup/del Disinstallare le credenziali utente (tipicamente, pieni privilegi amministrativi))

gli altri ci sono tre modi per eseguire le applicazioni programatically (modalità consigliata):

function Exec(const Filename, Params, WorkingDir: String; const ShowCmd: Integer; const Wait: TExecWait; var ResultCode: Integer): Boolean; 

function ShellExec(const Verb, Filename, Params, WorkingDir: String; const ShowCmd: Integer; const Wait: TExecWait; var ErrorCode: Integer): Boolean; 

function ShellExecAsOriginalUser(const Verb, Filename, Params, WorkingDir: String; const ShowCmd: Integer; const Wait: TExecWait; var ErrorCode: Integer): Boolean; 

si dovrebbe usare Exec() o ShellExec() perché aprono il file specificato o esegue un'altra azione specificata dal Verbo, utilizzando le stesse credenziali come Setup/uNINS alto.

Ma nessuno dei modi indicati funzionerà se il programma di installazione non è in esecuzione in modalità elevata. in modo da assicurarsi la finestra UAC apparirà prima installazione si avvia:

Nella sezione [Setup] direttiva use valori PrivilegesRequired

validi:

none, poweruser, admin, o lowest

Usa di amministrazione per garantire credenziali appropriate.

+1

Nota che per impostazione predefinita 'PrivilegesRequired = admin' e i file eseguiti vengono eseguiti come utente amministratore (tranne per' postinstall [Esegui] '). Quindi devi fare in modo che non funzioni. – Miral

1

Ma cosa succede se è necessario eseguire un file batch nel momento postUninstall? In questo caso per ripristinare un backup dei file di database che sono stati modificati dall'applicazione?

Ci sono volute alcune ore per provare tutto fino a quando ho trovato questo hack.

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); 
var 
    ResultCode: Integer; 
    outfile: String; 
    runBatHeader: String; 
    runBatBody: String; 

begin 

    if CurUninstallStep = usPostUninstall then 
    begin 
    (* 
     This is a messy hack, but the only way I could find to run a bat file 
     during the post unistall section. In this case all files copied are 
     already removed, and it was not permitted to extract temp files in 
     the uninstall phase. Code here writes 'outfile' to a system folder then runs it. 
    *) 
    if DirExists('C:\ProgramData\MySQL\MySQL Server 5.7_bak') then begin 
     if MsgBox('Uninstall located a possible backup of your original MySQL tables. ' + 
     'Uninstall can attempt to copy it to the previous location. There is no ' + 
     'guarantee that it will succeed. Do you want to try restoring this folder?', mbConfirmation, MB_YESNO or MB_DEFBUTTON2) = IDYES then 
     begin 

     outFile := 'C:\ProgramData\MySQL\restore.bat'; 
     runBatHeader := '@echo off' + #13#10 + #13#10; 
     runBatBody := 'ECHO Attempt to stop MySQL57' + #13#10 + 
       'NET STOP MySQL57' + #13#10 + 
       'ECHO Removing application databases' + #13#10 + 
       'RMDIR /S /Q "C:\ProgramData\MySQL\MySQL Server 5.7\"' + #13#10 + 
       'ECHO Copying backup to original location' + #13#10 + 
       'XCOPY "C:\ProgramData\MySQL\MySQL Server 5.7_bak" "C:\ProgramData\MySQL\MySQL Server 5.7\" /C /E /H /I /K /O /Q /R /Y' + #13#10 + #13#10 + 
       'ECHO Try to start MySQL57' + #13#10 + 
       'NET START MySQL57';'; 
     SaveStringToFile(outFile, runBatHeader, False); 
     SaveStringToFile(outFile, runBatBody, True); 

     MsgBox('ShelExec : C:\ProgramData\MySQL\restore.bat', mbConfirmation, MB_OK); 
     if not ShellExec('', 'C:\ProgramData\MySQL\restore.bat', '', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then 
     begin 
      // handle failure if necessary 
      MsgBox('Apparently, the administrative privilege was not operational. Exiting without restoring the backup. ('+ IntToStr(ResultCode) +')', mbConfirmation, MB_OK); 
     end; 
     DeleteFile(outfile); 

     end; 
    end; 
    end; 
end; 

Tuttavia non è stata una mia idea. Ho trovato un example here.