2013-05-07 98 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

相关问题