1

我有一个带有 Pascal 代码的安装脚本,以确定要安装的应用程序当前是否正在运行:

; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

[Setup]
AppName=MyApp
AppVerName=MyApp v1.0
DiskSpanning=no
AppPublisher=me
AppPublisherURL=http://www.example.com
AppSupportURL=http://www.example.com
AppUpdatesURL=http://www.example.com
DefaultDirName={pf}\MyApp
UsePreviousAppDir=yes
DefaultGroupName=MyApp
OutputBaseFilename=Setup
OutputDir=.\MyAppSetup
MinVersion=5.0

[Tasks]
Name: desktopicon; Description: Create a &desktop icon; GroupDescription: Additional icons:; MinVersion: 4,4

[Files]
Source: .\Release\MyApp.exe; DestDir: {app}; Flags: ignoreversion

[Icons]
Name: {group}\EasyCash&Tax; Filename: {app}\MyApp.exe
Name: {userdesktop}\EasyCash&Tax; Filename: {app}\MyApp.exe; MinVersion: 4,4; Tasks: desktopicon

[Run]
Filename: {app}\MyApp.exe; Description: Launch MyApp; Flags: nowait postinstall skipifsilent

[Code]

function CheckProcessRunning( aProcName,
                              aProcDesc: string ): boolean;
var
  ShellResult: boolean;
  ResultCode: integer;
  cmd: string;
  sl: TStringList;
  f: string;
  d: string;
begin
  cmd := 'for /f "delims=," %%i ' + 
         'in (''tasklist /FI "IMAGENAME eq ' + aProcName + '" /FO CSV'') ' + 
         'do if "%%~i"=="' + aProcName + '" exit 1'; 
  f := 'CheckProc.cmd';
  d := AddBackSlash( ExpandConstant( '{tmp}' ));
  sl := TStringList.Create;
  sl.Add( cmd );
  sl.Add( 'exit /0' );
  sl.SaveToFile( d + f );
  sl.Free;
  Result := true;
  while ( Result ) do
  begin
    ResultCode := 1;
    ShellResult := Exec( f,
                         '',
                         d, 
                         SW_HIDE, 
                         ewWaitUntilTerminated, 
                         ResultCode );
    Result := ResultCode > 0;
    if Result and 
       ( MsgBox( aProcDesc + ' is active and must be closed to proceed', 
                 mbConfirmation, 
                 MB_OKCANCEL ) <> IDOK ) then
      Break;
  end;
  DeleteFile( d + f );
end;

// Perform some initializations.  Return False to abort setup
function InitializeSetup: Boolean;
begin
  // Do not use any user defined vars in here such as {app}
  Result := not ( CheckProcessRunning( 'MyApp.exe',      'MyApp' ));
end;


function InitializeUninstall: Boolean;
begin
  Result := not ( CheckProcessRunning( 'MyApp.exe',      'MyApp' ));
end;

这适用于 99% 的情况,但用户时不时会报告误报并且无法继续安装。

用户报告在命令行tasklist /FI "IMAGENAME eq MyApp.exe" /FO CSV(由 Pascal 脚本使用)中没有返回任何内容。

脚本中是否存在可能给出误报的错误,或者是否有更好的方法来确定应用程序是否正在运行tasklist

4

1 回答 1

2

脚本中是否有可能给出误报的错误?

没有错误。

您是否知道,这tasklist可能不可用?想想“XP Home”(是的,它正在淡出),但仍在使用中,您的解决方案将无法在那里工作,因为tasklist根本不可用。

还是有比“任务列表”更好的方法来确定应用程序是否正在运行?

是的,还有其他一些可能更可靠的方法可以做到这一点。例如,包含psvince在安装程序中并将其用于进程检测是很常见的。相当不错也是WMI基于解决方案。

以下是使用 InnoSetup 进行“进程检测”的一些方法:

于 2015-06-15T18:14:32.163 回答