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
2025-05-19 17:10:14 +09:00

304 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using Newtonsoft.Json;
using System.Security.Cryptography;
using System.Net.Http;
using Microsoft.Win32;
using System.Security.Policy;
using System.Runtime.InteropServices;
namespace StudioClient
{
public partial class Form1 : Form
{
static string serverUrl = "http://xr.flexing.ai:3030/XR_Server/";
static string appName_Studio = "Studio";
static string appName_StudioTwin = "StudioTwin";
static string appName_StudioSimulator = "StudioSimulator";
static string setupFileTag = "Setup.exe";
static readonly HttpClient httpClient = new HttpClient();
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern uint RegisterWindowMessage(string lpString);
private uint installCompleteMsg;
private uint uninstallCompleteMsg;
public Form1()
{
InitializeComponent();
Initialize();
}
void Initialize()
{
installCompleteMsg = RegisterWindowMessage($@"INSTALL_COMPLETE");
uninstallCompleteMsg = RegisterWindowMessage($@"UNINSTALL_COMPLETE");
string installPath;
installPath = GetInstalledPathFromRegistry(appName_Studio);
if (!string.IsNullOrWhiteSpace(installPath) && Directory.Exists(installPath))
{
SetButtonState(true, StudioInstallButton, StudioCheckButton, StudioDeleteButton);
}
else
{
SetButtonState(false, StudioInstallButton, StudioCheckButton, StudioDeleteButton);
}
}
void SetButtonState(bool isInstallComplete, Button installButton, Button checkButton, Button deleteButton)
{
if (isInstallComplete)
{
installButton.Text = "실행";
checkButton.Visible = true;
checkButton.Enabled = true;
deleteButton.Visible = true;
deleteButton.Enabled = true;
}
else
{
installButton.Text = "설치";
checkButton.Visible = false;
checkButton.Enabled = false;
deleteButton.Visible = false;
deleteButton.Enabled = false;
}
}
private async void StudioInstallButton_Click(object sender, EventArgs e)
{
await OnClickButton(appName_Studio);
}
private async void StudioTwinInstallButton_Click(object sender, EventArgs e)
{
//await InstallApp(serverUrl, appName_StudioTwin);
}
private async void StudioSimulatorInstallButton_Click(object sender, EventArgs e)
{
}
private async void StudioCheckButton_Click(object sender, EventArgs e)
{
}
private async void StudioDeleteButton_Click(object sender, EventArgs e)
{
await UninstallApp(appName_Studio);
}
private async void StudioTwinDeleteButton_Click(object sender, EventArgs e)
{
}
private async void StudioSimulatorDeleteButton_Click(object sender, EventArgs e)
{
}
private async void WriteText(string text)
{
label1.Text = text;
}
private async Task OnClickButton(string appName)
{
string appUrl = Path.Combine(serverUrl, appName);
// 이미 Setup으로 설치를 진행했는지 체크
string installPath = GetInstalledPathFromRegistry(appName);
string exeFilePath;
if (!string.IsNullOrWhiteSpace(installPath) && Directory.Exists(installPath)) // 이미 설치 되있으면 경로에서 exe파일 실행
{
WriteText("런처 실행");
exeFilePath = Directory.GetFiles(installPath, "*.exe", SearchOption.TopDirectoryOnly)
.FirstOrDefault(file =>
!Path.GetFileName(file).Equals("unins000.exe", StringComparison.OrdinalIgnoreCase) &&
Path.GetFileName(file).IndexOf("Launcher", StringComparison.OrdinalIgnoreCase) >= 0);
if (string.IsNullOrEmpty(exeFilePath))
{
WriteText("❌ 설치 경로에 실행할 수 있는 런처의 exe 파일이 없습니다.");
return;
}
StartExecutableFile(exeFilePath, installPath);
}
else // 설치 안되있으면 Setup 다운받고 Setup 실행
{
WriteText("설치 진행중");
// Setup 파일이 이미 있으면 삭제하고 서버에서 새로 다운로드
string setupFileName = appName + setupFileTag;
if (File.Exists(setupFileName))
{
File.Delete(setupFileName);
}
string setupFileUrl = Path.Combine(appUrl, setupFileName);
await DownloadFile(setupFileUrl, ProgressBar);
string currentDir = AppContext.BaseDirectory;
exeFilePath = Path.Combine(currentDir, setupFileName);
StartExecutableFile(exeFilePath, currentDir);
}
}
private string GetInstalledPathFromRegistry(string appName)
{
try
{
using (RegistryKey key = Registry.CurrentUser.OpenSubKey($@"Software\UVC\{appName}"))
{
if (key != null)
{
return key.GetValue("InstallPath") as string ?? "";
}
}
}
catch (Exception ex)
{
WriteText($"❌ 레지스트리 읽기 실패 ({appName}): {ex.Message}");
}
return "";
}
private async Task DownloadFile(string url, ProgressBar progressBar)
{
try
{
string currentDir = AppContext.BaseDirectory;
string fileName = Path.GetFileName(new Uri(url).LocalPath);
string fullPath = Path.Combine(currentDir, fileName);
using (var response = await httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
{
response.EnsureSuccessStatusCode();
long? totalBytes = response.Content.Headers.ContentLength;
if (totalBytes == null)
{
WriteText("❌ 파일 크기를 알 수 없습니다.");
return;
}
using (var contentStream = await response.Content.ReadAsStreamAsync())
using (var fileStream = new FileStream(fullPath, FileMode.Create, FileAccess.Write, FileShare.None))
{
progressBar.Invoke((MethodInvoker)(() =>
{
progressBar.Minimum = 0;
progressBar.Maximum = 100;
progressBar.Value = 0;
}));
byte[] buffer = new byte[81920]; // 80KB 버퍼
long totalRead = 0;
int bytesRead;
while ((bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await fileStream.WriteAsync(buffer, 0, bytesRead);
totalRead += bytesRead;
int progress = (int)((totalRead * 100) / totalBytes.Value);
progressBar.Invoke((MethodInvoker)(() =>
{
progressBar.Value = Math.Min(progress, 100);
}));
}
WriteText("✅ 다운로드 완료!");
}
}
}
catch (Exception ex)
{
WriteText($"❌ 다운로드 실패: {ex.Message}");
}
}
private void StartExecutableFile(string exeFilePath, string workingDirectory)
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = exeFilePath,
WorkingDirectory = workingDirectory,
UseShellExecute = true // Windows에서 기본 프로그램으로 실행
};
Process.Start(startInfo);
}
private async Task UninstallApp(string appName)
{
string appUrl = Path.Combine(serverUrl, appName);
// 설치가 이미 되어있는지 체크
string installPath = GetInstalledPathFromRegistry(appName);
string exeFilePath;
if (!string.IsNullOrWhiteSpace(installPath) && Directory.Exists(installPath)) // 설치 되있으면 경로에서 Uninstaller 실행
{
exeFilePath = Directory.GetFiles(installPath, "unins000.exe", SearchOption.TopDirectoryOnly).FirstOrDefault();
if (string.IsNullOrEmpty(exeFilePath))
{
WriteText("❌ 설치 경로에 실행할 수 있는 unins000.exe 파일이 없습니다.");
return;
}
WriteText("Uninstaller 실행");
StartExecutableFile(exeFilePath, installPath);
}
else
{
WriteText("❌ 설치된 경로가 없습니다.");
}
}
// Install / Uninstall 완료 시
protected override void WndProc(ref Message m)
{
if (m.Msg == installCompleteMsg)
{
SetButtonState(true, StudioInstallButton, StudioCheckButton, StudioDeleteButton);
}
else if (m.Msg == uninstallCompleteMsg)
{
SetButtonState(false, StudioInstallButton, StudioCheckButton, StudioDeleteButton);
}
base.WndProc(ref m);
}
}
}