Browse Source

[Setup] section directive CloseApplications can now be set to force. If it is, Setup will force close when closing applications. Use with care since this may cause the user to lose unsaved work.

Added new command line parameters supported by Setup: /FORCECLOSEAPPLICATIONS and /NOFORCECLOSEAPPLICATIONS. These can be used to override the CloseApplications directive.

Closes  #145.
Martijn Laan 10 years ago
parent
commit
d00b4d5767
6 changed files with 49 additions and 13 deletions
  1. 7 1
      Projects/Compile.pas
  2. 10 4
      Projects/Install.pas
  3. 10 2
      Projects/Main.pas
  4. 2 1
      Projects/Struct.pas
  5. 18 5
      ishelp/isetup.xml
  6. 2 0
      whatsnew.htm

+ 7 - 1
Projects/Compile.pas

@@ -3691,7 +3691,13 @@ begin
         SetSetupHeaderOption(shChangesEnvironment);
       end;
     ssCloseApplications: begin
-        SetSetupHeaderOption(shCloseApplications);
+        if CompareText(Value, 'force') = 0 then begin
+          Include(SetupHeader.Options, shCloseApplications);
+          Include(SetupHeader.Options, shForceCloseApplications);
+        end else begin
+          SetSetupHeaderOption(shCloseApplications);
+          Exclude(SetupHeader.Options, shForceCloseApplications);
+        end;
       end;
     ssCloseApplicationsFilter: begin
         if Value = '' then

+ 10 - 4
Projects/Install.pas

@@ -2765,21 +2765,27 @@ var
   procedure ShutdownApplications;
   const
     ERROR_FAIL_SHUTDOWN = 351;
+    ForcedStrings: array [Boolean] of String = ('', ' (forced)');
+    ForcedActionFlag: array [Boolean] of ULONG = (0, RmForceShutdown);
   var
+    Forced: Boolean;
     Error: DWORD;
   begin
-    Log('Shutting down applications using our files.');
+    Forced := InitForceCloseApplications or
+              ((shForceCloseApplications in SetupHeader.Options) and not InitNoForceCloseApplications);
+
+    Log('Shutting down applications using our files.' + ForcedStrings[Forced]);
 
     RmDoRestart := True;
 
-    Error := RmShutdown(RmSessionHandle, 0, nil);
+    Error := RmShutdown(RmSessionHandle, ForcedActionFlag[Forced], nil);
     while Error = ERROR_FAIL_SHUTDOWN do begin
       Log('Some applications could not be shut down.');
       if AbortRetryIgnoreMsgBox(SetupMessages[msgErrorCloseApplications],
          SetupMessages[msgEntryAbortRetryIgnore]) then
         Break;
-      Log('Retrying to shut down applications using our files.');
-      Error := RmShutdown(RmSessionHandle, 0, nil);
+      Log('Retrying to shut down applications using our files.' + ForcedStrings[Forced]);
+      Error := RmShutdown(RmSessionHandle, ForcedActionFlag[Forced], nil);
     end;
 
     { Close session on all errors except for ERROR_FAIL_SHUTDOWN, should still call RmRestart in that case. }

+ 10 - 2
Projects/Main.pas

@@ -102,8 +102,8 @@ var
   InitDir, InitProgramGroup: String;
   InitLoadInf, InitSaveInf: String;
   InitNoIcons, InitSilent, InitVerySilent, InitNoRestart, InitCloseApplications,
-    InitNoCloseApplications, InitRestartApplications, InitNoRestartApplications,
-    InitNoCancel: Boolean;
+    InitNoCloseApplications, InitForceCloseApplications, InitNoForceCloseApplications,
+    InitRestartApplications, InitNoRestartApplications, InitNoCancel: Boolean;
   InitSetupType: String;
   InitComponents, InitTasks: TStringList;
   InitComponentsSpecified: Boolean;
@@ -643,6 +643,8 @@ begin
   InitNoRestart := GetIniBool(Section, 'NoRestart', InitNoRestart, FileName);
   InitCloseApplications := GetIniBool(Section, 'CloseApplications', InitCloseApplications, FileName);
   InitNoCloseApplications := GetIniBool(Section, 'NoCloseApplications', InitNoCloseApplications, FileName);
+  InitForceCloseApplications := GetIniBool(Section, 'ForceCloseApplications', InitForceCloseApplications, FileName);
+  InitNoForceCloseApplications := GetIniBool(Section, 'NoForceCloseApplications', InitNoForceCloseApplications, FileName);
   InitRestartApplications := GetIniBool(Section, 'RestartApplications', InitRestartApplications, FileName);
   InitNoRestartApplications := GetIniBool(Section, 'NoRestartApplications', InitNoRestartApplications, FileName);
   InitNoCancel := GetIniBool(Section, 'NoCancel', InitNoCancel, FileName);
@@ -2802,6 +2804,12 @@ begin
     if CompareText(ParamName, '/NoCloseApplications') = 0 then
       InitNoCloseApplications := True
     else
+    if CompareText(ParamName, '/ForceCloseApplications') = 0 then
+      InitForceCloseApplications := True
+    else
+    if CompareText(ParamName, '/NoForceCloseApplications') = 0 then
+      InitNoForceCloseApplications := True
+    else
     if CompareText(ParamName, '/RestartApplications') = 0 then
       InitRestartApplications := True
     else

+ 2 - 1
Projects/Struct.pas

@@ -65,7 +65,8 @@ type
     shAppendDefaultGroupName, shEncryptionUsed, shChangesEnvironment,
     {$IFNDEF UNICODE}shShowUndisplayableLanguages, {$ENDIF}shSetupLogging,
     shSignedUninstaller, shUsePreviousLanguage, shDisableWelcomePage,
-    shCloseApplications, shRestartApplications, shAllowNetworkDrive);
+    shCloseApplications, shRestartApplications, shAllowNetworkDrive,
+    shForceCloseApplications);
   TSetupLanguageDetectionMethod = (ldUILanguage, ldLocale, ldNone);
   TSetupCompressMethod = (cmStored, cmZip, cmBzip, cmLZMA, cmLZMA2);
   TSetupSalt = array[0..7] of Byte;

+ 18 - 5
ishelp/isetup.xml

@@ -2750,7 +2750,7 @@ Shown by default, but can be disabled via <link topic="setup_disablereadypage">D
 <b>Preparing to Install</b><br/>
 Normally, Setup will never stop or pause on this page. The only time it will is if Setup determines it can't continue or if it detects applications using files that need to be updated.<br/><br/>
 The former can happen if the <tt>PrepareToInstall</tt> event function returned an error or if one or more files specified in the [Files] and [InstallDelete] sections were queued (by some other installation) to be replaced or deleted on the next restart. In this case, it tells the user they need to restart their computer and then run Setup again. Note that this check is performed on silent installations too, but any messages are displayed in a message box instead of inside a wizard page.<br/><br/>
-The latter can happen if <link topic="setup_closeapplications">CloseApplications</link> is set to <tt>yes</tt>.
+The latter can happen if <link topic="setup_closeapplications">CloseApplications</link> is set to <tt>yes</tt> or <tt>force</tt>.
 </li>
 
 <li>
@@ -3021,6 +3021,8 @@ Filename: "{win}\MYPROG.INI"; Section: "InstallSettings"; Key: "InstallPath"; St
 <keyword value="/NORESTART" anchor="NORESTART" />
 <keyword value="/CLOSEAPPLICATIONS" anchor="CLOSEAPPLICATIONS" />
 <keyword value="/NOCLOSEAPPLICATIONS" anchor="NOCLOSEAPPLICATIONS" />
+<keyword value="/FORCECLOSEAPPLICATIONS" anchor="FORCECLOSEAPPLICATIONS" />
+<keyword value="/NOFORCECLOSEAPPLICATIONS" anchor="NOFORCECLOSEAPPLICATIONS" />
 <keyword value="/RESTARTAPPLICATIONS" anchor="RESTARTAPPLICATIONS" />
 <keyword value="/NORESTARTAPPLICATIONS" anchor="NORESTARTAPPLICATIONS" />
 <keyword value="/LOADINF=" anchor="LOADINF" />
@@ -3122,9 +3124,19 @@ Filename: "{win}\MYPROG.INI"; Section: "InstallSettings"; Key: "InstallPath"; St
 <p>Prevents Setup from closing applications using files that need to be updated by Setup. If /CLOSEAPPLICATIONS was also used, this command line parameter is ignored.</p>
 </dd>
 
+<dt><b><a name="FORCECLOSEAPPLICATIONS">/FORCECLOSEAPPLICATIONS</a></b></dt>
+<dd>
+<p>Instructs Setup to force close when closing applications.</p>
+</dd>
+
+<dt><b><a name="NOFORCECLOSEAPPLICATIONS">/NOFORCECLOSEAPPLICATIONS</a></b></dt>
+<dd>
+<p>Prevents Setup from force closing when closing applications. If /FORCECLOSEAPPLICATIONS was also used, this command line parameter is ignored.</p>
+</dd>
+
 <dt><b><a name="RESTARTAPPLICATIONS">/RESTARTAPPLICATIONS</a></b></dt>
 <dd>
-<p>Instructs Setup to restart applications if possible. If Setup didn't close these applications (for example because /NOCLOSEAPPLICATIONS was used), this command line parameter is ignored.</p>
+<p>Instructs Setup to restart applications if possible. Only has an effect when combined with '/CLOSEAPPLICATIONS'.</p>
 </dd>
 
 <dt><b><a name="NORESTARTAPPLICATIONS">/NORESTARTAPPLICATIONS</a></b></dt>
@@ -4992,11 +5004,12 @@ SignTool=byparam format c:
 </setuptopic>
 
 <setuptopic directive="CloseApplications">
-<setupvalid><link topic="yesnonotes"><tt>yes</tt> or <tt>no</tt></link></setupvalid>
+<setupvalid><tt>force</tt>, <link topic="yesnonotes"><tt>yes</tt>, or <tt>no</tt></link></setupvalid>
 <setupdefault><tt>yes</tt></setupdefault>
 <body>
-<p>If set to <tt>yes</tt> and Setup is not running silently, Setup will pause on the <i>Preparing to Install</i> wizard page if it detects applications using files that need to be updated by the [Files] or [InstallDelete] section, showing the applications and asking the user if Setup should automatically close the applications and restart them after the installation has completed.</p>
-<p>If set to <tt>yes</tt> and Setup is running silently, Setup will always close and restart such applications, unless told not to via the command line.</p>
+<p>If set to <tt>yes</tt> or <tt>force</tt> and Setup is not running silently, Setup will pause on the <i>Preparing to Install</i> wizard page if it detects applications using files that need to be updated by the [Files] or [InstallDelete] section, showing the applications and asking the user if Setup should automatically close the applications and restart them after the installation has completed.</p>
+<p>If set to <tt>yes</tt> or <tt>force</tt> and Setup is running silently, Setup will always close and restart such applications, unless told not to via the command line.</p>
+<p>If set to <tt>force</tt> Setup will force close when closing applications, unless told not to via the command line. Use with care since this may cause the user to lose unsaved work.</p>
 <p>Note: Setup uses the Windows <extlink href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa373524.aspx">Restart Manager</extlink> API to close and restart applications, which is available only on Windows Vista and newer.</p>
 <p><b>See also:</b><br/>
 <link topic="setup_closeapplicationsfilter">CloseApplicationsFilter</link><br/>

+ 2 - 0
whatsnew.htm

@@ -30,6 +30,8 @@ For conditions of distribution and use, see <a href="http://www.jrsoftware.org/f
 <ul>
 <li><b>Change in default behavior:</b> As recommended by Microsoft's desktop applications guideline, <tt>DisableWelcomePage</tt> now defaults to <tt>yes</tt>. Additionally <tt>DisableDirPage</tt> and <tt>DisableProgramGroupPage</tt> now default to <tt>auto</tt>. The defaults in all previous versions were <tt>no</tt>.</li>
 <li>The Compiler IDE's New Script Wizard now offers to create a shortcut to the main executable in the common Start Menu Programs folder instead of creating a new Start Menu folder especially for the application. This option is enabled by default and is recommended by Microsoft unless you install a suite of applications rather than a single application.</li>
+<li>[Setup] section directive <tt>CloseApplications</tt> can now be set to <tt>force</tt>. If it is, Setup will force close when closing applications. Use with care since this may cause the user to lose unsaved work.</li>
+<li>Added new command line parameters supported by Setup: /FORCECLOSEAPPLICATIONS and /NOFORCECLOSEAPPLICATIONS. These can be used to override the <tt>CloseApplications</tt> directive.</li>
 <li>The <tt>Attribs</tt> parameter of a [Files] or [Dir] entry may now also include <tt>notcontentindexed</tt> to specify that the file or directory is not to be indexed by the content indexing service.</li>
 <li>Pascal Scripting change: function <tt>RegQueryBinaryValue</tt> can now be used to query any type of registry value and not just <tt>REG_BINARY</tt>-type values.</li>
 <li>The Setup and Uninstall programs are now marked as DEP and ASLR compatible.</li>