Update in-place instead of using Updater.exe

This commit is contained in:
UnknownShadow200 2021-01-18 18:27:39 +11:00
parent 7dbfb5c074
commit b1d7825237
7 changed files with 13 additions and 299 deletions

View File

@ -8,8 +8,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MCGalaxyGUI", "GUI\MCGalaxy
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MCGalaxy_", "MCGalaxy\MCGalaxy_.csproj", "{12597DB0-7C34-4DE1-88EA-9250FF3372EB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Updater", "updater\Updater.csproj", "{1C317052-9B87-471C-A8AF-5AB2D779C174}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MCGalaxyCLI", "CLI\MCGalaxyCLI.csproj", "{A1A5B886-2D0A-4D2A-AE13-409560D5227C}"
EndProject
Global
@ -26,10 +24,6 @@ Global
{12597DB0-7C34-4DE1-88EA-9250FF3372EB}.Debug|x86.Build.0 = Debug|x86
{12597DB0-7C34-4DE1-88EA-9250FF3372EB}.Release|x86.ActiveCfg = Release|x86
{12597DB0-7C34-4DE1-88EA-9250FF3372EB}.Release|x86.Build.0 = Release|x86
{1C317052-9B87-471C-A8AF-5AB2D779C174}.Debug|x86.ActiveCfg = Debug|x86
{1C317052-9B87-471C-A8AF-5AB2D779C174}.Debug|x86.Build.0 = Debug|x86
{1C317052-9B87-471C-A8AF-5AB2D779C174}.Release|x86.ActiveCfg = Release|x86
{1C317052-9B87-471C-A8AF-5AB2D779C174}.Release|x86.Build.0 = Release|x86
{A1A5B886-2D0A-4D2A-AE13-409560D5227C}.Debug|x86.Build.0 = Debug|x86
{A1A5B886-2D0A-4D2A-AE13-409560D5227C}.Debug|x86.ActiveCfg = Debug|x86
{A1A5B886-2D0A-4D2A-AE13-409560D5227C}.Release|x86.Build.0 = Release|x86

View File

@ -71,7 +71,8 @@ namespace MCGalaxy {
public static void PerformUpdate() {
try {
try {
DeleteFiles("Changelog.txt", "MCGalaxy_.update", "MCGalaxy.update", "MCGalaxyCLI.update");
DeleteFiles("Changelog.txt", "MCGalaxy_.update", "MCGalaxy.update", "MCGalaxyCLI.update",
"prev_MCGalaxy_.dll", "prev_MCGalaxy.exe", "prev_MCGalaxyCLI.exe");
} catch {
}
@ -91,20 +92,18 @@ namespace MCGalaxy {
Player[] players = PlayerInfo.Online.Items;
foreach (Player pl in players) pl.save();
// Although Process.Start checks path exists, that won't work correctly when running from mono
// (since 'mono' exists but Updater.exe might not)
// So always explicitly check that Updater.exe exists here
string path = Path.Combine(Utils.FolderPath, "Updater.exe");
if (!File.Exists(path)) throw new FileNotFoundException("Unable to find " + path);
// Move current files to previous files (by moving instead of copying,
// can overwrite original the files without breaking the server)
File.Move("MCGalaxy_.dll", "prev_MCGalaxy_.dll");
File.Move("MCGalaxy.exe", "prev_MCGalaxy.exe");
File.Move("MCGalaxyCLI.exe", "prev_MCGalaxyCLI.exe");
try {
Process.Start(path, "securitycheck10934579068013978427893755755270374" + exeName);
} catch {
if (Type.GetType("Mono.Runtime") == null) throw;
// if running on mono, try again with 'mono /home/user1/MCG/MCGalaxyCLI.exe' instead
Process.Start("mono", path + " securitycheck10934579068013978427893755755270374" + exeName);
}
Server.Stop(false, "Updating server.");
// Move update files to current files
File.Move("MCGalaxy_.update", "MCGalaxy_.dll");
File.Move("MCGalaxy.update", "MCGalaxy.exe");
File.Move("MCGalaxyCLI.update", "MCGalaxyCLI.exe");
Server.Stop(true, "Updating server.");
} catch (Exception ex) {
Logger.LogError("Error performing update", ex);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -1,142 +0,0 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Windows.Forms;
namespace Updater {
// !! NOTE !!! You must not use any MCGalaxy code here, as you cannot reference the dlls because updating replaces thems
class Program {
static int tries = 0;
static bool usingConsole = false;
const string check = "securitycheck10934579068013978427893755755270374";
static void Main(string[] args) {
AppDomain.CurrentDomain.UnhandledException += UnhandledError;
usingConsole = IsConsole();
if (args.Length < 1 || !args[0].Contains(check)) {
ShowMessage("Updater was started incorrectly.", true); return;
}
try {
args[0] = args[0].Replace(check, "");
if (args[0] == ".exe") args[0] = "MCGalaxy.exe";
// Wait for other processes to finish
Console.WriteLine("Waiting for " + args[0] + " to exit...");
while (Process.GetProcessesByName(args[0]).Length > 0) {
Thread.Sleep(1);
}
} catch (Exception e) {
UpdateFailed(e);
}
Update(args);
}
static bool IsConsole() {
try {
string[] lines = File.ReadAllLines("Viewmode.cfg");
foreach (string line in lines) {
// Find the cli = true/false line
if (!line.StartsWith("cli")) continue;
int sep = line.IndexOf('=');
if (sep == -1) continue;
string value = line.Substring(sep + 1).Trim();
return value.Equals("true", StringComparison.OrdinalIgnoreCase);
}
} catch {
}
return false;
}
static void Update(string[] args) {
Console.WriteLine("Updating MCGalaxy...");
// No files to update
if (!File.Exists("MCGalaxy.update") && !File.Exists("MCGalaxy_.update")) {
ShowMessage("Updater has no files to update", true); return;
}
for (tries = 1; tries <= 3; tries++) {
if (!UpdateFile("MCGalaxy", ".exe")) continue;
if (!UpdateFile("MCGalaxy_", ".dll")) continue;
if (!UpdateFile("MCGalaxyCLI", ".exe")) continue;
TryStartProcess(args[0]);
return;
}
}
static bool UpdateFile(string name, string ext) {
if (!File.Exists(name + ".update")) return true;
try {
if (File.Exists(name + ext)) {
if (File.Exists(name + ".backup"))
File.Delete(name + ".backup");
File.Move(name + ext, name + ".backup");
}
File.Move(name + ".update", name + ext);
return true;
} catch (Exception ex) {
Retry(ex);
return false;
}
}
static void Retry(Exception ex) {
if (tries == 3) {
UpdateFailed(ex);
} else {
Console.WriteLine("\n\nAn error occured while updating. Retrying...\n\n");
Thread.Sleep(100);
}
}
static void StartProcess(string file) {
try {
Process.Start(file);
} catch {
if (Type.GetType("Mono.Runtime") == null) throw;
// if running on mono, try again with 'mono /home/user1/MCG/MCGalaxyCLI.exe' instead
string absolutePath = AppDomain.CurrentDomain.BaseDirectory;
Process.Start("mono", Path.Combine(absolutePath, file));
}
}
static void TryStartProcess(string file) {
Console.WriteLine("Successfully updated MCGalaxy. Starting...");
try {
StartProcess(file);
} catch (Exception) {
ShowMessage("Updater has updated MCGalaxy, but was unable to start it. You will need to start it manually.", false);
}
}
static void UpdateFailed(Exception e) {
ShowMessage("Updater failed to update MCGalaxy:\n\n" + e, true);
}
static void UnhandledError(object sender, UnhandledExceptionEventArgs args) {
Exception e = (Exception)args.ExceptionObject;
ShowMessage("UnhandledException:\n\n" + e, true);
}
static void ShowMessage(string message, bool error) {
if (usingConsole) {
Console.WriteLine(message);
} else {
string title = error ? "Updater Error" : "Updater";
MessageBoxIcon icon = error ? MessageBoxIcon.Error : MessageBoxIcon.Information;
MessageBox.Show(message, title, MessageBoxButtons.OK, icon);
}
if (error) Environment.Exit(0);
}
}
}

View File

@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
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("Updater")]
[assembly: AssemblyDescription("Simple updater for MCGalaxy")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Updater")]
[assembly: AssemblyCopyright("Copyright © 2011")]
[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("a0c78baf-3bac-45d1-bc11-fda489845e08")]
// 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.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -1,98 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{1C317052-9B87-471C-A8AF-5AB2D779C174}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Updater</RootNamespace>
<AssemblyName>Updater</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<NoWin32Manifest>False</NoWin32Manifest>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\bin\Debug\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<StartupObject>Updater.Program</StartupObject>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Galaxy.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<ItemGroup>
<Content Include="Galaxy.ico" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" /></startup></configuration>