Ejemplo n.º 1
0
        private static bool UpdateCache()
        {
            //
            // Run the update.
            //
            Console.WriteLine("Running the update");
            bool gotNewVersion      = false;
            bool downloadSuccessful = false;
            DataReceivedEventHandler outputHandler = (s, e) =>
            {
                Console.WriteLine(e.Data);
                if (!gotNewVersion && e.Data.Contains("downloading,"))
                {
                    gotNewVersion = true;
                }

                if (e.Data.StartsWith("Success!"))
                {
                    downloadSuccessful = true;
                }
            };

            var result = ServerUpdater.UpgradeServerAsync(false, InstallDirectory, SteamCmdPath, "+login anonymous +force_install_dir \"{0}\"  \"+app_update 376030 {1}\" +quit", null, CancellationToken.None).Result;

            if (!result || !downloadSuccessful)
            {
                Console.WriteLine("Failed to update.");
                return(false);
            }
            else
            {
                File.WriteAllText(GetLatestCacheTimeFile(), DateTime.Now.ToString("o", CultureInfo.CurrentCulture));
                return(true);
            }
        }
        public async Task <bool> UpgradeAsync(CancellationToken cancellationToken, bool validate)
        {
            if (!System.Environment.Is64BitOperatingSystem)
            {
                var result = MessageBox.Show("ARK: Survival Evolved(tm) Server requires a 64-bit operating system to run.  Your operating system is 32-bit and therefore the Ark Server Manager will be unable to start the server, but you may still install it or load and save profiles and settings files for use on other machines.\r\n\r\nDo you wish to continue?", "64-bit OS Required", MessageBoxButton.YesNo, MessageBoxImage.Warning);
                if (result == MessageBoxResult.No)
                {
                    return(false);
                }
            }

            string serverExe = GetServerExe();

            try
            {
                await StopAsync();

                this.Status = ServerStatus.Updating;

                // Run the SteamCMD to install the server
                var steamCmdPath = Updater.GetSteamCMDPath();
                //DataReceivedEventHandler dataReceived = (s, e) => Console.WriteLine(e.Data);
                var success = await ServerUpdater.UpgradeServerAsync(validate, this.ProfileSnapshot.InstallDirectory, steamCmdPath, Config.Default.SteamCmdInstallServerArgsFormat, null /* dataReceived*/, cancellationToken);

                if (success && ServerManager.Instance.AvailableVersion != null)
                {
                    this.Version = ServerManager.Instance.AvailableVersion;
                }

                return(success);
            }
            catch (TaskCanceledException)
            {
                return(false);
            }
            finally
            {
                this.Status = ServerStatus.Stopped;
            }
        }
        private static ServerProcessStatus GetServerProcessStatus(ServerStatusUpdateRegistration updateContext, out Process serverProcess)
        {
            serverProcess = null;
            if (String.IsNullOrWhiteSpace(updateContext.InstallDirectory))
            {
                return(ServerProcessStatus.NotInstalled);
            }

            var serverExePath = Path.Combine(updateContext.InstallDirectory, Config.Default.ServerBinaryRelativePath, Config.Default.ServerExe);

            if (!File.Exists(serverExePath))
            {
                return(ServerProcessStatus.NotInstalled);
            }

            //
            // The server appears to be installed, now determine if it is running or stopped.
            //
            try
            {
                foreach (var process in Process.GetProcessesByName(Config.Default.ServerProcessName))
                {
                    var commandLine = ServerUpdater.GetCommandLineForProcess(process.Id);

                    if (commandLine.Contains(updateContext.InstallDirectory) && commandLine.Contains(Config.Default.ServerExe))
                    {
                        // Does this match our server exe and port?
                        var serverArgMatch = String.Format(Config.Default.ServerCommandLineArgsMatchFormat, updateContext.LocalEndpoint.Port);
                        if (commandLine.Contains(serverArgMatch))
                        {
                            // Was an IP set on it?
                            var anyIpArgMatch = String.Format(Config.Default.ServerCommandLineArgsIPMatchFormat, String.Empty);
                            if (commandLine.Contains(anyIpArgMatch))
                            {
                                // If we have a specific IP, check for it.
                                var ipArgMatch = String.Format(Config.Default.ServerCommandLineArgsIPMatchFormat, updateContext.LocalEndpoint.Address.ToString());
                                if (!commandLine.Contains(ipArgMatch))
                                {
                                    // Specific IP set didn't match
                                    continue;
                                }

                                // Specific IP matched
                            }

                            // Either specific IP matched or no specific IP was set and we will claim this is ours.

                            process.EnableRaisingEvents = true;
                            if (process.HasExited)
                            {
                                return(ServerProcessStatus.Stopped);
                            }

                            serverProcess = process;
                            return(ServerProcessStatus.Running);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Debug("Exception while checking process status: {0}\n{1}", ex.Message, ex.StackTrace);
            }

            return(ServerProcessStatus.Stopped);
        }
Ejemplo n.º 4
0
        public async Task <bool> UpgradeAsync(CancellationToken cancellationToken, bool updateServer, bool validate, bool updateMods, ProgressDelegate progressCallback)
        {
            if (updateServer && !Environment.Is64BitOperatingSystem)
            {
                var result = MessageBox.Show("The ARK server requires a 64-bit operating system to run. Your operating system is 32-bit and therefore the Ark Server Manager will be unable to start the server, but you may still install it or load and save profiles and settings files for use on other machines.\r\n\r\nDo you wish to continue?", "64-bit OS Required", MessageBoxButton.YesNo, MessageBoxImage.Warning);
                if (result == MessageBoxResult.No)
                {
                    return(false);
                }
            }

            try
            {
                await StopAsync();

                bool isNewInstallation = this.Status == ServerStatus.Uninstalled;

                this.Status = ServerStatus.Updating;

                // Run the SteamCMD to install the server
                var steamCmdFile = Updater.GetSteamCmdFile();
                if (string.IsNullOrWhiteSpace(steamCmdFile) || !File.Exists(steamCmdFile))
                {
                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ***********************************");
                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ERROR: SteamCMD could not be found. Expected location is {steamCmdFile}");
                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ***********************************");
                    return(false);
                }

                // record the start time of the process, this is used to determine if any files changed in the download process.
                var startTime = DateTime.Now;

                var gotNewVersion      = false;
                var downloadSuccessful = false;
                var success            = false;

                if (updateServer)
                {
                    // *********************
                    // Server Update Section
                    // *********************

                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Starting server update.");

                    // Check if this is a new server installation.
                    if (isNewInstallation)
                    {
                        // check if the auto-update facility is enabled and the cache folder defined.
                        if (!this.ProfileSnapshot.SotFServer && Config.Default.AutoUpdate_EnableUpdate && !string.IsNullOrWhiteSpace(Config.Default.AutoUpdate_CacheDir) && Directory.Exists(Config.Default.AutoUpdate_CacheDir))
                        {
                            // Auto-Update enabled and cache foldler exists.
                            progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Installing server from local cache...may take a while to copy all the files.");

                            // Install the server files from the cache.
                            var installationFolder = this.ProfileSnapshot.InstallDirectory;
                            int count = 0;
                            await Task.Run(() =>
                                           ServerApp.DirectoryCopy(Config.Default.AutoUpdate_CacheDir, installationFolder, true, Config.Default.AutoUpdate_UseSmartCopy, (p, m, n) =>
                            {
                                count++;
                                progressCallback?.Invoke(0, ".", count % DIRECTORIES_PER_LINE == 0);
                            }), cancellationToken);
                        }
                    }

                    progressCallback?.Invoke(0, "\r\n");
                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Updating server from steam.\r\n");

                    downloadSuccessful = !Config.Default.SteamCmdRedirectOutput;
                    DataReceivedEventHandler serverOutputHandler = (s, e) =>
                    {
                        var dataValue = e.Data ?? string.Empty;
                        progressCallback?.Invoke(0, dataValue);
                        if (!gotNewVersion && dataValue.Contains("downloading,"))
                        {
                            gotNewVersion = true;
                        }
                        if (dataValue.StartsWith("Success!"))
                        {
                            downloadSuccessful = true;
                        }
                    };

                    var steamCmdInstallServerArgsFormat = this.ProfileSnapshot.SotFServer ? Config.Default.SteamCmdInstallServerArgsFormat_SotF : Config.Default.SteamCmdInstallServerArgsFormat;
                    var steamCmdArgs = String.Format(steamCmdInstallServerArgsFormat, this.ProfileSnapshot.InstallDirectory, validate ? "validate" : string.Empty);

                    success = await ServerUpdater.UpgradeServerAsync(steamCmdFile, steamCmdArgs, this.ProfileSnapshot.InstallDirectory, Config.Default.SteamCmdRedirectOutput?serverOutputHandler : null, cancellationToken);

                    if (success && downloadSuccessful)
                    {
                        progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Finished server update.");

                        if (Directory.Exists(this.ProfileSnapshot.InstallDirectory))
                        {
                            if (!Config.Default.SteamCmdRedirectOutput)
                            {
                                // check if any of the server files have changed.
                                gotNewVersion = ServerApp.HasNewServerVersion(this.ProfileSnapshot.InstallDirectory, startTime);
                            }

                            progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} New server version - {gotNewVersion.ToString().ToUpperInvariant()}.");
                        }

                        progressCallback?.Invoke(0, "\r\n");
                    }
                    else
                    {
                        success = false;
                        progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ****************************");
                        progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ERROR: Failed server update.");
                        progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ****************************\r\n");

                        if (Config.Default.SteamCmdRedirectOutput)
                        {
                            progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} If the server update keeps failing try disabling the '{_globalizer.GetResourceString("GlobalSettings_SteamCmdRedirectOutputLabel")}' option in the settings window.\r\n");
                        }
                    }
                }
                else
                {
                    success = true;
                }

                if (success)
                {
                    if (updateMods)
                    {
                        // ******************
                        // Mod Update Section
                        // ******************

                        // build a list of mods to be processed
                        var modIdList = new List <string>();
                        if (!string.IsNullOrWhiteSpace(this.ProfileSnapshot.ServerMapModId))
                        {
                            modIdList.Add(this.ProfileSnapshot.ServerMapModId);
                        }
                        if (!string.IsNullOrWhiteSpace(this.ProfileSnapshot.TotalConversionModId))
                        {
                            modIdList.Add(this.ProfileSnapshot.TotalConversionModId);
                        }
                        modIdList.AddRange(this.ProfileSnapshot.ServerModIds);

                        modIdList = ModUtils.ValidateModList(modIdList);

                        // get the details of the mods to be processed.
                        var modDetails = SteamUtils.GetSteamModDetails(modIdList);
                        if (modDetails != null)
                        {
                            // create a new list for any failed mod updates
                            var failedMods = new List <string>(modIdList.Count);

                            for (var index = 0; index < modIdList.Count; index++)
                            {
                                var modId      = modIdList[index];
                                var modTitle   = modId;
                                var modSuccess = false;
                                gotNewVersion      = false;
                                downloadSuccessful = false;

                                progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Started processing mod {index + 1} of {modIdList.Count}.");
                                progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Mod {modId}.");

                                // check if the steam information was downloaded
                                var modDetail = modDetails.publishedfiledetails?.FirstOrDefault(m => m.publishedfileid.Equals(modId, StringComparison.OrdinalIgnoreCase));
                                if (modDetail != null)
                                {
                                    modTitle = $"{modDetail.title} ({modId})";
                                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} {modDetail.title ?? string.Empty}.\r\n");

                                    var modCachePath  = ModUtils.GetModCachePath(modId, this.ProfileSnapshot.SotFServer);
                                    var cacheTimeFile = ModUtils.GetLatestModCacheTimeFile(modId, this.ProfileSnapshot.SotFServer);
                                    var modPath       = ModUtils.GetModPath(this.ProfileSnapshot.InstallDirectory, modId);
                                    var modTimeFile   = ModUtils.GetLatestModTimeFile(this.ProfileSnapshot.InstallDirectory, modId);

                                    var modCacheLastUpdated = 0;
                                    var downloadMod         = true;
                                    var copyMod             = true;

                                    if (downloadMod)
                                    {
                                        // check if the mod needs to be downloaded, or force the download.
                                        if (Config.Default.ServerUpdate_ForceUpdateMods)
                                        {
                                            progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Forcing mod download - ASM setting is TRUE.");
                                        }
                                        else
                                        {
                                            // check if the mod detail record is valid (private mod).
                                            if (modDetail.time_updated <= 0)
                                            {
                                                progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Forcing mod download - mod is private.");
                                            }
                                            else
                                            {
                                                modCacheLastUpdated = ModUtils.GetModLatestTime(cacheTimeFile);
                                                if (modCacheLastUpdated <= 0)
                                                {
                                                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Forcing mod download - mod cache is not versioned.");
                                                }
                                                else
                                                {
                                                    var steamLastUpdated = modDetail.time_updated;
                                                    if (steamLastUpdated <= modCacheLastUpdated)
                                                    {
                                                        progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Skipping mod download - mod cache has the latest version.");
                                                        downloadMod = false;
                                                    }
                                                }
                                            }
                                        }

                                        if (downloadMod)
                                        {
                                            // mod will be downloaded
                                            downloadSuccessful = !Config.Default.SteamCmdRedirectOutput;
                                            DataReceivedEventHandler modOutputHandler = (s, e) =>
                                            {
                                                var dataValue = e.Data ?? string.Empty;
                                                progressCallback?.Invoke(0, dataValue);
                                                if (dataValue.StartsWith("Success."))
                                                {
                                                    downloadSuccessful = true;
                                                }
                                            };

                                            progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Starting mod download.\r\n");

                                            var steamCmdArgs = string.Empty;
                                            if (this.ProfileSnapshot.SotFServer)
                                            {
                                                if (Config.Default.SteamCmd_UseAnonymousCredentials)
                                                {
                                                    steamCmdArgs = string.Format(Config.Default.SteamCmdInstallModArgsFormat_SotF, Config.Default.SteamCmd_AnonymousUsername, modId);
                                                }
                                                else
                                                {
                                                    steamCmdArgs = string.Format(Config.Default.SteamCmdInstallModArgsFormat_SotF, Config.Default.SteamCmd_Username, modId);
                                                }
                                            }
                                            else
                                            {
                                                if (Config.Default.SteamCmd_UseAnonymousCredentials)
                                                {
                                                    steamCmdArgs = string.Format(Config.Default.SteamCmdInstallModArgsFormat, Config.Default.SteamCmd_AnonymousUsername, modId);
                                                }
                                                else
                                                {
                                                    steamCmdArgs = string.Format(Config.Default.SteamCmdInstallModArgsFormat, Config.Default.SteamCmd_Username, modId);
                                                }
                                            }

                                            modSuccess = await ServerUpdater.UpgradeModsAsync(steamCmdFile, steamCmdArgs, Config.Default.SteamCmdRedirectOutput?modOutputHandler : null, cancellationToken);

                                            if (modSuccess && downloadSuccessful)
                                            {
                                                progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Finished mod download.");
                                                copyMod = true;

                                                if (Directory.Exists(modCachePath))
                                                {
                                                    // check if any of the mod files have changed.
                                                    gotNewVersion = new DirectoryInfo(modCachePath).GetFiles("*.*", SearchOption.AllDirectories).Any(file => file.LastWriteTime >= startTime);

                                                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} New mod version - {gotNewVersion.ToString().ToUpperInvariant()}.");

                                                    var steamLastUpdated = modDetail.time_updated.ToString();
                                                    if (modDetail.time_updated <= 0)
                                                    {
                                                        // get the version number from the steamcmd workshop file.
                                                        steamLastUpdated = ModUtils.GetSteamWorkshopLatestTime(ModUtils.GetSteamWorkshopFile(this.ProfileSnapshot.SotFServer), modId).ToString();
                                                    }

                                                    // update the last updated file with the steam updated time.
                                                    File.WriteAllText(cacheTimeFile, steamLastUpdated);

                                                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Mod Cache version: {steamLastUpdated}\r\n");
                                                }
                                            }
                                            else
                                            {
                                                modSuccess = false;
                                                progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ***************************");
                                                progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ERROR: Mod download failed.");
                                                progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ***************************\r\n");

                                                if (Config.Default.SteamCmdRedirectOutput)
                                                {
                                                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} If the mod update keeps failing try disabling the '{_globalizer.GetResourceString("GlobalSettings_SteamCmdRedirectOutputLabel")}' option in the settings window.\r\n");
                                                }
                                                copyMod = false;
                                            }
                                        }
                                        else
                                        {
                                            modSuccess = true;
                                        }
                                    }
                                    else
                                    {
                                        modSuccess = true;
                                    }

                                    if (copyMod)
                                    {
                                        // check if the mod needs to be copied, or force the copy.
                                        if (Config.Default.ServerUpdate_ForceCopyMods)
                                        {
                                            progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Forcing mod copy - ASM setting is TRUE.");
                                        }
                                        else
                                        {
                                            // check the mod version against the cache version.
                                            var modLastUpdated = ModUtils.GetModLatestTime(modTimeFile);
                                            if (modLastUpdated <= 0)
                                            {
                                                progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Forcing mod copy - mod is not versioned.");
                                            }
                                            else
                                            {
                                                modCacheLastUpdated = ModUtils.GetModLatestTime(cacheTimeFile);
                                                if (modCacheLastUpdated <= modLastUpdated)
                                                {
                                                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Skipping mod copy - mod has the latest version.");
                                                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Mod version: {modLastUpdated}");
                                                    copyMod = false;
                                                }
                                            }
                                        }

                                        if (copyMod)
                                        {
                                            try
                                            {
                                                if (Directory.Exists(modCachePath))
                                                {
                                                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Started mod copy.");
                                                    int count = 0;
                                                    await Task.Run(() => ModUtils.CopyMod(modCachePath, modPath, modId, (p, m, n) =>
                                                    {
                                                        count++;
                                                        progressCallback?.Invoke(0, ".", count % DIRECTORIES_PER_LINE == 0);
                                                    }), cancellationToken);

                                                    progressCallback?.Invoke(0, "\r\n");
                                                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Finished mod copy.");

                                                    var modLastUpdated = ModUtils.GetModLatestTime(modTimeFile);
                                                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Mod version: {modLastUpdated}");
                                                }
                                                else
                                                {
                                                    modSuccess = false;
                                                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ****************************************************");
                                                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ERROR: Mod cache was not found, mod was not updated.");
                                                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ****************************************************");
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                modSuccess = false;
                                                progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ***********************");
                                                progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ERROR: Failed mod copy.\r\n{ex.Message}");
                                                progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ***********************");
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    // no steam information downloaded, display an error, mod might no longer be available
                                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} *******************************************************************");
                                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ERROR: Mod cannot be updated, unable to download steam information.");
                                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} *******************************************************************");
                                }

                                if (!modSuccess)
                                {
                                    success = false;
                                    failedMods.Add($"{index + 1} of {modIdList.Count} - {modTitle}");
                                }

                                progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Finished processing mod {modId}.\r\n");
                            }

                            if (failedMods.Count > 0)
                            {
                                progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} **************************************************************************");
                                progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ERROR: The following mods failed the update, check above for more details.");
                                foreach (var failedMod in failedMods)
                                {
                                    progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} {failedMod}");
                                }
                                progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} **************************************************************************\r\n");
                            }
                        }
                        else
                        {
                            success = false;
                            // no steam information downloaded, display an error
                            progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ********************************************************************");
                            progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ERROR: Mods cannot be updated, unable to download steam information.");
                            progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ********************************************************************\r\n");
                        }
                    }
                }
                else
                {
                    if (updateServer && updateMods)
                    {
                        progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ***********************************************************");
                        progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ERROR: Mods were not processed as server update had errors.");
                        progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} ***********************************************************\r\n");
                    }
                }

                progressCallback?.Invoke(0, $"{Updater.OUTPUT_PREFIX} Finished upgrade process.");
                return(success);
            }
            catch (TaskCanceledException)
            {
                return(false);
            }
            finally
            {
                this.Status = ServerStatus.Stopped;
            }
        }
Ejemplo n.º 5
0
        private static void RunUpdate(bool noDelay)
        {
            var endpoint = new IPEndPoint(IPAddress.Parse(ServerIP), RCONPort);

            server = ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endpoint);

            //
            // Find the process
            //
            var     runningProcesses = Process.GetProcessesByName("ShooterGameServer.exe");
            var     expectedExePath  = ServerUpdater.NormalizePath(Path.Combine(InstallDirectory, "ShooterGame", "Binaries", "Win64", "ShooterGameServer.exe"));
            Process process          = null;

            foreach (var runningProcess in runningProcesses)
            {
                var runningPath = ServerUpdater.NormalizePath(runningProcess.Modules[0].FileName);
                if (String.Equals(expectedExePath, runningPath))
                {
                    process = runningProcess;
                    break;
                }
            }

            if (process == null)
            {
                Console.WriteLine("ERROR: Unable to find process for " + InstallDirectory);
                Environment.Exit(-1);
            }

            var serverCommandLine = ServerUpdater.GetCommandLineForProcess(process.Id);

            if (String.IsNullOrEmpty(serverCommandLine))
            {
                Console.WriteLine("ERROR: Unable to retrieve command-line for process " + process.Id);
                Environment.Exit(-1);
            }

            //
            // Stop the server
            //
            Console.WriteLine("Stopping the server...");
            process.EnableRaisingEvents = true;
            if (process.ProcessName == "ShooterGameServer.exe")
            {
                TaskCompletionSource <bool> ts = new TaskCompletionSource <bool>();
                EventHandler handler           = (s, e) => ts.TrySetResult(true);
                process.Exited += handler;
                process.CloseMainWindow();
                if (!process.HasExited)
                {
                    ts.Task.Wait();
                }
            }

            if (!UpdateCache())
            {
                Environment.Exit(-1);
            }

            Console.WriteLine("Re-launching the server");
            process = Process.Start(serverCommandLine);
            if (process == null)
            {
                Console.WriteLine("Failed to restart server.");
                Environment.Exit(-1);
            }

            //
            // Re-schedule updater
            //
            Console.WriteLine("TODO: Reschedule update");

            Environment.Exit(0);
        }