mirror of
https://github.com/tribufu/ServerManagers
synced 2026-05-06 15:17:34 +00:00
source code checkin
This commit is contained in:
parent
5f8fb2c825
commit
7e57b72e35
675 changed files with 168433 additions and 0 deletions
6
src/ServerManager.Updater/App.config
Normal file
6
src/ServerManager.Updater/App.config
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
|
||||
</startup>
|
||||
</configuration>
|
||||
BIN
src/ServerManager.Updater/Art/favicon.ico
Normal file
BIN
src/ServerManager.Updater/Art/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
293
src/ServerManager.Updater/Program.cs
Normal file
293
src/ServerManager.Updater/Program.cs
Normal file
|
|
@ -0,0 +1,293 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ServerManagerTool.Updater
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
private static string[] ApplicationArgs
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
private static string DownloadUrl
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
private static string Prefix
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
Console.Title = "Server Manager Updater";
|
||||
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
|
||||
|
||||
var updaterArgs = args;
|
||||
ApplicationArgs = null;
|
||||
DownloadUrl = null;
|
||||
Prefix = null;
|
||||
|
||||
try
|
||||
{
|
||||
// check if the updater is already running
|
||||
if (ProcessUtils.IsAlreadyRunning())
|
||||
throw new Exception("The updater is already running.");
|
||||
|
||||
var process = Validate(updaterArgs);
|
||||
CloseApplication(process);
|
||||
process = null;
|
||||
|
||||
Update();
|
||||
RestartApplication();
|
||||
|
||||
Environment.ExitCode = 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OutputError(ex.Message, ex.StackTrace);
|
||||
Environment.ExitCode = 1;
|
||||
|
||||
OutputMessage("Press any key to continue.");
|
||||
Console.ReadKey(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CloseApplication(Process process)
|
||||
{
|
||||
OutputMessage("Closing application...");
|
||||
|
||||
if (process == null || process.HasExited)
|
||||
throw new Exception("The process is not associated with a running application.");
|
||||
|
||||
// send a close to the application
|
||||
process.CloseMainWindow();
|
||||
|
||||
// wait until the application has been closed
|
||||
DateTime start = DateTime.Now;
|
||||
while (!process.HasExited)
|
||||
{
|
||||
if (start.AddMinutes(5) < DateTime.Now)
|
||||
{
|
||||
process.Kill();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!process.HasExited)
|
||||
throw new Exception("The application could not be closed.");
|
||||
}
|
||||
|
||||
private static void OutputError(string error, string stackTrace)
|
||||
{
|
||||
Console.WriteLine($"ERROR: {error}");
|
||||
}
|
||||
|
||||
private static void OutputMessage(string message)
|
||||
{
|
||||
Console.WriteLine(message);
|
||||
}
|
||||
|
||||
private static void RestartApplication()
|
||||
{
|
||||
OutputMessage("Restarting application...");
|
||||
|
||||
var file = ApplicationArgs[0];
|
||||
var arguments = string.Empty;
|
||||
if (ApplicationArgs.Length > 1)
|
||||
{
|
||||
string[] argumentArray = new string[ApplicationArgs.Length - 1];
|
||||
Array.Copy(ApplicationArgs, 1, argumentArray, 0, argumentArray.Length);
|
||||
arguments = String.Join(" ", argumentArray);
|
||||
}
|
||||
|
||||
ProcessStartInfo info = new ProcessStartInfo()
|
||||
{
|
||||
FileName = file.AsQuoted(),
|
||||
Arguments = arguments,
|
||||
UseShellExecute = true,
|
||||
CreateNoWindow = true,
|
||||
};
|
||||
|
||||
var process = Process.Start(info);
|
||||
if (process == null)
|
||||
throw new Exception("Could not restart application.");
|
||||
}
|
||||
|
||||
private static void Update()
|
||||
{
|
||||
if (ApplicationArgs == null || ApplicationArgs.Length == 0)
|
||||
throw new ArgumentNullException(nameof(ApplicationArgs), "The application args cannot be null or empty.");
|
||||
if (string.IsNullOrWhiteSpace(DownloadUrl))
|
||||
throw new ArgumentNullException(nameof(DownloadUrl), "The download url cannot be null or empty.");
|
||||
if (string.IsNullOrWhiteSpace(Prefix))
|
||||
throw new ArgumentNullException(nameof(Prefix), "The prefix cannot be null or empty.");
|
||||
|
||||
OutputMessage("Starting upgrade process...");
|
||||
|
||||
var currentInstallPath = Path.GetDirectoryName(ApplicationArgs[0]);
|
||||
var upgradeStagingPath = Path.GetTempPath();
|
||||
var applicationZip = Path.Combine(upgradeStagingPath, $"{Prefix}Latest.zip");
|
||||
var extractPath = Path.Combine(upgradeStagingPath, $"{Prefix}Latest");
|
||||
|
||||
// Download the latest version
|
||||
using (var client = new WebClient())
|
||||
{
|
||||
OutputMessage("Downloading latest version file...");
|
||||
#if DEBUG
|
||||
OutputMessage($"Url: {DownloadUrl}");
|
||||
OutputMessage($"Zip: {applicationZip}");
|
||||
#endif
|
||||
client.DownloadFile(DownloadUrl, applicationZip);
|
||||
}
|
||||
|
||||
// Unblock the downloaded file
|
||||
OutputMessage("Preparing downloaded file...");
|
||||
#if DEBUG
|
||||
OutputMessage($"Zip: {applicationZip}");
|
||||
#endif
|
||||
IOUtils.Unblock(applicationZip);
|
||||
|
||||
try
|
||||
{
|
||||
// Delete the old extraction directory
|
||||
if (Directory.Exists(extractPath))
|
||||
{
|
||||
#if DEBUG
|
||||
OutputMessage("Deleting extract directory...");
|
||||
OutputMessage($"Dir: {extractPath}");
|
||||
#endif
|
||||
Directory.Delete(extractPath, true);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
// Extract latest version to extraction directory
|
||||
OutputMessage("Extracting latest version to staging area...");
|
||||
#if DEBUG
|
||||
OutputMessage($"Zip: {applicationZip}");
|
||||
OutputMessage($"Dir: {extractPath}");
|
||||
#endif
|
||||
ZipFile.ExtractToDirectory(applicationZip, extractPath);
|
||||
|
||||
// build a list of files to be updated
|
||||
var latestFiles = Directory.GetFiles(extractPath, "*.*", SearchOption.AllDirectories).ToList();
|
||||
|
||||
// build a list of files to be removed
|
||||
var deleteFiles = Directory.GetFiles(currentInstallPath, "*.*", SearchOption.AllDirectories).ToList();
|
||||
foreach (var latestFile in latestFiles)
|
||||
{
|
||||
var file = Path.Combine(currentInstallPath, latestFile.Replace($"{extractPath}\\", ""));
|
||||
if (deleteFiles.Contains(file))
|
||||
deleteFiles.Remove(file);
|
||||
}
|
||||
|
||||
OutputMessage("Upgrading application...");
|
||||
|
||||
// delete the obsolete files
|
||||
foreach (var deleteFile in deleteFiles)
|
||||
{
|
||||
if (File.Exists(deleteFile))
|
||||
{
|
||||
#if DEBUG
|
||||
OutputMessage($"Delete: {deleteFile}");
|
||||
#endif
|
||||
//File.Delete(deleteFile);
|
||||
}
|
||||
}
|
||||
|
||||
// remove the updater from the files to be updated
|
||||
var assemblyFile = Assembly.GetEntryAssembly().Location;
|
||||
var assemblyPath = Path.GetDirectoryName(assemblyFile);
|
||||
|
||||
var updaterFile = Path.Combine(extractPath, assemblyFile.Replace($"{assemblyPath}\\", ""));
|
||||
#if DEBUG
|
||||
OutputMessage($"Checking: {updaterFile}");
|
||||
#endif
|
||||
if (latestFiles.Contains(updaterFile))
|
||||
latestFiles.Remove(updaterFile);
|
||||
|
||||
var updaterConfigFile = Path.Combine(updaterFile, ".config");
|
||||
#if DEBUG
|
||||
OutputMessage($"Checking: {updaterConfigFile}");
|
||||
#endif
|
||||
if (latestFiles.Contains(updaterConfigFile))
|
||||
latestFiles.Remove(updaterConfigFile);
|
||||
|
||||
// Replace the current installation
|
||||
foreach (var latestFile in latestFiles)
|
||||
{
|
||||
var file = Path.Combine(currentInstallPath, latestFile.Replace($"{extractPath}\\", ""));
|
||||
if (File.Exists(latestFile))
|
||||
{
|
||||
#if DEBUG
|
||||
OutputMessage($"Copy: {latestFile} to {file}");
|
||||
#endif
|
||||
// check if the directory exists
|
||||
var filePath = Path.GetDirectoryName(file);
|
||||
if (!Directory.Exists(filePath))
|
||||
Directory.CreateDirectory(filePath);
|
||||
|
||||
// copy over the file
|
||||
File.Copy(latestFile, file, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Process Validate(string[] args)
|
||||
{
|
||||
OutputMessage("Validating update...");
|
||||
|
||||
// argument format - PID, DownloadUrl, Prefix
|
||||
if (args == null)
|
||||
throw new ArgumentNullException(nameof(args), "The arguments cannot be null or empty");
|
||||
if (args == null || args.Length != 3)
|
||||
throw new ArgumentOutOfRangeException(nameof(args), "The arguments do not contain valid information.");
|
||||
|
||||
// check if the passed pid is valid
|
||||
if (!int.TryParse(args[0], out int pid))
|
||||
throw new InvalidCastException("The process id value is not valid.");
|
||||
|
||||
DownloadUrl = args[1];
|
||||
if (string.IsNullOrWhiteSpace(DownloadUrl))
|
||||
throw new ArgumentNullException(nameof(DownloadUrl), "The download url cannot be null or empty.");
|
||||
|
||||
Prefix = args[2];
|
||||
if (string.IsNullOrWhiteSpace(Prefix))
|
||||
throw new ArgumentNullException(nameof(Prefix), "The prefix cannot be null or empty.");
|
||||
|
||||
// get the process associated with the pid
|
||||
var process = ProcessUtils.GetProcess(pid);
|
||||
if (process == null)
|
||||
throw new Exception("The process id value is not associated with a running application.");
|
||||
|
||||
// get a list of the running processes with the same name and file location
|
||||
var executablePath = ProcessUtils.GetMainModuleFilepath(pid);
|
||||
var processes = ProcessUtils.GetProcesses(process.ProcessName, executablePath);
|
||||
|
||||
// check if there is more than one instance of the application running
|
||||
if (processes.Length != 1)
|
||||
throw new Exception("The application to be updated has more than one instance running.");
|
||||
|
||||
// get the command line of the process
|
||||
var commandLine = ProcessUtils.GetCommandLineForProcess(pid);
|
||||
ApplicationArgs = ProcessUtils.CommandLineToArgs(commandLine);
|
||||
|
||||
if (ApplicationArgs == null || ApplicationArgs.Length == 0)
|
||||
throw new ArgumentNullException(nameof(ApplicationArgs), "The application args cannot be null or empty.");
|
||||
|
||||
return process;
|
||||
}
|
||||
}
|
||||
}
|
||||
35
src/ServerManager.Updater/Properties/AssemblyInfo.cs
Normal file
35
src/ServerManager.Updater/Properties/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("ServerManager Updater")]
|
||||
[assembly: AssemblyDescription("An application used to update the server managers.")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Bletch1971")]
|
||||
[assembly: AssemblyProduct("Server Managers")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2015-2020")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("3e0c9ee6-780f-4fef-ba03-e38062a5fdb6")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.1")]
|
||||
54
src/ServerManager.Updater/Properties/app.manifest
Normal file
54
src/ServerManager.Updater/Properties/app.manifest
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<!-- UAC Manifest Options
|
||||
If you want to change the Windows User Account Control level replace the
|
||||
requestedExecutionLevel node with one of the following.
|
||||
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||
|
||||
Specifying requestedExecutionLevel node will disable file and registry virtualization.
|
||||
If you want to utilize File and Registry Virtualization for backward
|
||||
compatibility then delete the requestedExecutionLevel node.
|
||||
-->
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
<applicationRequestMinimum>
|
||||
<defaultAssemblyRequest permissionSetReference="Custom" />
|
||||
<PermissionSet class="System.Security.PermissionSet" version="1" ID="Custom" SameSite="site" Unrestricted="true" />
|
||||
</applicationRequestMinimum>
|
||||
</security>
|
||||
</trustInfo>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- A list of all Windows versions that this application is designed to work with.
|
||||
Windows will automatically select the most compatible environment.-->
|
||||
<!-- If your application is designed to work with Windows Vista, uncomment the following supportedOS node-->
|
||||
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"></supportedOS>-->
|
||||
<!-- If your application is designed to work with Windows 7, uncomment the following supportedOS node-->
|
||||
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>-->
|
||||
<!-- If your application is designed to work with Windows 8, uncomment the following supportedOS node-->
|
||||
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS>-->
|
||||
<!-- If your application is designed to work with Windows 8.1, uncomment the following supportedOS node-->
|
||||
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>-->
|
||||
</application>
|
||||
</compatibility>
|
||||
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
|
||||
<!-- <dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>-->
|
||||
</asmv1:assembly>
|
||||
28
src/ServerManager.Updater/ServerManager.Updater.csproj
Normal file
28
src/ServerManager.Updater/ServerManager.Updater.csproj
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup Label="Globals">
|
||||
<SccProjectName>%24/Development/ServerManagers/Main/ServerManager.Updater</SccProjectName>
|
||||
<SccProvider>{4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}</SccProvider>
|
||||
<SccAuxPath>https://dev.azure.com/bretthewitson</SccAuxPath>
|
||||
<SccLocalPath>.</SccLocalPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net462</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<ApplicationIcon>Art\favicon.ico</ApplicationIcon>
|
||||
<StartupObject>ServerManagerTool.Updater.Program</StartupObject>
|
||||
<AssemblyName>ServerManagerUpdater</AssemblyName>
|
||||
<RootNamespace>ServerManagerTool.Updater</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebugType>none</DebugType>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Management" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
20
src/ServerManager.Updater/Utils/IOUtils.cs
Normal file
20
src/ServerManager.Updater/Utils/IOUtils.cs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ServerManagerTool.Updater
|
||||
{
|
||||
public static class IOUtils
|
||||
{
|
||||
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool DeleteFile(string name);
|
||||
|
||||
public static bool Unblock(string fileName)
|
||||
{
|
||||
return DeleteFile(fileName + ":Zone.Identifier");
|
||||
}
|
||||
|
||||
public static string NormalizePath(string path) => Path.GetFullPath(new Uri(path).LocalPath).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar).ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
113
src/ServerManager.Updater/Utils/ProcessUtils.cs
Normal file
113
src/ServerManager.Updater/Utils/ProcessUtils.cs
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace ServerManagerTool.Updater
|
||||
{
|
||||
public static class ProcessUtils
|
||||
{
|
||||
public static string FIELD_COMMANDLINE = "CommandLine";
|
||||
public static string FIELD_EXECUTABLEPATH = "ExecutablePath";
|
||||
public static string FIELD_PROCESSID = "ProcessId";
|
||||
|
||||
private static Mutex _mutex;
|
||||
|
||||
[DllImport("shell32.dll", SetLastError = true)]
|
||||
static extern IntPtr CommandLineToArgvW([MarshalAs(UnmanagedType.LPWStr)] string lpCmdLine, out int pNumArgs);
|
||||
|
||||
public static string[] CommandLineToArgs(string commandLine)
|
||||
{
|
||||
var argv = CommandLineToArgvW(commandLine, out int argc);
|
||||
if (argv == IntPtr.Zero)
|
||||
throw new Win32Exception();
|
||||
|
||||
try
|
||||
{
|
||||
var args = new string[argc];
|
||||
for (var i = 0; i < args.Length; i++)
|
||||
{
|
||||
var p = Marshal.ReadIntPtr(argv, i * IntPtr.Size);
|
||||
args[i] = Marshal.PtrToStringUni(p);
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.FreeHGlobal(argv);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetCommandLineForProcess(int processId)
|
||||
{
|
||||
var wmiQueryString = $"SELECT {FIELD_COMMANDLINE} FROM Win32_Process WHERE {FIELD_PROCESSID} = {processId}";
|
||||
|
||||
using (var searcher = new ManagementObjectSearcher(wmiQueryString))
|
||||
{
|
||||
using (var results = searcher.Get())
|
||||
{
|
||||
ManagementObject mo = results.Cast<ManagementObject>().FirstOrDefault();
|
||||
if (mo != null)
|
||||
return (string)mo[FIELD_COMMANDLINE];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string GetMainModuleFilepath(int processId)
|
||||
{
|
||||
var wmiQueryString = $"SELECT {FIELD_EXECUTABLEPATH} FROM Win32_Process WHERE {FIELD_PROCESSID} = {processId}";
|
||||
|
||||
using (var searcher = new ManagementObjectSearcher(wmiQueryString))
|
||||
{
|
||||
using (var results = searcher.Get())
|
||||
{
|
||||
ManagementObject mo = results.Cast<ManagementObject>().FirstOrDefault();
|
||||
if (mo != null)
|
||||
return (string)mo[FIELD_EXECUTABLEPATH];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Process GetProcess(int processId)
|
||||
{
|
||||
return Process.GetProcessById(processId);
|
||||
}
|
||||
|
||||
public static Process[] GetProcesses(string processName, string executablePath)
|
||||
{
|
||||
var runningProcesses = Process.GetProcessesByName(processName).ToList();
|
||||
|
||||
for (var i = runningProcesses.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var process = runningProcesses[i];
|
||||
var runningPath = GetMainModuleFilepath(process.Id);
|
||||
if (!string.Equals(executablePath, runningPath, StringComparison.OrdinalIgnoreCase))
|
||||
runningProcesses.RemoveAt(i);
|
||||
}
|
||||
|
||||
return runningProcesses.ToArray();
|
||||
}
|
||||
|
||||
public static bool IsAlreadyRunning()
|
||||
{
|
||||
var assemblyLocation = Assembly.GetEntryAssembly().Location;
|
||||
var name = $"Global::{Path.GetFileName(assemblyLocation)}";
|
||||
|
||||
_mutex = new Mutex(true, name, out bool createdNew);
|
||||
if (createdNew)
|
||||
_mutex.ReleaseMutex();
|
||||
|
||||
return !createdNew;
|
||||
}
|
||||
}
|
||||
}
|
||||
15
src/ServerManager.Updater/Utils/ScriptUtils.cs
Normal file
15
src/ServerManager.Updater/Utils/ScriptUtils.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
namespace ServerManagerTool.Updater
|
||||
{
|
||||
public static class ScriptUtils
|
||||
{
|
||||
public static string AsQuoted(this string parameter)
|
||||
{
|
||||
var newValue = parameter;
|
||||
if (!newValue.StartsWith("\""))
|
||||
newValue = "\"" + newValue;
|
||||
if (!newValue.EndsWith("\""))
|
||||
newValue = newValue + "\"";
|
||||
return newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue