@@ -21,7 +21,7 @@ using namespace ::Magpie::Core;
21
21
22
22
namespace winrt ::Magpie::App {
23
23
24
- static constexpr uint32_t SETTINGS_VERSION = 2 ;
24
+ static constexpr uint32_t CONFIG_VERSION = 2 ;
25
25
26
26
_AppSettingsData::_AppSettingsData () {}
27
27
@@ -213,13 +213,15 @@ bool AppSettings::Initialize() noexcept {
213
213
Logger& logger = Logger::Get ();
214
214
215
215
// 若程序所在目录存在配置文件则为便携模式
216
- _isPortableMode = Win32Utils::FileExists (
217
- StrUtils::Concat (CommonSharedConstants::CONFIG_DIR, CommonSharedConstants::CONFIG_NAME).c_str ());
218
- _UpdateConfigPath ();
216
+ _isPortableMode = Win32Utils::FileExists (StrUtils::Concat (
217
+ CommonSharedConstants::CONFIG_DIR, CommonSharedConstants::CONFIG_FILENAME).c_str ());
218
+
219
+ std::wstring existingConfigPath;
220
+ _UpdateConfigPath (&existingConfigPath);
219
221
220
222
logger.Info (StrUtils::Concat (" 便携模式:" , _isPortableMode ? " 是" : " 否" ));
221
223
222
- if (! Win32Utils::FileExists (_configPath. c_str () )) {
224
+ if (existingConfigPath. empty ( )) {
223
225
logger.Info (" 不存在配置文件" );
224
226
_SetDefaultScalingModes ();
225
227
_SetDefaultShortcuts ();
@@ -230,13 +232,14 @@ bool AppSettings::Initialize() noexcept {
230
232
// 此时 ResourceLoader 使用“首选语言”
231
233
232
234
std::string configText;
233
- if (!Win32Utils::ReadTextFile (_configPath .c_str (), configText)) {
235
+ if (!Win32Utils::ReadTextFile (existingConfigPath .c_str (), configText)) {
234
236
logger.Error (" 读取配置文件失败" );
235
237
ResourceLoader resourceLoader =
236
238
ResourceLoader::GetForCurrentView (CommonSharedConstants::APP_RESOURCE_MAP_ID);
237
239
hstring title = resourceLoader.GetString (L" AppSettings_ErrorDialog_ReadFailed" );
238
240
hstring content = resourceLoader.GetString (L" AppSettings_ErrorDialog_ConfigLocation" );
239
- ShowErrorMessage (title.c_str (), fmt::format (fmt::runtime (std::wstring_view (content)), _configPath).c_str ());
241
+ ShowErrorMessage (title.c_str (),
242
+ fmt::format (fmt::runtime (std::wstring_view (content)), existingConfigPath).c_str ());
240
243
return false ;
241
244
}
242
245
@@ -256,7 +259,8 @@ bool AppSettings::Initialize() noexcept {
256
259
ResourceLoader::GetForCurrentView (CommonSharedConstants::APP_RESOURCE_MAP_ID);
257
260
hstring title = resourceLoader.GetString (L" AppSettings_ErrorDialog_NotValidJson" );
258
261
hstring content = resourceLoader.GetString (L" AppSettings_ErrorDialog_ConfigLocation" );
259
- ShowErrorMessage (title.c_str (), fmt::format (fmt::runtime (std::wstring_view (content)), _configPath).c_str ());
262
+ ShowErrorMessage (title.c_str (),
263
+ fmt::format (fmt::runtime (std::wstring_view (content)), existingConfigPath).c_str ());
260
264
return false ;
261
265
}
262
266
@@ -266,53 +270,14 @@ bool AppSettings::Initialize() noexcept {
266
270
ResourceLoader::GetForCurrentView (CommonSharedConstants::APP_RESOURCE_MAP_ID);
267
271
hstring title = resourceLoader.GetString (L" AppSettings_ErrorDialog_ParseFailed" );
268
272
hstring content = resourceLoader.GetString (L" AppSettings_ErrorDialog_ConfigLocation" );
269
- ShowErrorMessage (title.c_str (), fmt::format (fmt::runtime (std::wstring_view (content)), _configPath).c_str ());
273
+ ShowErrorMessage (title.c_str (),
274
+ fmt::format (fmt::runtime (std::wstring_view (content)), existingConfigPath).c_str ());
270
275
return false ;
271
276
}
272
277
273
278
auto root = ((const rapidjson::Document&)doc).GetObj ();
274
279
275
- uint32_t settingsVersion = 0 ;
276
- // 不存在 version 字段则视为 0
277
- JsonHelper::ReadUInt (root, " version" , settingsVersion);
278
-
279
- if (settingsVersion > SETTINGS_VERSION) {
280
- Logger::Get ().Warn (" 未知的配置文件版本" );
281
-
282
- ResourceLoader resourceLoader =
283
- ResourceLoader::GetForCurrentView (CommonSharedConstants::APP_RESOURCE_MAP_ID);
284
- if (_isPortableMode) {
285
- hstring contentStr = resourceLoader.GetString (
286
- L" AppSettings_PortableModeUnkownConfiguration_Content" );
287
- hstring continueStr = resourceLoader.GetString (
288
- L" AppSettings_PortableModeUnkownConfiguration_Continue" );
289
- hstring exitStr = resourceLoader.GetString (
290
- L" AppSettings_PortableModeUnkownConfiguration_Exit" );
291
- if (!ShowOkCancelWarningMessage (nullptr ,
292
- contentStr.c_str (), continueStr.c_str (), exitStr.c_str ())
293
- ) {
294
- return false ;
295
- }
296
- } else {
297
- hstring contentStr = resourceLoader.GetString (
298
- L" AppSettings_UnkownConfiguration_Content" );
299
- hstring continueStr = resourceLoader.GetString (
300
- L" AppSettings_UnkownConfiguration_Continue" );
301
- hstring enablePortableModeStr = resourceLoader.GetString (
302
- L" AppSettings_UnkownConfiguration_EnablePortableMode" );
303
- if (!ShowOkCancelWarningMessage (nullptr ,
304
- contentStr.c_str (), continueStr.c_str (), enablePortableModeStr.c_str ())
305
- ) {
306
- IsPortableMode (true );
307
- _SetDefaultScalingModes ();
308
- _SetDefaultShortcuts ();
309
- SaveAsync ();
310
- return true ;
311
- }
312
- }
313
- }
314
-
315
- _LoadSettings (root, settingsVersion);
280
+ _LoadSettings (root);
316
281
317
282
if (_SetDefaultShortcuts ()) {
318
283
SaveAsync ();
@@ -343,7 +308,7 @@ void AppSettings::IsPortableMode(bool value) noexcept {
343
308
if (!value) {
344
309
// 关闭便携模式需删除本地配置文件
345
310
// 不关心是否成功
346
- DeleteFile (StrUtils::Concat (_configDir, CommonSharedConstants::CONFIG_NAME ).c_str ());
311
+ DeleteFile (StrUtils::Concat (_configDir, CommonSharedConstants::CONFIG_FILENAME ).c_str ());
347
312
}
348
313
349
314
Logger::Get ().Info (value ? " 已开启便携模式" : " 已关闭便携模式" );
@@ -486,9 +451,6 @@ bool AppSettings::_Save(const _AppSettingsData& data) noexcept {
486
451
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer (json);
487
452
writer.StartObject ();
488
453
489
- writer.Key (" version" );
490
- writer.Uint (SETTINGS_VERSION);
491
-
492
454
writer.Key (" language" );
493
455
if (_language < 0 ) {
494
456
writer.String (" " );
@@ -582,7 +544,7 @@ bool AppSettings::_Save(const _AppSettingsData& data) noexcept {
582
544
}
583
545
584
546
// 永远不会失败,遇到不合法的配置项时静默忽略
585
- void AppSettings::_LoadSettings (const rapidjson::GenericObject<true , rapidjson::Value>& root, uint32_t /* version */ ) noexcept {
547
+ void AppSettings::_LoadSettings (const rapidjson::GenericObject<true , rapidjson::Value>& root) noexcept {
586
548
{
587
549
std::wstring language;
588
550
JsonHelper::ReadString (root, " language" , language);
@@ -697,7 +659,7 @@ void AppSettings::_LoadSettings(const rapidjson::GenericObject<true, rapidjson::
697
659
// v0.10.0-preview1 使用 alwaysRunAsElevated
698
660
JsonHelper::ReadBool (root, " alwaysRunAsElevated" , _isAlwaysRunAsAdmin);
699
661
}
700
- if (!JsonHelper::ReadBool (root, " showNotifyIcon" , _isShowNotifyIcon)) {
662
+ if (!JsonHelper::ReadBool (root, " showNotifyIcon" , _isShowNotifyIcon, true )) {
701
663
// v0.10 使用 showTrayIcon
702
664
JsonHelper::ReadBool (root, " showTrayIcon" , _isShowNotifyIcon);
703
665
}
@@ -991,33 +953,79 @@ void AppSettings::_SetDefaultScalingModes() noexcept {
991
953
_defaultProfile.scalingMode = 0 ;
992
954
}
993
955
994
- void AppSettings::_UpdateConfigPath () noexcept {
956
+ static std::wstring FindOldConfig (const wchar_t * localAppDataDir) noexcept {
957
+ for (uint32_t version = CONFIG_VERSION - 1 ; version >= 2 ; --version) {
958
+ std::wstring oldConfigPath = fmt::format (
959
+ L" {}\\ Magpie\\ {}v{}\\ {}" ,
960
+ localAppDataDir,
961
+ CommonSharedConstants::CONFIG_DIR,
962
+ version,
963
+ CommonSharedConstants::CONFIG_FILENAME
964
+ );
965
+
966
+ if (Win32Utils::FileExists (oldConfigPath.c_str ())) {
967
+ return oldConfigPath;
968
+ }
969
+ }
970
+
971
+ // v1 版本的配置文件不在子目录中
972
+ std::wstring v1ConfigPath = StrUtils::Concat (
973
+ localAppDataDir,
974
+ L" \\ Magpie\\ " ,
975
+ CommonSharedConstants::CONFIG_DIR,
976
+ CommonSharedConstants::CONFIG_FILENAME
977
+ );
978
+
979
+ if (Win32Utils::FileExists (v1ConfigPath.c_str ())) {
980
+ return v1ConfigPath;
981
+ }
982
+
983
+ return {};
984
+ }
985
+
986
+ void AppSettings::_UpdateConfigPath (std::wstring* existingConfigPath) noexcept {
995
987
if (_isPortableMode) {
996
988
wchar_t curDir[MAX_PATH];
997
989
GetCurrentDirectory (MAX_PATH, curDir);
998
990
999
- _configDir = curDir;
1000
- if (_configDir.back () != L' \\ ' ) {
1001
- _configDir.push_back (L' \\ ' );
991
+ _configDir = StrUtils::Concat (curDir, L" \\ " , CommonSharedConstants::CONFIG_DIR);
992
+ _configPath = _configDir + CommonSharedConstants::CONFIG_FILENAME;
993
+
994
+ if (existingConfigPath) {
995
+ if (Win32Utils::FileExists (_configPath.c_str ())) {
996
+ *existingConfigPath = _configPath;
997
+ }
1002
998
}
1003
- _configDir += CommonSharedConstants::CONFIG_DIR;
1004
999
} else {
1005
1000
wchar_t localAppDataDir[MAX_PATH];
1006
1001
HRESULT hr = SHGetFolderPath (NULL , CSIDL_LOCAL_APPDATA, NULL , 0 , localAppDataDir);
1007
1002
if (SUCCEEDED (hr)) {
1008
- _configDir = StrUtils::Concat (
1009
- localAppDataDir,
1010
- localAppDataDir[StrUtils::StrLen (localAppDataDir) - 1 ] == L' \\ ' ? L" Magpie\\ " : L" \\ Magpie\\ " ,
1011
- CommonSharedConstants::CONFIG_DIR
1012
- );
1003
+ _configDir = fmt::format (L" {}\\ Magpie\\ {}v{}\\ " ,
1004
+ localAppDataDir, CommonSharedConstants::CONFIG_DIR, CONFIG_VERSION);
1005
+ _configPath = _configDir + CommonSharedConstants::CONFIG_FILENAME;
1006
+
1007
+ if (existingConfigPath) {
1008
+ if (Win32Utils::FileExists (_configPath.c_str ())) {
1009
+ *existingConfigPath = _configPath;
1010
+ } else {
1011
+ // 查找旧版本配置文件
1012
+ *existingConfigPath = FindOldConfig (localAppDataDir);
1013
+ }
1014
+ }
1013
1015
} else {
1014
1016
Logger::Get ().ComError (" SHGetFolderPath 失败" , hr);
1017
+
1015
1018
_configDir = CommonSharedConstants::CONFIG_DIR;
1019
+ _configPath = _configDir + CommonSharedConstants::CONFIG_FILENAME;
1020
+
1021
+ if (existingConfigPath) {
1022
+ if (Win32Utils::FileExists (_configPath.c_str ())) {
1023
+ *existingConfigPath = _configPath;
1024
+ }
1025
+ }
1016
1026
}
1017
1027
}
1018
1028
1019
- _configPath = _configDir + CommonSharedConstants::CONFIG_NAME;
1020
-
1021
1029
// 确保 ConfigDir 存在
1022
1030
Win32Utils::CreateDir (_configDir.c_str (), true );
1023
1031
}
0 commit comments