Inno Setup以管理员身份运行提取的批处理文件

时间:2013-05-07 22:42:51

标签: batch-file installer 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]部分中。

2 个答案:

答案 0 :(得分:11)

如果您使用的是[Run]部分,请确保使用runascurrentuser标志(如果指定了此标志,则生成的进程将继承Setup / Uninstall的用户凭据(通常为完全管理权限))< / p>

另外,有三种方法可以以编程方式运行应用程序(推荐方式):

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(),因为他们使用与设置/卸载相同的凭据打开指定的文件或执行Verb指定的其他操作。

但是,如果您的安装程序未在提升模式下运行,则所提及的方法都不起作用。 因此,请确保在安装程序启动之前显示UAC窗口:

[Setup]部分中使用指令PrivilegesRequired

有效值:

nonepoweruseradminlowest

使用admin确保适当的凭据。

答案 1 :(得分: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