This repository has been archived on 2026-01-20. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Installer-Launcher/Launcher_App/ProgramLauncher/Form1.cs
jmaniuvc f0b7dfd413 main
2025-05-15 11:44:27 +09:00

196 lines
6.6 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Deployment.Application;
using System.Diagnostics;
using System.Drawing;
using Newtonsoft.Json;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Http;
namespace ProgramLauncher
{
public partial class Form1 : Form
{
static string downloadServerUrl = "http://xr.flexing.ai:3030/XR_Server";
static string downloadFolderName = "Build";
static string jsonFileName = "file_list.json";
static string localVersionID = "versionID.txt";
static readonly HttpClient httpClient = new HttpClient();
public Form1()
{
downloadServerUrl = CombineUrl(downloadServerUrl, Program.projectName);
InitializeComponent();
}
private async void Form1_Load(object sender, EventArgs e)
{
Label_UpdateFileName.Text = string.Empty;
await CheckUpdate();
}
private async Task CheckUpdate()
{
var serverFileList = await GetServerFileList(downloadServerUrl);
if (serverFileList == null) return;
string latestVersionID = serverFileList.VersionID;
string localVersionID = GetLocalVersion();
if (latestVersionID != localVersionID)
{
Label_ProgressState.Text = "업데이트 중...";
foreach (var file in serverFileList.Files)
{
string localFilePath = Path.Combine(downloadFolderName, file.Key);
string serverHash = file.Value;
if (!File.Exists(localFilePath) || GetFileHash(localFilePath) != serverHash)
{
Label_UpdateFileName.Text = localFilePath;
string downloadFolder = CombineUrl(downloadServerUrl, downloadFolderName);
await DownloadFile(Path.Combine(downloadFolder, file.Key), localFilePath);
}
}
var serverFilePaths = new HashSet<string>(
serverFileList.Files.Keys.Select(file => file.Replace('\\', '/')) // 서버의 파일 경로를 통일
);
foreach (string localFile in Directory.GetFiles(downloadFolderName, "*", SearchOption.AllDirectories))
{
// 현재 파일의 상대 경로를 구함 (localFolder 기준)
string relativePath = localFile.Substring(downloadFolderName.Length + 1).Replace('\\', '/');
if (!serverFilePaths.Contains(relativePath))
{
File.Delete(localFile);
}
}
SaveLocalVersion(latestVersionID);
}
StartExecutableFile(downloadFolderName);
this.Close();
}
static async Task<ServerFileList> GetServerFileList(string serverUrl)
{
using (WebClient client = new WebClient())
{
try
{
string serverJsonUrl = CombineUrl(serverUrl, jsonFileName);
string json = await client.DownloadStringTaskAsync(serverJsonUrl);
return JsonConvert.DeserializeObject<ServerFileList>(json);
}
catch (Exception ex)
{
return null;
}
}
}
static string GetLocalVersion()
{
return File.Exists(localVersionID) ? File.ReadAllText(localVersionID).Trim() : "";
}
static void SaveLocalVersion(string version)
{
File.WriteAllText(localVersionID, version);
}
static string GetFileHash(string filePath)
{
using (var sha256 = SHA256.Create())
using (var stream = File.OpenRead(filePath))
{
byte[] hash = sha256.ComputeHash(stream);
return BitConverter.ToString(hash).Replace("-", "").ToLower();
}
}
/*
static async Task DownloadFile(string url, string outputPath)
{
try
{
using (WebClient client = new WebClient())
{
Directory.CreateDirectory(Path.GetDirectoryName(outputPath) ?? "");
await client.DownloadFileTaskAsync(new Uri(url), outputPath);
}
}
catch (Exception ex)
{
return;
}
}
*/
static async Task DownloadFile(string url, string outputPath)
{
try
{
Directory.CreateDirectory(Path.GetDirectoryName(outputPath) ?? "");
using (var response = await httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
{
response.EnsureSuccessStatusCode(); // 200 OK가 아닐 경우 예외 발생
using (var stream = await response.Content.ReadAsStreamAsync())
using (var fileStream = new FileStream(outputPath, FileMode.Create, FileAccess.Write, FileShare.None))
{
await stream.CopyToAsync(fileStream);
}
}
}
catch (Exception ex)
{
}
}
static void StartExecutableFile(string executeFolder)
{
string[] exeFiles = Directory.GetFiles(executeFolder, "*.exe", SearchOption.TopDirectoryOnly);
if (exeFiles.Length == 0)
{
return;
}
string executeFilePath = exeFiles.FirstOrDefault(file => !file.EndsWith("UnityCrashHandler64.exe", StringComparison.OrdinalIgnoreCase));
string executeFileName = Path.GetFileName(executeFilePath);
Process process = new Process();
process.StartInfo.UseShellExecute = true;
process.StartInfo.WorkingDirectory = executeFolder;
process.StartInfo.FileName = executeFileName;
process.Start();
}
static string CombineUrl(string baseUrl, string relativePath)
{
return $"{baseUrl.TrimEnd('/')}/{relativePath.TrimStart('/')}";
}
}
class ServerFileList
{
public string VersionID { get; set; } = "";
public Dictionary<string, string> Files { get; set; } = new Dictionary<string, string>();
}
}