diff --git a/dist/README.txt b/dist/README.txt
index d7d1950..f6c31d3 100644
--- a/dist/README.txt
+++ b/dist/README.txt
@@ -1,5 +1,5 @@
UbisamBase 플랫폼 배포 폴더 (빌드할 때 자동 생성 - 직접 고치지 마세요)
-갱신 시각 : 2026-09-21 21:55:55
+갱신 시각 : 2026-09-21 22:04:42
빌드 구성 : Release
원본 소스 : D:\업무\03_개발\Source\용접기\08_UbisamPlatform\
----
diff --git a/dist/UbisamBase.Core.dll b/dist/UbisamBase.Core.dll
index f857205..735fad7 100644
Binary files a/dist/UbisamBase.Core.dll and b/dist/UbisamBase.Core.dll differ
diff --git a/dist/UbisamBase.Launcher.exe b/dist/UbisamBase.Launcher.exe
index 9022b4b..1cecfa8 100644
Binary files a/dist/UbisamBase.Launcher.exe and b/dist/UbisamBase.Launcher.exe differ
diff --git a/dist/UbisamBase.Shell.exe b/dist/UbisamBase.Shell.exe
index 8d575aa..007a217 100644
Binary files a/dist/UbisamBase.Shell.exe and b/dist/UbisamBase.Shell.exe differ
diff --git a/dist/platform-version.json b/dist/platform-version.json
index 54aa3b9..1772d2c 100644
--- a/dist/platform-version.json
+++ b/dist/platform-version.json
@@ -1,4 +1,4 @@
{
-"version": "2026-09-21 21:55:55",
+"version": "2026-09-21 22:04:42",
"configuration": "Release"
}
diff --git a/src/UbisamBase.Launcher/PlatformUpdater.cs b/src/UbisamBase.Launcher/PlatformUpdater.cs
index 26386f8..de2df40 100644
--- a/src/UbisamBase.Launcher/PlatformUpdater.cs
+++ b/src/UbisamBase.Launcher/PlatformUpdater.cs
@@ -117,20 +117,10 @@ internal static class PlatformUpdater
}
// 3) 자동 업데이트가 아니면 물어본다.
- if (!settings.AutoUpdate)
+ if (!settings.AutoUpdate && !UpdateDialog.Ask(localVersion, remoteVersion))
{
- var answer = MessageBox.Show(
- "새 플랫폼 버전이 있습니다.\n\n" +
- "지금 버전 : " + (string.IsNullOrEmpty(localVersion) ? "(알 수 없음)" : localVersion) + "\n" +
- "새 버전 : " + remoteVersion + "\n\n" +
- "지금 업데이트하고 실행할까요?",
- "UbisamBase 업데이트", MessageBoxButton.YesNo, MessageBoxImage.Question);
-
- if (answer != MessageBoxResult.Yes)
- {
- // 기록을 남기지 않는다 — 다음에 켤 때 다시 물어본다.
- return;
- }
+ // 기록을 남기지 않는다 — 다음에 켤 때 다시 물어본다.
+ return;
}
var failed = CopyAll(remoteDist, platformDir);
diff --git a/src/UbisamBase.Launcher/UpdateDialog.xaml b/src/UbisamBase.Launcher/UpdateDialog.xaml
new file mode 100644
index 0000000..097f686
--- /dev/null
+++ b/src/UbisamBase.Launcher/UpdateDialog.xaml
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/UbisamBase.Launcher/UpdateDialog.xaml.cs b/src/UbisamBase.Launcher/UpdateDialog.xaml.cs
new file mode 100644
index 0000000..0fe9705
--- /dev/null
+++ b/src/UbisamBase.Launcher/UpdateDialog.xaml.cs
@@ -0,0 +1,103 @@
+using System;
+using System.Windows;
+using System.Windows.Input;
+using System.Windows.Media;
+using Microsoft.Win32;
+
+namespace UbisamBase.Launcher;
+
+///
+/// "새 버전이 있습니다 — 지금 받을까요?" 대화상자. 플랫폼(Core)의 MessageDialog와 같은 생김새지만,
+/// Launcher는 Core를 참조하지 않으므로(참조하면 갱신 대상인 Core.dll을 물고 있게 된다) 색을 직접 넣는다.
+///
+/// 테마는 윈도우 설정(밝게/어둡게)을 따라간다 — 이 시점에는 아직 앱의 UI 설정을 읽을 수 없기 때문이다.
+/// 색 값은 Core의 Colors.Dark.xaml / Colors.Light.xaml에서 같은 이름으로 가져온 것이다.
+///
+public partial class UpdateDialog : Window
+{
+ private UpdateDialog(string currentVersion, string newVersion)
+ {
+ InitializeComponent();
+
+ CurrentValue.Text = string.IsNullOrEmpty(currentVersion) ? "(알 수 없음)" : currentVersion;
+ NewValue.Text = newVersion;
+
+ ApplyTheme(IsSystemLightTheme());
+ }
+
+ /// 대화상자를 띄우고 "업데이트"를 눌렀는지 돌려준다.
+ public static bool Ask(string currentVersion, string newVersion)
+ => new UpdateDialog(currentVersion, newVersion).ShowDialog() == true;
+
+ private void ApplyTheme(bool light)
+ {
+ // Colors.Light.xaml / Colors.Dark.xaml 과 같은 값.
+ var background = Color(light ? "#FFF2F2F3" : "#FF23262B");
+ var foreground = Color(light ? "#FF1D1F20" : "#FFE8EAED");
+ var panel = Color(light ? "#FFFFFFFF" : "#FF2A2E34");
+ var border = Color(light ? "#FFD6D6D9" : "#FF3A3F47");
+ var muted = Color(light ? "#FF98989B" : "#FF8A9099");
+ var accentFill = Color(light ? "#FF1D82E8" : "#FF1E7FD4");
+ var onAccent = Color(light ? "#FFFFFFFF" : "#FFF2F7FC");
+
+ Background = background;
+ Foreground = foreground;
+ RootBorder.BorderBrush = border;
+
+ TitleBar.Background = panel;
+ TitleBar.BorderBrush = border;
+ TitleText.Foreground = foreground;
+
+ ButtonBar.Background = panel;
+ ButtonBar.BorderBrush = border;
+
+ IconPath.Stroke = foreground;
+ HeadlineText.Foreground = foreground;
+ CurrentLabel.Foreground = muted;
+ NewLabel.Foreground = muted;
+ CurrentValue.Foreground = muted;
+ NewValue.Foreground = foreground;
+ FootnoteText.Foreground = muted;
+
+ YesButton.Background = accentFill;
+ YesButton.BorderBrush = accentFill;
+ YesButton.Foreground = onAccent;
+
+ NoButton.Background = Brushes.Transparent;
+ NoButton.BorderBrush = border;
+ NoButton.Foreground = foreground;
+ }
+
+ private static SolidColorBrush Color(string hex)
+ => new SolidColorBrush((Color)ColorConverter.ConvertFromString(hex));
+
+ /// 윈도우가 밝은 테마인지. Core의 UiSettingsService.IsSystemLightTheme과 같은 판정이다.
+ private static bool IsSystemLightTheme()
+ {
+ try
+ {
+ using var key = Registry.CurrentUser.OpenSubKey(
+ @"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize");
+
+ return key?.GetValue("AppsUseLightTheme") is not int value || value != 0;
+ }
+ catch
+ {
+ return true;
+ }
+ }
+
+ private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => DragMove();
+
+ private void Yes_Click(object sender, RoutedEventArgs e) => DialogResult = true;
+
+ private void No_Click(object sender, RoutedEventArgs e) => DialogResult = false;
+
+ private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Escape)
+ {
+ DialogResult = false;
+ }
+ }
+}