2013-05-07 10 views
5

Buduję instalator za pomocą programu Inno Setup i chcę, aby wyodrębnione pliki były uruchamiane jako administrator. Czy istnieje sposób, aby wymusić wyodrębnione pliki (np. Plik wsadowy), aby działały jako administrator? Jeśli tak, jakie elementy kodu muszę dołączyć, aby to wykonać.Inno Setup Uruchom wyodrębniony plik wsadowy jako administrator

Dziennik konfiguracja pokazuje coś jak następuje:

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 

Pliki że mam problemy z systemem jako administratora są zawarte w sekcji [Run].

+1

Najlepszym rozwiązaniem jest przepisanie wszystkiego, co robisz w pliku wsadowym, na kod Inno. Kod może zrobić wszystko, co może zrobić plik wsadowy, i wiele więcej. – Miral

+0

@Miral - Nie jestem pewien, w jaki sposób usuwać pliki oraz uruchamiać i zatrzymywać usługi za pomocą Inno Setup. W rezultacie musiałem użyć plików wsadowych. – John

Odpowiedz

8

Jeśli używasz [Run] sekcję następnie upewnij się, że korzystać z runascurrentuser flag (Jeśli ta flaga jest określona, ​​zrodził proces będzie dziedziczyć konfiguracji/poświadczenia użytkownika Uninstall jest (zazwyczaj pełne uprawnienia administracyjne))

Else istnieją trzy sposoby jak uruchomić aplikacje programowo (zalecany sposób):

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; 

należy użyć Exec() lub ShellExec() ponieważ otworzyć określony plik lub wykonuje inną akcję określoną przez czasownik, przy użyciu tych samych poświadczeń jako Setup/Unins wysoki.

Ale żaden z wymienionych sposobów nie zadziała, jeśli instalator nie pracuje w trybie podwyższonym. więc upewnij się okno Kontrola konta użytkownika pojawi się przed instalatora zaczyna:

W sekcji [Setup] dyrektywy posługują PrivilegesRequired

Prawidłowe wartości:

none, poweruser, admin lub lowest

Zastosowanie administratora, aby zapewnić odpowiednie dane uwierzytelniające.

+1

Zwróć uwagę, że domyślnie 'PrivilegesRequired = admin' i pliki uruchamiane są jako użytkownik admin (z wyjątkiem' postinstall [Run] '). Musisz więc zejść mi z drogi, żeby nie zadziałał. – Miral

1

Ale co, jeśli musisz uruchomić plik wsadowy w momencie postUninstall? W takim przypadku, aby przywrócić kopię zapasową plików bazy danych, które zostały zmienione przez aplikację?

Trwa kilka godzin próbując wszystkiego, dopóki nie znalazłem tego hacka.

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; 

To nie był mój pomysł. Znalazłem example here.