gpt4 book ai didi

.net - 使字符串在 .NET 应用程序中持久化

转载 作者:行者123 更新时间:2023-12-04 12:26:43 25 4
gpt4 key购买 nike

我试图在 VS 2008 下用 C++ 编写的 .NET 应用程序中使字符串持久化(即,它是一个文件路径)。我只需要在应用程序启动时阅读它,并在离开时编写它。

我正在努力寻找正确的方法来做到这一点。 Web 搜索将我定向到 ConfigurationSettings 和 ConfigurationManager 对象。似乎第一个是只读的,第二个在配置引用(框架 3.5)中找不到。

我知道我可以对注册表或外部文件执行显式读/写,但我更喜欢更标准的方式。我不希望这需要两行以上的代码。

我在正确的轨道上吗?

最佳答案

使用 VS2008 和 .NET framework 3.5,如果应用程序安装在 %ProgramFiles% 或 %ProgramFiles(x86)% 的子文件夹中,则无法创建修改 app.config 所需的 list ,因为它们受到操作系统的特别保护,并且您不能在没有提升进程的情况下写入注册表的 HKLM 节点。

我想我会编码默认值和一个 bool 值,告诉应用程序是否以可移植模式运行到 app.config。从 app.config 中读取默认值,用 user.config 中的值(如果存在)覆盖变量,如果处于可移植模式,则将该值写入 user.config,如果处于非可移植模式,则将值写入 app.config。

在自定义类中,独立于来自框架的任何不良支持(对 app.config 没有写访问权限,没有混合模式)......

应用程序配置:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup>
    <supportedRuntime version="v2.0.50727"/>
  </startup>
  <appSettings>
    <add key="PortableMode" value="Off"/>
    <add key="SomethingPath" value="Software\Cragin\FooApp\SomethingPath"/>
  </appSettings>
</configuration>



我认为它大约有 250 行代码而不是 2 行代码,但它确实有效(抱歉,它是用 C# 编写的,但您可能知道如何将它改编为 C++)。
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml.Linq;

namespace DesktopApp1 {

static class Program {

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main() {
Config myConfig = new Config();
myConfig.Load();

//Change settings during the livetime of the application
myConfig.SomethingPath = @"C:\Temp\Foo\TestUser.dat";
myConfig.PortableMode = false;

//Write it when closing the application
myConfig.Save();

}

}

internal class Config {

//Private Fields
private AppOrUserConfig _Config;
private Boolean _IsUserConfig;
private String _AppConfigPath;
private String _UserConfigPath;

public void Load() {
AppOrUserConfig myDefaultConfig = new AppOrUserConfig();
AppOrUserConfig myAppConfig = new AppOrUserConfig(AppConfigPath, myDefaultConfig);
if (myAppConfig.PortableMode) {
_Config = myAppConfig;
_IsUserConfig = false;
} else {
_Config = new AppOrUserConfig(UserConfigPath, myAppConfig);
_IsUserConfig = true;
}
}

public Boolean Save() {
CheckLoad();
String myFilePath = IsUserConfig ? UserConfigPath : AppConfigPath;
try {
String myContent = _Config.XmlContent;
String myFolder = Path.GetDirectoryName(myFilePath);
Directory.CreateDirectory(myFolder);
File.Delete(myFilePath);
File.WriteAllText(myFilePath, myContent, new UTF8Encoding(true));
return true;
} catch {
}
return false;
}

public Boolean PortableMode {
get {
CheckLoad();
return _Config.PortableMode;
}
set {
CheckLoad();
if (PortableMode == value) return;
if (value) {
_Config.PortableMode = true;
_IsUserConfig = false;
Save();
} else {
String myPath = SomethingPath;
_Config.PortableMode = false;
Save();
Load();
SomethingPath = myPath;
}
}
}

public String SomethingPath {
get {
CheckLoad();
return _Config.SomethingPath;
}
set {
CheckLoad();
_Config.SomethingPath = value;
}
}

private String AppConfigPath {
get {
String myResult = _AppConfigPath;
if (myResult == null) {
myResult = Assembly.GetEntryAssembly().EntryPoint.DeclaringType.Module.FullyQualifiedName + ".config";
_AppConfigPath = myResult;
}
return myResult;
}
}

private String UserConfigPath {
get {
String myResult = _UserConfigPath;
if (myResult == null) {
myResult = Path.Combine(Environment.ExpandEnvironmentVariables(@"%LOCALAPPDATA%\Cragin\FooApp"), Path.GetFileName(AppConfigPath));
_UserConfigPath = myResult;
}
return myResult;
}
}

private Boolean IsUserConfig {
get {
return _IsUserConfig;
}
}

private void CheckLoad() {
if (_Config == null) throw new InvalidOperationException(@"Call method ""Load()"" first.");
}

}

internal class AppOrUserConfig {

//Private Fields
private XDocument _Xml;

//Constructors

public AppOrUserConfig() {
_Xml = XDocument.Parse(@"<?xml version=""1.0"" encoding=""utf-8""?>
<configuration>
<startup>
<supportedRuntime version=""v2.0.50727""/>
</startup>
<appSettings>
<add key=""PortableMode"" value=""Off""/>
<add key=""SomethingPath"" value=""C:\ProgramData\Cragin\SomeLibrary""/>
</appSettings>
</configuration>");
}

public AppOrUserConfig(String filePath, AppOrUserConfig defaultValue) : this() {
XDocument myXml = null;
try {
myXml = XDocument.Parse(File.ReadAllText(filePath));
} catch {
return;
}
AppOrUserConfig myDummy = new AppOrUserConfig(myXml, defaultValue);
PortableMode = myDummy.PortableMode;
SomethingPath = myDummy.SomethingPath;
}

public AppOrUserConfig(XDocument xml, AppOrUserConfig defaultValue) : this() {
if (defaultValue == null) defaultValue = new AppOrUserConfig();
if (xml == null) {
PortableMode = defaultValue.PortableMode;
SomethingPath = defaultValue.SomethingPath;
return;
}
AppOrUserConfig myDummy = new AppOrUserConfig();
myDummy._Xml = xml;
PortableMode = myDummy.GetPortableMode(defaultValue.PortableMode);
SomethingPath = myDummy.GetSomethingPath(defaultValue.SomethingPath);
}

public Boolean PortableMode {
get {
return GetPortableMode(false);
}
set {
(from e in _Xml.Element("configuration").Element("appSettings").Elements("add") where (string)e.Attribute("key") == "PortableMode" select e).Last().Attribute("value").Value = value ? "on" : "off";
}
}

public String SomethingPath {
get {
return GetSomethingPath(@"C:\ProgramData\Cragin\SomeLibrary");
}
set {
(from e in _Xml.Element("configuration").Element("appSettings").Elements("add") where (string)e.Attribute("key") == "SomethingPath" select e).Last().Attribute("value").Value = value ?? "";
}
}

public String XmlContent {
get {
return _Xml.ToString(SaveOptions.None);
}
}

private Boolean GetPortableMode(Boolean defaultValue) {
try {
String myString = (from e in _Xml.Element("configuration").Element("appSettings").Elements("add") where (string)e.Attribute("key") == "PortableMode" select e).Last().Attribute("value").Value;
return ToBoolean(myString);
} catch {
PortableMode = defaultValue;
return defaultValue;
}
}

private String GetSomethingPath(String defaultValue) {
try {
return (from e in _Xml.Element("configuration").Element("appSettings").Elements("add") where (string)e.Attribute("key") == "SomethingPath" select e).Last().Attribute("value").Value;
} catch {
SomethingPath = defaultValue;
return defaultValue;
}
}

private static Boolean ToBoolean(String value) {
value = value.Trim();
switch (value.Length) {
case 1:
if (value[0] == '0') return false;
if (value[0] == '1') return true;
break;
case 5:
if (value.ToLowerInvariant() == "false") return false;
break;
case 4:
if (value.ToLowerInvariant() == "true") return true;
break;
case 3:
if (value.ToLowerInvariant() == "off") return false;
break;
case 2:
if (value.ToLowerInvariant() == "on") return true;
break;
}
throw new FormatException();
}

}

}

我希望它对您或其他任何人有用。

关于.net - 使字符串在 .NET 应用程序中持久化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56092212/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com