chore: 首次簽入 Thinkyu ASP.NET 專案
- 加入 Visual Studio / ASP.NET .gitignore - 排除建置輸出、IDE 設定、NuGet packages、大型 MSI 安裝檔
This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
|
||||
namespace 報到系統客戶端.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// 系統設定管理服務
|
||||
/// 提供讀取和寫入應用程式設定的功能
|
||||
/// 設定檔存儲在用戶的 AppData 資料夾中,以避免 Program Files 權限問題
|
||||
/// </summary>
|
||||
public class ConfigService
|
||||
{
|
||||
private static ConfigService _instance;
|
||||
private static readonly object _lockObject = new object();
|
||||
|
||||
private string _userConfigPath;
|
||||
private string _defaultConfigPath;
|
||||
|
||||
/// <summary>
|
||||
/// 取得 ConfigService 的單一實例
|
||||
/// </summary>
|
||||
public static ConfigService Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
lock (_lockObject)
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = new ConfigService();
|
||||
}
|
||||
}
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
private ConfigService()
|
||||
{
|
||||
_defaultConfigPath = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
|
||||
|
||||
// 用戶設定檔存儲在 AppData\Roaming\報到系統客戶端 資料夾
|
||||
string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
|
||||
string configDirectory = Path.Combine(appDataPath, "報到系統客戶端");
|
||||
|
||||
// 確保目錄存在
|
||||
if (!Directory.Exists(configDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(configDirectory);
|
||||
}
|
||||
|
||||
_userConfigPath = Path.Combine(configDirectory, "AppSettings.config");
|
||||
|
||||
// 如果用戶設定檔不存在,從預設設定檔複製
|
||||
if (!File.Exists(_userConfigPath))
|
||||
{
|
||||
InitializeUserConfig();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化用戶設定檔
|
||||
/// 從預設設定檔複製所需的設定項目
|
||||
/// </summary>
|
||||
private void InitializeUserConfig()
|
||||
{
|
||||
try
|
||||
{
|
||||
XmlDocument defaultDoc = new XmlDocument();
|
||||
defaultDoc.Load(_defaultConfigPath);
|
||||
|
||||
XmlDocument userDoc = new XmlDocument();
|
||||
|
||||
// 建立新的設定檔結構
|
||||
XmlDeclaration declaration = userDoc.CreateXmlDeclaration("1.0", "utf-8", null);
|
||||
userDoc.AppendChild(declaration);
|
||||
|
||||
XmlElement configElement = userDoc.CreateElement("configuration");
|
||||
userDoc.AppendChild(configElement);
|
||||
|
||||
// 建立 applicationSettings 節點
|
||||
XmlElement appSettingsNode = userDoc.CreateElement("applicationSettings");
|
||||
configElement.AppendChild(appSettingsNode);
|
||||
|
||||
// 建立報到系統客戶端.Properties.Settings 節點
|
||||
XmlElement settingsNode = userDoc.CreateElement("報到系統客戶端.Properties.Settings");
|
||||
appSettingsNode.AppendChild(settingsNode);
|
||||
|
||||
// 建立 ApiBaseUrl 設定項目
|
||||
XmlElement settingElement = userDoc.CreateElement("setting");
|
||||
settingElement.SetAttribute("name", "ApiBaseUrl");
|
||||
settingElement.SetAttribute("serializeAs", "String");
|
||||
|
||||
XmlElement valueElement = userDoc.CreateElement("value");
|
||||
valueElement.InnerText = "https://thinkyustaff.com/event";
|
||||
settingElement.AppendChild(valueElement);
|
||||
|
||||
settingsNode.AppendChild(settingElement);
|
||||
|
||||
userDoc.Save(_userConfigPath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"初始化用戶設定檔失敗: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 讀取 API 基礎 URL
|
||||
/// </summary>
|
||||
/// <returns>API 基礎 URL</returns>
|
||||
public string GetApiBaseUrl()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(_userConfigPath))
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(_userConfigPath);
|
||||
|
||||
XmlNode valueNode = doc.SelectSingleNode(
|
||||
"/configuration/applicationSettings/報到系統客戶端.Properties.Settings/setting[@name='ApiBaseUrl']/value"
|
||||
);
|
||||
|
||||
if (valueNode != null && !string.IsNullOrWhiteSpace(valueNode.InnerText))
|
||||
{
|
||||
return valueNode.InnerText;
|
||||
}
|
||||
}
|
||||
|
||||
// 回退到預設值或 App.config
|
||||
return Properties.Settings.Default.ApiBaseUrl ?? "https://thinkyustaff.com/event";
|
||||
}
|
||||
catch
|
||||
{
|
||||
return "https://thinkyustaff.com/event";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 設定 API 基礎 URL
|
||||
/// </summary>
|
||||
/// <param name="baseUrl">新的 API 基礎 URL</param>
|
||||
/// <returns>是否設定成功</returns>
|
||||
public bool SetApiBaseUrl(string baseUrl)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(baseUrl))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 確保用戶設定檔存在
|
||||
if (!File.Exists(_userConfigPath))
|
||||
{
|
||||
InitializeUserConfig();
|
||||
}
|
||||
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(_userConfigPath);
|
||||
|
||||
// 找到或建立 applicationSettings 節點
|
||||
XmlNode appSettingsNode = doc.SelectSingleNode("//applicationSettings");
|
||||
if (appSettingsNode == null)
|
||||
{
|
||||
XmlNode configNode = doc.SelectSingleNode("//configuration");
|
||||
if (configNode == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
appSettingsNode = doc.CreateElement("applicationSettings");
|
||||
configNode.AppendChild(appSettingsNode);
|
||||
}
|
||||
|
||||
// 找到或建立 報到系統客戶端.Properties.Settings 節點
|
||||
XmlNode settingsNode = appSettingsNode.SelectSingleNode("報到系統客戶端.Properties.Settings");
|
||||
if (settingsNode == null)
|
||||
{
|
||||
settingsNode = doc.CreateElement("報到系統客戶端.Properties.Settings");
|
||||
appSettingsNode.AppendChild(settingsNode);
|
||||
}
|
||||
|
||||
// 找到 ApiBaseUrl 設定項目
|
||||
XmlNode apiBaseUrlNode = settingsNode.SelectSingleNode("setting[@name='ApiBaseUrl']");
|
||||
if (apiBaseUrlNode == null)
|
||||
{
|
||||
apiBaseUrlNode = doc.CreateElement("setting");
|
||||
apiBaseUrlNode.Attributes.Append(doc.CreateAttribute("name"));
|
||||
apiBaseUrlNode.Attributes["name"].Value = "ApiBaseUrl";
|
||||
apiBaseUrlNode.Attributes.Append(doc.CreateAttribute("serializeAs"));
|
||||
apiBaseUrlNode.Attributes["serializeAs"].Value = "String";
|
||||
settingsNode.AppendChild(apiBaseUrlNode);
|
||||
}
|
||||
|
||||
// 更新值
|
||||
XmlNode valueNode = apiBaseUrlNode.SelectSingleNode("value");
|
||||
if (valueNode != null)
|
||||
{
|
||||
valueNode.InnerText = baseUrl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果沒有 value 節點,則建立一個
|
||||
valueNode = doc.CreateElement("value");
|
||||
valueNode.InnerText = baseUrl;
|
||||
apiBaseUrlNode.AppendChild(valueNode);
|
||||
}
|
||||
|
||||
// 保存設定檔到用戶的 AppData 資料夾
|
||||
doc.Save(_userConfigPath);
|
||||
|
||||
// 刷新設定以更新記憶體中的值
|
||||
RefreshSettings();
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"設定 ApiBaseUrl 失敗: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新設定值
|
||||
/// </summary>
|
||||
private void RefreshSettings()
|
||||
{
|
||||
try
|
||||
{
|
||||
Properties.Settings.Default.Reload();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 刷新失敗時不執行任何操作
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取得應用程式設定檔路徑
|
||||
/// 返回用戶設定檔的路徑(位於 AppData 中)
|
||||
/// </summary>
|
||||
/// <returns>設定檔路徑</returns>
|
||||
//public string GetConfigFilePath()
|
||||
//{
|
||||
// return _userConfigPath;
|
||||
//}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user