最近在做的WINCE程序即將送測,客戶端有很多東西都要移到配置文件中,于是慣性思維的我們想到了
System.Configuration.ConfigurationManager類。
一如既往的,我們添加個(gè)XML文件,重命名為
APP.CONFIG,
修改其中內(nèi)容為
<?xml version=
"
1.0
"
encoding=
"
utf-8
"
?>
<configuration>
<appSettings>
<!--DeviceSvc地址-->
<add key =
"
DeviceSvcAddress
"
value=
"
http://***********/DeviceSvc.svc
"
/>
</appSettings>
</configuration>
保存之后,在調(diào)用的地方很順其自然的 調(diào)用
var
filePath = ConfigurationManager.AppSettings[
"DeviceSvcAddress"
];
之后傻眼了,發(fā)現(xiàn)CompactFramework這個(gè)精簡的.NET框架不支持ConfigurationManager,那怎么辦,這種配置型的字符串不可能放在代碼中啊。轉(zhuǎn)念一想,其實(shí)ConfigurationManager無非也就是個(gè)XML文件讀取類,CompactFramework對XML讀寫可是完全支持,那么為何我們不可以自己寫一個(gè)。
動(dòng)手之前可以先整理下需求,這個(gè)類要干什么:
1.最好是靜態(tài)的,方便調(diào)用。
2.能讀取APP。Config中的配置節(jié)點(diǎn)。
3.如果再能添加修改就更好了。
?
OK,需求確定那就動(dòng)手
public
static
class
AppConfiger
{
public
static
string
_configName =
string
.Empty;
private
static
XDocument _configDoc =
null
;
private
static
string
_path =
string
.Empty;
static
AppConfiger()
{
//
編譯CAB文件發(fā)布時(shí)要修改為
//
_configName = "Cp.Device.exe.Config";
//
正常調(diào)試時(shí)使用
//
#if DEBUG
//
_configName = "App.Config";
//
#endif
//
#if !DEBUG
//
_configName = "Cp.Device.exe.Config";
//
#endif
LoadConfigurationFile(_configName);
}
??????? private static void LoadConfigurationFile(string configName)
??????? {
??????????? _configDoc = new XDocument();
??????????? string appDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
??????????? _path = Path.Combine(appDir, configName);
??????????? _configDoc = XDocument.Load(_path);
??????? }
}
這是這個(gè)類的一個(gè)屬性跟構(gòu)造函數(shù),_configName 這個(gè)就是配置文件的文件名,大家注意這一段
//
編譯CAB文件發(fā)布時(shí)要修改為
//
_configName = "Cp.Device.exe.Config";
//
正常調(diào)試時(shí)使用
//
#if DEBUG
//
_configName = "App.Config";
//
#endif
//
#if !DEBUG
//
_configName = "Cp.Device.exe.Config";
//
#endif
這一段弄得我好糾結(jié),WINCE程序Deploye運(yùn)行方式有2種,
一種是直連開發(fā)機(jī),用VS的F5運(yùn)行之后VS可以做一次發(fā)布,你可以修改程序的發(fā)布路徑,這種方式中還有DEBUG跟RELEASE模式。由于某種我不知道的原因,這樣的方式發(fā)布出來的文件,沒有*.exe.config這樣的配置文件生成,于是我把APP.CONFING屬性改為Contant+copy always。之后就用app.config文件去讀配置。
另外一種方式就是編譯CAB包安裝,這也是模擬正常發(fā)布的流程,這種方式下會(huì)生成*.exe.config這個(gè)文件,我以為這個(gè)模式也會(huì)有DEBUG跟RELEASE之分所以就用了
“#if DEBUG”
這樣的編譯路徑去區(qū)分,結(jié)果發(fā)現(xiàn)無論什么方式編譯出來的CAB包,都只會(huì)走到
_configName = "App.Config";
這個(gè)分支中,在程序發(fā)布時(shí),如果有2個(gè)配置文件這種事情也太不專業(yè)了
,于是我就換了另外一種思路去讀取配置文件
private
static
void
LoadConfigurationFile()
{
var
configName =
"
App.Config
"
;
_configDoc =
new
XDocument();
string
appDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
_path = Path.Combine(appDir, configName);
try
{
_configDoc = XDocument.Load(_path);
}
catch
(FileNotFoundException)
{
configName =
"
Cp.Device.exe.Config
"
;
_path = Path.Combine(appDir, configName);
_configDoc = XDocument.Load(_path);
}
catch
(Exception)
{
MessageBox.Show(
"
配置文件錯(cuò)誤
"
);
return
;
}
}
這樣就會(huì)在發(fā)布跟編譯時(shí)都可以讀取各自的CONFIG文件而不用每次都跑去修改_configName了。
既然我們已經(jīng)拿到了_configDoc,其他就好說了:
對節(jié)點(diǎn)的一些操作
private
static
XElement GetDescendant(
string
key)
{
var
getAppSettings = _configDoc.Descendants(
"
appSettings
"
).Elements();
XElement elem =
null
;
foreach
(
var
setting
in
getAppSettings)
{
XAttribute keyAtt = setting.Attribute(
"
key
"
);
if
(keyAtt.Value == key)
{
elem = setting;
break
;
}
}
return
elem;
}
public
static
void
Add(
string
key,
string
Value)
{
LoadConfigurationFile();
//
LoadConfigurationFile(_configName);
XElement element =
new
XElement(
"
add
"
,
new
XAttribute(
"
key
"
, key),
new
XAttribute(
"
value
"
, Value));
var
addElement = _configDoc.Descendants(
"
appSettings
"
).Elements().Last();
addElement.AddAfterSelf(element);
_configDoc.Save(_path);
}
public
static
string
GetAppSettingValue(
string
key)
{
XElement getAppSettings = GetDescendant(key);
var
configValue = getAppSettings.Attribute(
"
value
"
).Value;
return
configValue.ToString();
}
public
static
void
SetAppSettingValue(
string
key,
string
newValue)
{
XElement getAppSettings = GetDescendant(key);
getAppSettings.SetAttributeValue(
"
value
"
, newValue);
_configDoc.Save(_path);
}
調(diào)用的時(shí)候也很簡單
var i = AppConfiger.GetAppSettingValue("DeviceSvcAddress");
?至此,我們自己寫的可以用在CompactFramework中的Confier已經(jīng)完成了。
Wince自定義的ConfigurationManager