2013-05-07 104 views
5

我正在用Inno Setup構建安裝程序,並希望提取的文件以管理員身份運行。有沒有辦法強制提取文件(即批處理文件)以管理員身份運行?如果是這樣,我需要包含哪些代碼元素才能執行此操作。Inno Setup以管理員身份運行提取的批處理文件

安裝日誌顯示類似如下:

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 

,我有與運行作爲管理員用戶問題的文件包含在[Run]部分。

+1

最好的辦法是將批處理文件中的任何內容重寫到Inno代碼中。代碼可以完成批處理文件可以執行的任何操作,等等。 – Miral 2013-05-08 20:47:25

+0

@Miral - 我不確定如何使用Inno Setup刪除文件並啓動和停止服務。結果,我不得不使用批處理文件。 – John 2013-05-08 21:16:35

回答

8

如果您正在使用[Run]部分然後確保你使用runascurrentuser標誌(如果指定了該標誌,衍生進程將繼承安裝/卸載的用戶憑據(通常,完整的管理權限))

否則有三辦法如何編程運行應用程序(推薦方式):

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; 

,因爲他們打開指定的文件或者您應該使用Exec()ShellExec()執行由動詞指定的其他動作,使用相同的憑據設置/ Unins高。

但是,如果您的安裝程序沒有以提升模式運行,上述方式都不會起作用。 所以一定要確保UAC窗口安裝程序之前,將出現啓動:

在第[Setup]使用指令PrivilegesRequired

有效值:

nonepoweruseradmin,或lowest

使用admin保證適當的憑據。

+1

請注意,默認情況下'PrivilegesRequired = admin'和執行的文件以admin用戶身份運行(除'postinstall [Run]'之外)。所以你必須走出自己的路,因爲它不工作。 – Miral 2013-05-08 20:46:48

1

但是如果你需要在postUninstall時刻運行批處理文件呢?在這種情況下,恢復由應用程序更改的數據庫文件的備份?

我花了幾個小時嘗試一切,直到我發現這個黑客。

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; 

雖然這不是我的想法。我發現一個example here

相關問題