mirror of
https://gitlab.com/cleanflash/installer.git
synced 2026-08-12 18:31:37 +08:00
processes: Only kill processes that contain loaded Flash modules
This commit is contained in:
@@ -57,7 +57,7 @@
|
||||
</Compile>
|
||||
<Compile Include="InstallException.cs" />
|
||||
<Compile Include="IProgressForm.cs" />
|
||||
<Compile Include="ProcessRunner.cs" />
|
||||
<Compile Include="ProcessUtils.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace CleanFlashCommon {
|
||||
public class ProcessRunner {
|
||||
|
||||
public static ExitedProcess RunProcess(ProcessStartInfo startInfo) {
|
||||
startInfo.RedirectStandardOutput = true;
|
||||
startInfo.RedirectStandardError = true;
|
||||
|
||||
StringBuilder outputBuilder = new StringBuilder();
|
||||
Process process = new Process {
|
||||
StartInfo = startInfo
|
||||
};
|
||||
DataReceivedEventHandler outputHandler = new DataReceivedEventHandler(
|
||||
delegate (object sender, DataReceivedEventArgs e) {
|
||||
outputBuilder.AppendLine(e.Data);
|
||||
}
|
||||
);
|
||||
|
||||
process.OutputDataReceived += outputHandler;
|
||||
process.ErrorDataReceived += outputHandler;
|
||||
|
||||
process.Start();
|
||||
process.BeginOutputReadLine();
|
||||
process.BeginErrorReadLine();
|
||||
process.WaitForExit();
|
||||
process.CancelOutputRead();
|
||||
process.CancelErrorRead();
|
||||
|
||||
return new ExitedProcess {
|
||||
ExitCode = process.ExitCode,
|
||||
Output = outputBuilder.ToString().Trim()
|
||||
};
|
||||
}
|
||||
|
||||
public static Process RunUnmanagedProcess(ProcessStartInfo startInfo) {
|
||||
Process process = new Process {
|
||||
StartInfo = startInfo
|
||||
};
|
||||
process.Start();
|
||||
process.WaitForExit();
|
||||
return process;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace CleanFlashCommon {
|
||||
public class ProcessUtils {
|
||||
|
||||
class Native {
|
||||
internal enum ModuleFilter {
|
||||
ListModulesDefault = 0x0,
|
||||
ListModules32Bit = 0x01,
|
||||
ListModules64Bit = 0x02,
|
||||
ListModulesAll = 0x03,
|
||||
}
|
||||
|
||||
[DllImport("psapi.dll")]
|
||||
public static extern bool EnumProcessModulesEx(IntPtr hProcess, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U4)][In][Out] IntPtr[] lphModule, int cb, [MarshalAs(UnmanagedType.U4)] out int lpcbNeeded, uint dwFilterFlag);
|
||||
|
||||
[DllImport("psapi.dll")]
|
||||
public static extern bool EnumProcessModules(IntPtr hProcess, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U4)][In][Out] IntPtr[] lphModule, int cb, [MarshalAs(UnmanagedType.U4)] out int lpcbNeeded);
|
||||
|
||||
[DllImport("psapi.dll")]
|
||||
public static extern uint GetModuleFileNameEx(IntPtr hProcess, IntPtr hModule, [Out] StringBuilder lpBaseName, [In][MarshalAs(UnmanagedType.U4)] uint nSize);
|
||||
}
|
||||
|
||||
public static List<string> CollectModules(Process process) {
|
||||
List<string> collectedModules = new List<string>();
|
||||
bool ex = true;
|
||||
|
||||
IntPtr[] modulePointers = new IntPtr[0];
|
||||
int bytesNeeded;
|
||||
|
||||
// Determine number of modules
|
||||
try {
|
||||
if (!Native.EnumProcessModulesEx(process.Handle, modulePointers, 0, out bytesNeeded, (uint)Native.ModuleFilter.ListModulesAll)) {
|
||||
return collectedModules;
|
||||
}
|
||||
} catch (EntryPointNotFoundException) {
|
||||
if (!Native.EnumProcessModules(process.Handle, modulePointers, 0, out bytesNeeded)) {
|
||||
return collectedModules;
|
||||
}
|
||||
|
||||
ex = false;
|
||||
} catch {
|
||||
return collectedModules;
|
||||
}
|
||||
|
||||
int totalModules = bytesNeeded / IntPtr.Size;
|
||||
modulePointers = new IntPtr[totalModules];
|
||||
|
||||
// Collect modules from the process
|
||||
if ((ex && !Native.EnumProcessModulesEx(process.Handle, modulePointers, bytesNeeded, out bytesNeeded, (uint) Native.ModuleFilter.ListModulesAll)) || (!ex && !Native.EnumProcessModules(process.Handle, modulePointers, bytesNeeded, out bytesNeeded))) {
|
||||
return collectedModules;
|
||||
}
|
||||
|
||||
for (int i = 0; i < totalModules; ++i) {
|
||||
StringBuilder moduleFilePath = new StringBuilder(1024);
|
||||
Native.GetModuleFileNameEx(process.Handle, modulePointers[i], moduleFilePath, (uint) moduleFilePath.Capacity);
|
||||
|
||||
string moduleName = Path.GetFileName(moduleFilePath.ToString());
|
||||
collectedModules.Add(moduleName);
|
||||
}
|
||||
|
||||
return collectedModules;
|
||||
}
|
||||
|
||||
public static ExitedProcess RunProcess(ProcessStartInfo startInfo)
|
||||
{
|
||||
startInfo.RedirectStandardOutput = true;
|
||||
startInfo.RedirectStandardError = true;
|
||||
|
||||
StringBuilder outputBuilder = new StringBuilder();
|
||||
Process process = new Process
|
||||
{
|
||||
StartInfo = startInfo
|
||||
};
|
||||
DataReceivedEventHandler outputHandler = new DataReceivedEventHandler(
|
||||
delegate (object sender, DataReceivedEventArgs e) {
|
||||
outputBuilder.AppendLine(e.Data);
|
||||
}
|
||||
);
|
||||
|
||||
process.OutputDataReceived += outputHandler;
|
||||
process.ErrorDataReceived += outputHandler;
|
||||
|
||||
process.Start();
|
||||
process.BeginOutputReadLine();
|
||||
process.BeginErrorReadLine();
|
||||
process.WaitForExit();
|
||||
process.CancelOutputRead();
|
||||
process.CancelErrorRead();
|
||||
|
||||
return new ExitedProcess
|
||||
{
|
||||
ExitCode = process.ExitCode,
|
||||
Output = outputBuilder.ToString().Trim()
|
||||
};
|
||||
}
|
||||
|
||||
public static Process RunUnmanagedProcess(ProcessStartInfo startInfo)
|
||||
{
|
||||
Process process = new Process
|
||||
{
|
||||
StartInfo = startInfo
|
||||
};
|
||||
process.Start();
|
||||
process.WaitForExit();
|
||||
return process;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ namespace CleanFlashCommon {
|
||||
|
||||
Directory.SetCurrentDirectory(Path.GetDirectoryName(filename));
|
||||
|
||||
ExitedProcess process = ProcessRunner.RunProcess(
|
||||
ExitedProcess process = ProcessUtils.RunProcess(
|
||||
new ProcessStartInfo {
|
||||
FileName = "reg.exe",
|
||||
Arguments = "import " + Path.GetFileName(filename),
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace CleanFlashCommon {
|
||||
public class Uninstaller {
|
||||
@@ -12,10 +13,14 @@ namespace CleanFlashCommon {
|
||||
"flashcenterservice", "flashcenteruninst", "flashplay", "update", "wow_helper",
|
||||
"dummy_cmd", "flashhelperservice",
|
||||
// Flash Player-related processes
|
||||
"flashplayerapp", "flashplayer_sa", "flashplayer_sa_debug",
|
||||
"flashplayerapp", "flashplayer_sa", "flashplayer_sa_debug"
|
||||
};
|
||||
private static string[] CONDITIONAL_PROCESSES = new string[]
|
||||
{
|
||||
// Plugin container for Firefox
|
||||
"plugin-container",
|
||||
// Browsers that might be using Flash Player right now
|
||||
"opera", "iexplore", "chrome", "chromium", "brave", "vivaldi", "basilisk", "msedge",
|
||||
"seamonkey", "palemoon", "k-meleon", "plugin-container", "waterfox"
|
||||
"opera", "iexplore", "chrome", "chromium", "brave", "vivaldi", "msedge"
|
||||
};
|
||||
|
||||
static Uninstaller() {
|
||||
@@ -31,7 +36,7 @@ namespace CleanFlashCommon {
|
||||
}
|
||||
|
||||
public static void DeleteTask(string task) {
|
||||
ProcessRunner.RunUnmanagedProcess(
|
||||
ProcessUtils.RunUnmanagedProcess(
|
||||
new ProcessStartInfo {
|
||||
FileName = "schtasks.exe",
|
||||
Arguments = "/delete /tn \"" + task + "\" /f",
|
||||
@@ -42,7 +47,7 @@ namespace CleanFlashCommon {
|
||||
}
|
||||
|
||||
public static void StopService(string service) {
|
||||
ProcessRunner.RunUnmanagedProcess(
|
||||
ProcessUtils.RunUnmanagedProcess(
|
||||
new ProcessStartInfo {
|
||||
FileName = "net.exe",
|
||||
Arguments = "stop \"" + service + "\"",
|
||||
@@ -56,7 +61,7 @@ namespace CleanFlashCommon {
|
||||
// First, stop the service.
|
||||
StopService(service);
|
||||
|
||||
ProcessRunner.RunUnmanagedProcess(
|
||||
ProcessUtils.RunUnmanagedProcess(
|
||||
new ProcessStartInfo {
|
||||
FileName = "sc.exe",
|
||||
Arguments = "delete \"" + service + "\"",
|
||||
@@ -125,10 +130,25 @@ namespace CleanFlashCommon {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static bool ShouldKillConditionalProcess(Process process) {
|
||||
if (!CONDITIONAL_PROCESSES.Contains(process.ProcessName.ToLower())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (string module in ProcessUtils.CollectModules(process)) {
|
||||
if (Regex.IsMatch(module, "^(flash(32|64)|libpepflash|npswf)", RegexOptions.Compiled | RegexOptions.IgnoreCase)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void StopProcesses() {
|
||||
// Stop all processes that might interfere with the install process
|
||||
List<Process> processes = Process.GetProcesses()
|
||||
.Where(process => PROCESSES_TO_KILL.Contains(process.ProcessName.ToLower()))
|
||||
.Where(process => PROCESSES_TO_KILL.Contains(process.ProcessName.ToLower()) || ShouldKillConditionalProcess(process))
|
||||
.OrderBy(o => o.StartTime)
|
||||
.ToList();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user