如何获取.NET应用程序设置文件user.config的路径
朱二(2008.11 转载请注明作者)
最近在开发一个.NET项目的时,需要在客户端软件中保存用户的一些设置,比如是否在登录框中保存上次登录名等信息,就用到了.NET中的应用程序设置功能。如果使用用户范围的设置,程序会在磁盘上创建user.config用来存储修改后设置值,对 user.config所在的文件夹,我产生了一些兴趣,并做了一些研究。现举个例子来说明:
C:/Documents and Settings/Admin/Local Settings/Application Data/Microsoft/test.exe_Url_3ypvtlafqkef0gkp1kl5i2idjssaxajb/1.0.0.0/user.config
其中
“C:/Documents and Settings/Admin/Local Settings/Application Data”是LocalApplicationData特殊文件夹
“Microsoft”程序集的厂商名称
“Admin”是当前Windows用户名
“test.exe”是程序集友好名称
“1.0.0.0”是程序集版本
“user.config”是存储用户配置信息的文件的文件名
“Url_3ypvtlafqkef0gkp1kl5i2idjssaxajb”该字符串是将程序集的厂商信息、版本信息、绝对路径进行哈希计算,得到的唯一值,可避免不同的程序生成相同的文件路径。
如果要想通过编程的方式对user.config文件做一些灵活的控制,就必须得到该文件的绝对路径,为了获取.NET生成user.config唯
一路径的方法,笔者使用Reflector反编译了System.Config程序集,终于得到了其中的方法,做了一些简化。现做一些介绍:
(1)ClientConfigPaths类,只有一个public方法GetUserConfigFilePath,此方法即可获取user.config的绝对路径;
(2)StringUtil类,一个辅助类,用来做一些字符串操作
(3)使用方法:
- ClientConfigPaths ccp = new ClientConfigPaths();
- textBox1.Text = ccp.GetUserConfigFilePath();
以下的代码笔者做了一些简化的同时也做了一些限制,即只适用于从本地磁盘加载的程序集。
注意:如果是从internet加载或者使用clickonce部署的程序集请不要使用该方法。
- //ClientConfigPaths类
- using Microsoft.Win32;
- using System;
- using System.Collections;
- using System.Diagnostics;
- using System.Globalization;
- using System.IO;
- using System.Reflection;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Runtime.Serialization.Formatters.Binary;
- using System.Security.Cryptography;
- using System.Security.Permissions;
- using System.Security.Policy;
- using System.Text;
- internal class ClientConfigPaths
- {
- private string _applicationConfigUri;
- private string _applicationUri;
- private string _companyName;
- private bool _includesUserConfig;
- private string _productName;
- private string _productVersion;
- private const string ClickOnceDataDirectory = "DataDirectory";
- private const string ConfigExtension = ".config";
- private const string FILE_URI = "file:";
- private const string FILE_URI_LOCAL = "file:///";
- private const string FILE_URI_UNC = "file://";
- private const string HTTP_URI = "http://";
- private const int MAX_LENGTH_TO_USE = 0x19;
- private const int MAX_PATH = 260;
- private const string PathDesc = "Path";
- private static char[] s_Base32Char = new char[] {
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
- 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5'
- };
- private static SecurityPermission s_controlEvidencePerm;
- private static SecurityPermission s_serializationPerm;
- private const string StrongNameDesc = "StrongName";
- private const string UrlDesc = "Url";
- internal const string UserConfigFilename = "user.config";
- public string GetUserConfigFilePath()
- {
- string exePath = null;
- bool includeUserConfig = true;
- string UserConfigFilePath = "";
- this._includesUserConfig = includeUserConfig;
- Assembly exeAssembly = null;
- string codeBase = null;
- string applicationFilename = null;
- if (exePath == null)
- {
- AppDomainSetup setupInformation = AppDomain.CurrentDomain.SetupInformation;
- this._applicationConfigUri = setupInformation.ConfigurationFile;
- exeAssembly = Assembly.GetEntryAssembly();
- codeBase = exeAssembly.CodeBase;
- bool flag = false;
- if (StringUtil.StartsWithIgnoreCase(codeBase, "file:///"))
- {
- flag = true;
- codeBase = codeBase.Substring("file:///".Length);
- }
- else if (StringUtil.StartsWithIgnoreCase(codeBase, "file://"))
- {
- flag = true;
- codeBase = codeBase.Substring("file:".Length);
- }
- if (flag)
- {
- codeBase = codeBase.Replace('/', '//');
- applicationFilename = codeBase;
- }
- else
- {
- codeBase = exeAssembly.EscapedCodeBase;
- }
- }
- else
- {
- codeBase = Path.GetFullPath(exePath);
- if (!File.Exists(codeBase))
- {
- throw new Exception();
- }
- applicationFilename = codeBase;
- }
- if (this._applicationConfigUri == null)
- {
- this._applicationConfigUri = codeBase + ".config";
- }
- this._applicationUri = codeBase;
- if ((exePath == null) && this._includesUserConfig)
- {
- this.SetNamesAndVersion(applicationFilename, exeAssembly, false);
- string str5 = this.Validate(this._companyName, true);
- string str6 = this.Validate(AppDomain.CurrentDomain.FriendlyName, true);
- string str7 = !string.IsNullOrEmpty(this._applicationUri) ? this._applicationUri.ToLower
- (CultureInfo.InvariantCulture) : null;
- string str8 = !string.IsNullOrEmpty(str6) ? str6 : this.Validate(this._productName, true);
- string typeAndHashSuffix = this.GetTypeAndHashSuffix(AppDomain.CurrentDomain, str7);
- string str10 = (!string.IsNullOrEmpty(str8) && !string.IsNullOrEmpty(typeAndHashSuffix)) ?
- (str8 + typeAndHashSuffix) : null;
- string str11 = this.Validate(this._productVersion, false);
- string str12 = this.CombineIfValid(this.CombineIfValid(str5, str10), str11);
- string path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
- if (Path.IsPathRooted(path))
- {
- UserConfigFilePath = this.CombineIfValid(path, str12);
- UserConfigFilePath = this.CombineIfValid(UserConfigFilePath, "user.config");
- }
- }
- return UserConfigFilePath;
- }
- private string CombineIfValid(string path1, string path2)
- {
- string str = null;
- if ((path1 != null) && (path2 != null))
- {
- try
- {
- string str2 = Path.Combine(path1, path2);
- if (str2.Length < 260)
- {
- str = str2;
- }
- }
- catch
- {
- }
- }
- return str;
- }
- private static object GetEvidenceInfo(AppDomain appDomain, string exePath, out string typeName)
- {
- ControlEvidencePermission.Assert();
- Evidence evidence = appDomain.Evidence;
- StrongName sn = null;
- Url url = null;
- if (evidence != null)
- {
- IEnumerator hostEnumerator = evidence.GetHostEnumerator();
- object current = null;
- while (hostEnumerator.MoveNext())
- {
- current = hostEnumerator.Current;
- if (current is StrongName)
- {
- sn = (StrongName) current;
- break;
- }
- if (current is Url)
- {
- url = (Url) current;
- }
- }
- }
- object obj3 = null;
- if (sn != null)
- {
- obj3 = MakeVersionIndependent(sn);
- typeName = "StrongName";
- return obj3;
- }
- if (url != null)
- {
- obj3 = url.Value.ToUpperInvariant();
- typeName = "Url";
- return obj3;
- }
- if (exePath != null)
- {
- obj3 = exePath;
- typeName = "Path";
- return obj3;
- }
- typeName = null;
- return obj3;
- }
- private static string GetHash(Stream s)
- {
- byte[] buffer;
- using (SHA1 sha = new SHA1CryptoServiceProvider())
- {
- buffer = sha.ComputeHash(s);
- }
- return ToBase32StringSuitableForDirName(buffer);
- }
- private string GetTypeAndHashSuffix(AppDomain appDomain, string exePath)
- {
- string str = null;
- string typeName = null;
- object graph = null;
- graph = GetEvidenceInfo(appDomain, exePath, out typeName);
- if ((graph != null) && !string.IsNullOrEmpty(typeName))
- {
- MemoryStream serializationStream = new MemoryStream();
- BinaryFormatter formatter = new BinaryFormatter();
- SerializationFormatterPermission.Assert();
- formatter.Serialize(serializationStream, graph);
- serializationStream.Position = 0L;
- string hash = GetHash(serializationStream);
- if (!string.IsNullOrEmpty(hash))
- {
- str = "_" + typeName + "_" + hash;
- }
- }
- return str;
- }
- private static StrongName MakeVersionIndependent(StrongName sn)
- {
- return new StrongName(sn.PublicKey, sn.Name, new Version(0, 0, 0, 0));
- }
- private void SetNamesAndVersion(string applicationFilename, Assembly exeAssembly, bool isHttp)
- {
- Type reflectedType = null;
- if (exeAssembly != null)
- {
- object[] customAttributes = exeAssembly.GetCustomAttributes(typeof(AssemblyCompanyAttribute),
- false);
- if ((customAttributes != null) && (customAttributes.Length > 0))
- {
- this._companyName = ((AssemblyCompanyAttribute) customAttributes[0]).Company;
- if (this._companyName != null)
- {
- this._companyName = this._companyName.Trim();
- }
- }
- customAttributes = exeAssembly.GetCustomAttributes(typeof(AssemblyProductAttribute), false);
- if ((customAttributes != null) && (customAttributes.Length > 0))
- {
- this._productName = ((AssemblyProductAttribute) customAttributes[0]).Product;
- if (this._productName != null)
- {
- this._productName = this._productName.Trim();
- }
- }
- this._productVersion = exeAssembly.GetName().Version.ToString();
- if (this._productVersion != null)
- {
- this._productVersion = this._productVersion.Trim();
- }
- }
- if (!isHttp && ((string.IsNullOrEmpty(this._companyName) || string.IsNullOrEmpty(this._productName)) ||
- string.IsNullOrEmpty(this._productVersion)))
- {
- string fileName = null;
- if (exeAssembly != null)
- {
- MethodInfo entryPoint = exeAssembly.EntryPoint;
- if (entryPoint != null)
- {
- reflectedType = entryPoint.ReflectedType;
- if (reflectedType != null)
- {
- fileName = reflectedType.Module.FullyQualifiedName;
- }
- }
- }
- if (fileName == null)
- {
- fileName = applicationFilename;
- }
- if (fileName != null)
- {
- FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(fileName);
- if (versionInfo != null)
- {
- if (string.IsNullOrEmpty(this._companyName))
- {
- this._companyName = versionInfo.CompanyName;
- if (this._companyName != null)
- {
- this._companyName = this._companyName.Trim();
- }
- }
- if (string.IsNullOrEmpty(this._productName))
- {
- this._productName = versionInfo.ProductName;
- if (this._productName != null)
- {
- this._productName = this._productName.Trim();
- }
- }
- if (string.IsNullOrEmpty(this._productVersion))
- {
- this._productVersion = versionInfo.ProductVersion;
- if (this._productVersion != null)
- {
- this._productVersion = this._productVersion.Trim();
- }
- }
- }
- }
- }
- if (string.IsNullOrEmpty(this._companyName) || string.IsNullOrEmpty(this._productName))
- {
- string str2 = null;
- if (reflectedType != null)
- {
- str2 = reflectedType.Namespace;
- }
- if (string.IsNullOrEmpty(this._productName))
- {
- if (str2 != null)
- {
- int num = str2.LastIndexOf(".", StringComparison.Ordinal);
- if ((num != -1) && (num < (str2.Length - 1)))
- {
- this._productName = str2.Substring(num + 1);
- }
- else
- {
- this._productName = str2;
- }
- this._productName = this._productName.Trim();
- }
- if (string.IsNullOrEmpty(this._productName) && (reflectedType != null))
- {
- this._productName = reflectedType.Name.Trim();
- }
- if (this._productName == null)
- {
- this._productName = string.Empty;
- }
- }
- if (string.IsNullOrEmpty(this._companyName))
- {
- if (str2 != null)
- {
- int index = str2.IndexOf(".", StringComparison.Ordinal);
- if (index != -1)
- {
- this._companyName = str2.Substring(0, index);
- }
- else
- {
- this._companyName = str2;
- }
- this._companyName = this._companyName.Trim();
- }
- if (string.IsNullOrEmpty(this._companyName))
- {
- this._companyName = this._productName;
- }
- }
- }
- if (string.IsNullOrEmpty(this._productVersion))
- {
- this._productVersion = "1.0.0.0";
- }
- }
- private static string ToBase32StringSuitableForDirName(byte[] buff)
- {
- StringBuilder builder = new StringBuilder();
- int length = buff.Length;
- int num7 = 0;
- do
- {
- byte num = (num7 < length) ? buff[num7++] : ((byte) 0);
- byte num2 = (num7 < length) ? buff[num7++] : ((byte) 0);
- byte index = (num7 < length) ? buff[num7++] : ((byte) 0);
- byte num4 = (num7 < length) ? buff[num7++] : ((byte) 0);
- byte num5 = (num7 < length) ? buff[num7++] : ((byte) 0);
- builder.Append(s_Base32Char[num & 0x1f]);
- builder.Append(s_Base32Char[num2 & 0x1f]);
- builder.Append(s_Base32Char[index & 0x1f]);
- builder.Append(s_Base32Char[num4 & 0x1f]);
- builder.Append(s_Base32Char[num5 & 0x1f]);
- builder.Append(s_Base32Char[((num & 0xe0) >> 5) | ((num4 & 0x60) >> 2)]);
- builder.Append(s_Base32Char[((num2 & 0xe0) >> 5) | ((num5 & 0x60) >> 2)]);
- index = (byte) (index >> 5);
- if ((num4 & 0x80) != 0)
- {
- index = (byte) (index | 8);
- }
- if ((num5 & 0x80) != 0)
- {
- index = (byte) (index | 0x10);
- }
- builder.Append(s_Base32Char[index]);
- }
- while (num7 < length);
- return builder.ToString();
- }
- private string Validate(string str, bool limitSize)
- {
- string str2 = str;
- if (!string.IsNullOrEmpty(str2))
- {
- foreach (char ch in Path.GetInvalidFileNameChars())
- {
- str2 = str2.Replace(ch, '_');
- }
- str2 = str2.Replace(' ', '_');
- if (limitSize)
- {
- str2 = (str2.Length > 0x19) ? str2.Substring(0, 0x19) : str2;
- }
- }
- return str2;
- }
- private static SecurityPermission ControlEvidencePermission
- {
- get
- {
- if (s_controlEvidencePerm == null)
- {
- s_controlEvidencePerm = new SecurityPermission(SecurityPermissionFlag.ControlEvidence);
- }
- return s_controlEvidencePerm;
- }
- }
- private static SecurityPermission SerializationFormatterPermission
- {
- get
- {
- if (s_serializationPerm == null)
- {
- s_serializationPerm = new SecurityPermission(SecurityPermissionFlag.SerializationFormatter);
- }
- return s_serializationPerm;
- }
- }
- }
StringUtil类
- //StringUtil类
- using System;
- internal static class StringUtil
- {
- internal static bool EqualsIgnoreCase(string s1, string s2)
- {
- return string.Equals(s1, s2, StringComparison.OrdinalIgnoreCase);
- }
- internal static bool EqualsNE(string s1, string s2)
- {
- if (s1 == null)
- {
- s1 = string.Empty;
- }
- if (s2 == null)
- {
- s2 = string.Empty;
- }
- return string.Equals(s1, s2, StringComparison.Ordinal);
- }
- internal static string[] ObjectArrayToStringArray(object[] objectArray)
- {
- string[] array = new string[objectArray.Length];
- objectArray.CopyTo(array, 0);
- return array;
- }
- internal static bool StartsWith(string s1, string s2)
- {
- if (s2 == null)
- {
- return false;
- }
- return (0 == string.Compare(s1, 0, s2, 0, s2.Length, StringComparison.Ordinal));
- }
- internal static bool StartsWithIgnoreCase(string s1, string s2)
- {
- if (s2 == null)
- {
- return false;
- }
- return (0 == string.Compare(s1, 0, s2, 0, s2.Length, StringComparison.OrdinalIgnoreCase));
- }
- }