mirror of
https://github.com/netchx/netch.git
synced 2026-03-18 18:13:21 +08:00
289 lines
9.5 KiB
C#
289 lines
9.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net.Sockets;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using NetchUpdater.Properties;
|
|
|
|
namespace NetchUpdater
|
|
{
|
|
internal class Program
|
|
{
|
|
static string UpdaterFullName;
|
|
static string UpdaterDirectory;
|
|
static string UpdaterFriendlyName;
|
|
static Process CurrentProcess;
|
|
|
|
static Program()
|
|
{
|
|
CurrentProcess = Process.GetCurrentProcess();
|
|
UpdaterFullName = CurrentProcess.MainModule.FileName;
|
|
UpdaterDirectory = Path.GetDirectoryName(UpdaterFullName);
|
|
UpdaterFriendlyName = Path.GetFileName(UpdaterFullName);
|
|
}
|
|
|
|
public static void Main(string[] args)
|
|
{
|
|
var result = false;
|
|
|
|
try
|
|
{
|
|
#region Check Arguments
|
|
|
|
if (CurrentProcess.MainModule == null)
|
|
{
|
|
Console.WriteLine("Current Process MainModule is null");
|
|
return;
|
|
}
|
|
|
|
if (args.Length != 3)
|
|
{
|
|
Console.WriteLine("The program is not user-oriented\n此程序不是面向用户的");
|
|
return;
|
|
}
|
|
|
|
// arg0 port
|
|
if (!int.TryParse(args[0], out var port))
|
|
{
|
|
Console.WriteLine("arg0 Port Parse failed");
|
|
return;
|
|
}
|
|
|
|
var updateExtracted = true;
|
|
// arg1 update File/Directory
|
|
var updatePath = Path.GetFullPath(args[1]);
|
|
if (File.Exists(updatePath))
|
|
{
|
|
updateExtracted = false;
|
|
}
|
|
else if (!Directory.Exists(updatePath))
|
|
{
|
|
Console.WriteLine("arg1 update file/directory Not found");
|
|
return;
|
|
}
|
|
|
|
// arg2 target Directory
|
|
string targetPath;
|
|
if (!File.Exists(Path.Combine(targetPath = Path.GetFullPath(args[2]), "Netch.exe")))
|
|
{
|
|
Console.Write("arg2 Netch Directory doesn't seems right");
|
|
return;
|
|
}
|
|
|
|
#region if under target Directory,then rerun in temp directory
|
|
|
|
if (UpdaterDirectory.StartsWith(targetPath))
|
|
{
|
|
// Updater 在目标目录下
|
|
// 将程序复制到临时目录,传递参数
|
|
var tempPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
|
|
var newUpdaterPath = Path.Combine(tempPath, UpdaterFriendlyName);
|
|
Directory.CreateDirectory(tempPath);
|
|
File.Copy(UpdaterFullName, newUpdaterPath);
|
|
Process.Start(new ProcessStartInfo
|
|
{
|
|
FileName = newUpdaterPath,
|
|
Arguments = $"{port} {updatePath} {targetPath}",
|
|
WorkingDirectory = tempPath,
|
|
UseShellExecute = false
|
|
});
|
|
result = true;
|
|
return;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
/*while (!Debugger.IsAttached)
|
|
{
|
|
Console.WriteLine("Waiting Attach");
|
|
Thread.Sleep(1000);
|
|
}*/
|
|
|
|
#region Send Netch Exit command
|
|
|
|
Process[] _;
|
|
if ((_ = Process.GetProcessesByName("Netch")).Any())
|
|
{
|
|
Console.WriteLine("Found Netch process, Send exit command");
|
|
try
|
|
{
|
|
var udpClient = new UdpClient("127.0.0.1", port);
|
|
var sendBytes = Encoding.ASCII.GetBytes("Exit");
|
|
udpClient.Send(sendBytes, sendBytes.Length);
|
|
}
|
|
catch
|
|
{
|
|
Console.WriteLine("Send command failed");
|
|
return;
|
|
}
|
|
|
|
foreach (var proc in _)
|
|
{
|
|
try
|
|
{
|
|
proc.WaitForExit();
|
|
}
|
|
catch (Exception)
|
|
{
|
|
// ignored
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
var counter = 0;
|
|
while (!TestFileFree(Path.Combine(targetPath, "Netch.exe")))
|
|
{
|
|
// wait 5 sec
|
|
if (counter > 25)
|
|
{
|
|
Console.WriteLine("Waiting Netch exit timeout");
|
|
return;
|
|
}
|
|
|
|
Thread.Sleep(200);
|
|
counter++;
|
|
}
|
|
|
|
#region Update
|
|
|
|
if (!updateExtracted)
|
|
Extract(updatePath, targetPath, true);
|
|
else
|
|
MoveDirectory(updatePath, targetPath, true);
|
|
|
|
#endregion
|
|
|
|
#region Finished Update,Start Netch
|
|
|
|
Console.WriteLine("Start Netch");
|
|
Process.Start(new ProcessStartInfo
|
|
{
|
|
FileName = Path.Combine(targetPath, "Netch.exe"),
|
|
UseShellExecute = true,
|
|
});
|
|
|
|
#endregion
|
|
|
|
result = true;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
if (e is InvalidDataException)
|
|
Console.WriteLine("Archive file Broken");
|
|
Console.WriteLine(e.ToString());
|
|
}
|
|
finally
|
|
{
|
|
if (!result)
|
|
{
|
|
Console.WriteLine("Press any key to exit...");
|
|
Console.Read();
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void Extract(string archiveFileName, string destDirName, bool overwrite)
|
|
{
|
|
archiveFileName = Path.GetFullPath(archiveFileName);
|
|
destDirName = Path.GetFullPath(destDirName);
|
|
|
|
if (!File.Exists("7za.exe"))
|
|
File.WriteAllBytes("7za.exe", Resources._7za);
|
|
|
|
var argument = new StringBuilder();
|
|
argument.Append($" x {archiveFileName} -o{destDirName} ");
|
|
if (overwrite)
|
|
argument.Append(" -y ");
|
|
|
|
Process.Start(new ProcessStartInfo
|
|
{
|
|
UseShellExecute = false,
|
|
WindowStyle = ProcessWindowStyle.Hidden,
|
|
FileName = Path.GetFullPath("7za.exe"),
|
|
Arguments = argument.ToString()
|
|
})?.WaitForExit();
|
|
}
|
|
|
|
private static void MoveDirectory(string sourceDirName, string destDirName, bool overwrite)
|
|
{
|
|
sourceDirName = Path.GetFullPath(sourceDirName);
|
|
destDirName = Path.GetFullPath(destDirName);
|
|
if (!overwrite)
|
|
{
|
|
Directory.Move(sourceDirName, destDirName);
|
|
}
|
|
else
|
|
{
|
|
var DirStack = new Stack<string>();
|
|
DirStack.Push(sourceDirName);
|
|
|
|
while (DirStack.Count > 0)
|
|
{
|
|
var DirInfo = new DirectoryInfo(DirStack.Pop());
|
|
try
|
|
{
|
|
foreach (var DirChildInfo in DirInfo.GetDirectories())
|
|
{
|
|
try
|
|
{
|
|
var destPath = DirChildInfo.ToString().Replace(sourceDirName, destDirName);
|
|
if (!Directory.Exists(destPath))
|
|
{
|
|
Directory.CreateDirectory(destPath);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine($"Create {DirChildInfo} Folder Error: {e.Message}");
|
|
}
|
|
|
|
DirStack.Push(DirChildInfo.FullName);
|
|
}
|
|
|
|
foreach (var FileChildInfo in DirInfo.GetFiles())
|
|
{
|
|
try
|
|
{
|
|
var destPath = FileChildInfo.ToString().Replace(sourceDirName, destDirName);
|
|
if (File.Exists(destPath))
|
|
{
|
|
File.Delete(destPath);
|
|
}
|
|
|
|
FileChildInfo.MoveTo(destDirName);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine($"Move {FileChildInfo} Error: {e.Message}");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine($"ERROR:{e.Message}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static bool TestFileFree(string FileName)
|
|
{
|
|
try
|
|
{
|
|
File.Move(FileName, FileName);
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
} |