Some software install can spawn a child process that never exits. We want to be able to ignore child processes that don't exit after installation is finished

This commit is contained in:
Duc
2025-05-07 09:38:11 -07:00
parent 738834be94
commit c9315968da
14 changed files with 1451 additions and 1561 deletions

View File

@@ -1,23 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.IO;
using System.Security.AccessControl;
using System.Management;
using System.Security.Principal;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Drawing; using System.Drawing;
using System.IO;
using CommonLib.Windows.Forms; using System.Windows.Forms;
using CommonLib.IO; using CommonLib.IO;
using CommonLib.Misc; using CommonLib.Misc;
using CommonLib.Windows.Forms;
namespace All_Purpose_Auto_Setup namespace All_Purpose_Auto_Setup
{ {

View File

@@ -1,24 +1,14 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics; using System.Diagnostics;
using System.Text.RegularExpressions;
using System.IO;
using System.Security.AccessControl;
using System.Management;
using System.Security.Principal;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Drawing; using System.Drawing;
using System.IO;
using CommonLib.Windows.Forms; using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using CommonLib.IO; using CommonLib.IO;
using CommonLib.Misc; using CommonLib.Misc;
using CommonLib.Windows.Forms;
namespace All_Purpose_Auto_Setup namespace All_Purpose_Auto_Setup
{ {

View File

@@ -146,12 +146,22 @@ step = INSTALL_SOFTWARE_PACKAGES,Install_Software
; ;
; ****************************************************************************************************************************** ; ******************************************************************************************************************************
[Install_Software] [Install_Software]
app5_name = Visual Studio 2022 ;app5_name = Visual Studio 2022
app5_setup_argument = -p --norestart --noweb --add Microsoft.VisualStudio.Workload.ManagedDesktop;includeRecommended Microsoft.VisualStudio.Workload.NativeDesktop;includeRecommended Microsoft.VisualStudio.Component.VC.ATLMFC Microsoft.VisualStudio.Component.VC.CLI.Support Microsoft.VisualStudio.Workload.VisualStudioExtension;includeRecommended ;app5_setup_argument = -p --norestart --noweb --add Microsoft.VisualStudio.Workload.ManagedDesktop;includeRecommended Microsoft.VisualStudio.Workload.NativeDesktop;includeRecommended Microsoft.VisualStudio.Component.VC.ATLMFC Microsoft.VisualStudio.Component.VC.CLI.Support Microsoft.VisualStudio.Workload.VisualStudioExtension;includeRecommended
app5_reg_path = VisualStudio.DTE.17.0 ;app5_reg_path = VisualStudio.DTE.17.0
app5_reg_type = classes_root ;app5_reg_type = classes_root
app5_setup_file = D:\Windows_Stuff\Visual_Studio_2022.17.9.5\vs_setup.exe ;app5_setup_file = D:\Windows_Stuff\Visual_Studio_2022.17.9.5\vs_setup.exe
app5_install_process_name = setup ;app5_install_process_name = setup
app6_name = TestStand 2019
app6_reg_display_name = NI TestStand (32-bit)
app6_reg_type = local_machine
app62_reg_value = 19
app62_reg_name = DisplayVersion
app62_reg_compare = gte
app6_setup_file = C:\Users\Duc\Desktop\TestStand_2019\Install.exe
app6_spawned_processes_to_ignore = nierserver
app6_reboot_computer_at_completion = true
; ****************************************************************************************************************************** ; ******************************************************************************************************************************
; THIS SECTION IS OPTIONAL ; THIS SECTION IS OPTIONAL

View File

@@ -1,25 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.IO;
using System.Security.AccessControl;
using System.Management;
using System.Security.Principal;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Drawing; using System.Drawing;
using System.Linq;
using CommonLib.Windows.Forms; using System.Management;
using CommonLib.Windows.Misc; using System.Text.RegularExpressions;
using CommonLib.IO; using System.Threading;
using System.Windows.Forms;
using CommonLib.Misc; using CommonLib.Misc;
using CommonLib.Windows.Misc;
namespace All_Purpose_Auto_Setup namespace All_Purpose_Auto_Setup
{ {

View File

@@ -1,24 +1,16 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics; using System.Diagnostics;
using System.Text.RegularExpressions;
using System.IO;
using System.Security.AccessControl;
using System.Management;
using System.Security.Principal;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Drawing; using System.Drawing;
using System.IO;
using CommonLib.Windows.Forms; using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using CommonLib.IO; using CommonLib.IO;
using CommonLib.Misc; using CommonLib.Misc;
using CommonLib.Windows.Forms;
namespace All_Purpose_Auto_Setup namespace All_Purpose_Auto_Setup
{ {

View File

@@ -1,24 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.IO;
using System.Security.AccessControl;
using System.Management;
using System.Security.Principal;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Drawing; using System.Drawing;
using System.Text.RegularExpressions;
using CommonLib.Windows.Forms; using System.Windows.Forms;
using CommonLib.IO; using CommonLib.IO;
using CommonLib.Misc; using CommonLib.Misc;
using CommonLib.Windows.Misc; using CommonLib.Windows.Forms;
namespace All_Purpose_Auto_Setup namespace All_Purpose_Auto_Setup
{ {

View File

@@ -1,26 +1,19 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics; using System.Diagnostics;
using System.Text.RegularExpressions;
using System.IO;
using System.Security.AccessControl;
using System.Management;
using System.Security.Principal;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Drawing; using System.Drawing;
using System.IO;
using CommonLib.Windows.Forms; using System.Linq;
using System.Management;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using CommonLib.IO; using CommonLib.IO;
using CommonLib.Misc; using CommonLib.Misc;
using CommonLib.Windows.Forms;
using CommonLib.Windows.Misc; using CommonLib.Windows.Misc;
using CommonLib.Runtime.InteropServices; using Microsoft.Win32;
namespace All_Purpose_Auto_Setup namespace All_Purpose_Auto_Setup
{ {
@@ -60,7 +53,7 @@ namespace All_Purpose_Auto_Setup
bool setupSuccessful = true; bool setupSuccessful = true;
string msg, indentation = String.Empty; string msg, indentation = String.Empty;
string setupFile, exeFile, registryPath, registryDisplayName, registryType, registryName, registryValue, registryCompareOperator, installArgs, string setupFile, exeFile, registryPath, registryDisplayName, registryType, registryName, registryValue, registryCompareOperator, installArgs,
exitCodesToIgnore, installProcessName; exitCodesToIgnore, spawnedProcessesToIgnore;
bool promptBeforeInstallation = false, rebootComputerAtCompletionRequested = false, rebootComputerImmediatelyRequested = false; bool promptBeforeInstallation = false, rebootComputerAtCompletionRequested = false, rebootComputerImmediatelyRequested = false;
CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor(""); CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
@@ -132,7 +125,7 @@ namespace All_Purpose_Auto_Setup
registryCompareOperator = ""; registryCompareOperator = "";
installArgs = ""; installArgs = "";
exitCodesToIgnore = ""; exitCodesToIgnore = "";
installProcessName = ""; spawnedProcessesToIgnore = "";
rebootComputerAtCompletionRequested = false; rebootComputerAtCompletionRequested = false;
rebootComputerImmediatelyRequested = false; rebootComputerImmediatelyRequested = false;
@@ -143,7 +136,7 @@ namespace All_Purpose_Auto_Setup
break; break;
getInfoUsingExeVerification(processedConfigInfo.Value, ref setupFile, ref exeFile, ref promptBeforeInstallation, ref rebootComputerAtCompletionRequested, ref rebootComputerImmediatelyRequested); getInfoUsingExeVerification(processedConfigInfo.Value, ref setupFile, ref exeFile, ref promptBeforeInstallation, ref rebootComputerAtCompletionRequested, ref rebootComputerImmediatelyRequested);
getInfoUsingRegistryVerification(processedConfigInfo.Value, ref registryPath, ref registryDisplayName, ref registryType, ref registryName, ref registryValue, ref registryCompareOperator, ref installArgs, ref exitCodesToIgnore, ref installProcessName); getInfoUsingRegistryVerification(processedConfigInfo.Value, ref registryPath, ref registryDisplayName, ref registryType, ref registryName, ref registryValue, ref registryCompareOperator, ref installArgs, ref exitCodesToIgnore, ref spawnedProcessesToIgnore);
if (exeFile.Length > 0) if (exeFile.Length > 0)
{ {
@@ -153,7 +146,7 @@ namespace All_Purpose_Auto_Setup
{ {
setupSuccessful = checkSoftwareRegistry(processedConfigInfo.Key.iniValue, setupFile, promptBeforeInstallation, installArgs, registryPath, setupSuccessful = checkSoftwareRegistry(processedConfigInfo.Key.iniValue, setupFile, promptBeforeInstallation, installArgs, registryPath,
registryDisplayName, registryType, registryName, registryValue, registryCompareOperator, registryDisplayName, registryType, registryName, registryValue, registryCompareOperator,
exitCodesToIgnore, installProcessName, rebootComputerAtCompletionRequested, rebootComputerImmediatelyRequested); exitCodesToIgnore, spawnedProcessesToIgnore, rebootComputerAtCompletionRequested, rebootComputerImmediatelyRequested);
} }
if (!setupSuccessful || ((frmSetupStatusDisplay)m_parentForm).applicationNeedsToBeRestarted()) if (!setupSuccessful || ((frmSetupStatusDisplay)m_parentForm).applicationNeedsToBeRestarted())
@@ -256,7 +249,7 @@ namespace All_Purpose_Auto_Setup
return setupSuccessful; return setupSuccessful;
} }
public bool installSoftware(string softwareName, string setupFile, string setupArgs, string exitCodesToIgnore, string installProcessName, bool promptBeforeInstall) public bool installSoftware(string softwareName, string setupFile, string setupArgs, string exitCodesToIgnore, string spawnedProcessesToIgnore, bool promptBeforeInstall)
{ {
string msg1 = String.Empty, msg2 = String.Empty, msg3, indentation = String.Empty; string msg1 = String.Empty, msg2 = String.Empty, msg3, indentation = String.Empty;
bool setupSuccessful = true; bool setupSuccessful = true;
@@ -381,7 +374,7 @@ namespace All_Purpose_Auto_Setup
process = Process.Start(setupFile); process = Process.Start(setupFile);
} }
int exitCode = WaitForAllToExit(process); int exitCode = WaitForAllToExit(process, spawnedProcessesToIgnore);
process.Close(); process.Close();
@@ -493,7 +486,7 @@ namespace All_Purpose_Auto_Setup
_resetEvent.Set(); // signal that execution of this thread is done _resetEvent.Set(); // signal that execution of this thread is done
} }
private int WaitForAllToExit(Process process) private int WaitForAllToExit(Process process, string spawnedProcessesToIgnore)
{ {
int exitCode = -1; int exitCode = -1;
@@ -527,7 +520,17 @@ namespace All_Purpose_Auto_Setup
continue; continue;
} }
exitCode = WaitForAllToExit(childProcess); string indentation = Common.getIndentation(1);
((frmSetupStatusDisplay)m_parentForm).writeToLog($"{indentation}Child process spawned: {childProcess.ProcessName}\r\n");
string[] processArray = Array.ConvertAll(spawnedProcessesToIgnore.Split(','), p => p.Trim());
if (!processArray.Contains(childProcess.ProcessName, StringComparer.OrdinalIgnoreCase))
{
exitCode = WaitForAllToExit(childProcess, spawnedProcessesToIgnore);
}
else
((frmSetupStatusDisplay)m_parentForm).writeToLog($"{indentation}Ignoring spawned process: {childProcess.ProcessName}\r\n");
} }
} }
} }
@@ -621,7 +624,7 @@ namespace All_Purpose_Auto_Setup
public bool checkSoftwareRegistry(string softwareName, string setupFile, bool promptBeforeInstall, string setupArgs, string registryPath, string registryDisplayName, string registryType, public bool checkSoftwareRegistry(string softwareName, string setupFile, bool promptBeforeInstall, string setupArgs, string registryPath, string registryDisplayName, string registryType,
string registryName, string registryValue, string registryCompareOperator, string registryName, string registryValue, string registryCompareOperator,
string exitCodesToIgnore, string installProcessName, bool rebootComputerAtCompletionRequested, bool rebootComputerImmediatelyRequested) string exitCodesToIgnore, string spawnedProcessesToIgnore, bool rebootComputerAtCompletionRequested, bool rebootComputerImmediatelyRequested)
{ {
bool setupSuccessful = true; bool setupSuccessful = true;
bool installSuccessful = true; bool installSuccessful = true;
@@ -654,7 +657,7 @@ namespace All_Purpose_Auto_Setup
{ {
if (retriesCount == 1 && setupFile.Length > 0) if (retriesCount == 1 && setupFile.Length > 0)
{ {
installSuccessful = installSoftware(softwareName, setupFile, setupArgs, exitCodesToIgnore, installProcessName, promptBeforeInstall); installSuccessful = installSoftware(softwareName, setupFile, setupArgs, exitCodesToIgnore, spawnedProcessesToIgnore, promptBeforeInstall);
installExecuted = true; installExecuted = true;
@@ -1087,14 +1090,14 @@ namespace All_Purpose_Auto_Setup
} }
else if (Regex.IsMatch(iniKey.iniKeyName, @"app\d+_reboot_computer_at_completion", RegexOptions.IgnoreCase)) else if (Regex.IsMatch(iniKey.iniKeyName, @"app\d+_reboot_computer_at_completion", RegexOptions.IgnoreCase))
{ {
if (String.Equals(iniKey.iniValue, "yes", StringComparison.OrdinalIgnoreCase)) if (String.Equals(iniKey.iniValue, "yes", StringComparison.OrdinalIgnoreCase) || String.Equals(iniKey.iniValue, "true", StringComparison.OrdinalIgnoreCase))
rebootComputerAtCompletionRequested = true; rebootComputerAtCompletionRequested = true;
else else
rebootComputerAtCompletionRequested = false; rebootComputerAtCompletionRequested = false;
} }
else if (Regex.IsMatch(iniKey.iniKeyName, @"app\d+_reboot_computer_immediately", RegexOptions.IgnoreCase)) else if (Regex.IsMatch(iniKey.iniKeyName, @"app\d+_reboot_computer_immediately", RegexOptions.IgnoreCase))
{ {
if (String.Equals(iniKey.iniValue, "yes", StringComparison.OrdinalIgnoreCase)) if (String.Equals(iniKey.iniValue, "yes", StringComparison.OrdinalIgnoreCase) || String.Equals(iniKey.iniValue, "true", StringComparison.OrdinalIgnoreCase))
rebootComputerImmediatelyRequested = true; rebootComputerImmediatelyRequested = true;
else else
rebootComputerImmediatelyRequested = false; rebootComputerImmediatelyRequested = false;
@@ -1104,7 +1107,7 @@ namespace All_Purpose_Auto_Setup
// get all the necessary info if user choose to verify software by looking at the registry // get all the necessary info if user choose to verify software by looking at the registry
public void getInfoUsingRegistryVerification(List<ConfigFileManager.Ini_KeyValue<string>> iniKeys, ref string registryPath, ref string registryDisplayName, public void getInfoUsingRegistryVerification(List<ConfigFileManager.Ini_KeyValue<string>> iniKeys, ref string registryPath, ref string registryDisplayName,
ref string registryType, ref string registryName, ref string registryValue, ref string registryCompareOperator, ref string installArgs, ref string exitCodesToIgnore, ref string installProcessName) ref string registryType, ref string registryName, ref string registryValue, ref string registryCompareOperator, ref string installArgs, ref string exitCodesToIgnore, ref string spawnedProcessesToIgnore)
{ {
registryPath = ""; registryPath = "";
registryDisplayName = ""; registryDisplayName = "";
@@ -1150,9 +1153,9 @@ namespace All_Purpose_Auto_Setup
{ {
exitCodesToIgnore = iniKey.iniValue; exitCodesToIgnore = iniKey.iniValue;
} }
else if (Regex.IsMatch(iniKey.iniKeyName, @"app\d+_install_process_name", RegexOptions.IgnoreCase)) else if (Regex.IsMatch(iniKey.iniKeyName, @"app\d+_spawned_processes_to_ignore", RegexOptions.IgnoreCase))
{ {
installProcessName = iniKey.iniValue; spawnedProcessesToIgnore = iniKey.iniValue;
} }
} }
} }

View File

@@ -1,23 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics; using System.Diagnostics;
using System.Text.RegularExpressions;
using System.IO;
using System.Security.AccessControl;
using System.Management;
using System.Security.Principal;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Drawing; using System.Drawing;
using System.IO;
using CommonLib.Windows.Forms; using System.Text.RegularExpressions;
using CommonLib.IO; using System.Threading;
using System.Windows.Forms;
using CommonLib.Misc; using CommonLib.Misc;
namespace All_Purpose_Auto_Setup namespace All_Purpose_Auto_Setup

View File

@@ -1,24 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.IO;
using System.Security.AccessControl;
using System.Management;
using System.Security.Principal;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Drawing; using System.Drawing;
using System.Text.RegularExpressions;
using CommonLib.Windows.Forms; using System.Windows.Forms;
using CommonLib.IO;
using CommonLib.Misc; using CommonLib.Misc;
using CommonLib.Windows.Misc; using CommonLib.Windows.Misc;
using Microsoft.Win32;
namespace All_Purpose_Auto_Setup namespace All_Purpose_Auto_Setup
{ {

View File

@@ -1,23 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.IO;
using System.Security.AccessControl;
using System.Management;
using System.Security.Principal;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Drawing; using System.Drawing;
using System.IO;
using CommonLib.Windows.Forms; using System.Text.RegularExpressions;
using System.Windows.Forms;
using CommonLib.IO; using CommonLib.IO;
using CommonLib.Misc; using CommonLib.Misc;
using CommonLib.Windows.Forms;
using CommonLib.Windows.Misc; using CommonLib.Windows.Misc;
namespace All_Purpose_Auto_Setup namespace All_Purpose_Auto_Setup

View File

@@ -1,15 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Reflection;
using System.IO; using System.IO;
using System.Reflection;
using CommonLib.Windows.Forms; using CommonLib.Windows.Forms;
namespace All_Purpose_Auto_Setup namespace All_Purpose_Auto_Setup

View File

@@ -1,21 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Text.RegularExpressions; using System.Linq;
using System.Threading;
using System.Reflection; using System.Reflection;
using System.Text.RegularExpressions;
using CommonLib.Windows.Forms; using System.Windows.Forms;
using CommonLib.IO; using CommonLib.IO;
using CommonLib.Misc; using CommonLib.Windows.Forms;
using CommonLib.Windows.Misc; using CommonLib.Windows.Misc;
namespace All_Purpose_Auto_Setup namespace All_Purpose_Auto_Setup

View File

@@ -1,25 +1,14 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Data;
using System.Drawing; using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.IO; using System.IO;
using System.Security.AccessControl; using System.Text.RegularExpressions;
using System.Management; using System.Threading;
using System.Security.Principal; using System.Windows.Forms;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using CommonLib.Windows.Forms;
using CommonLib.IO; using CommonLib.IO;
using CommonLib.Misc; using CommonLib.Misc;
using CommonLib.Windows.Forms;
using CommonLib.Windows.Misc; using CommonLib.Windows.Misc;
namespace All_Purpose_Auto_Setup namespace All_Purpose_Auto_Setup
@@ -148,6 +137,7 @@ namespace All_Purpose_Auto_Setup
str = Regex.Replace(str, @"\n", "\r\n", RegexOptions.IgnoreCase); str = Regex.Replace(str, @"\n", "\r\n", RegexOptions.IgnoreCase);
swSetupLog.Write(str); swSetupLog.Write(str);
swSetupLog.Flush();
} }
} }
@@ -164,6 +154,7 @@ namespace All_Purpose_Auto_Setup
str = Regex.Replace(str, @"\n", "\r\n", RegexOptions.IgnoreCase); str = Regex.Replace(str, @"\n", "\r\n", RegexOptions.IgnoreCase);
swSetupLog.Write(str); swSetupLog.Write(str);
swSetupLog.Flush();
} }
return FormControlsManipThreadSafe.getRichTextBoxLastLineIndex(statusRtxtbox); return FormControlsManipThreadSafe.getRichTextBoxLastLineIndex(statusRtxtbox);
@@ -177,6 +168,7 @@ namespace All_Purpose_Auto_Setup
str = Regex.Replace(str, @"\n", "\r\n", RegexOptions.IgnoreCase); str = Regex.Replace(str, @"\n", "\r\n", RegexOptions.IgnoreCase);
swSetupLog.Write(str); swSetupLog.Write(str);
swSetupLog.Flush();
} }
} }

View File

@@ -1,13 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using System.Threading;
using CommonLib.Windows.Forms; using CommonLib.Windows.Forms;