如何获取.NET应用程序设置文件user.config的路径

如何获取.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)使用方法:

  1.   ClientConfigPaths ccp = new ClientConfigPaths();
  2.   textBox1.Text = ccp.GetUserConfigFilePath();

以下的代码笔者做了一些简化的同时也做了一些限制,即只适用于从本地磁盘加载的程序集。
注意:如果是从internet加载或者使用clickonce部署的程序集请不要使用该方法。

  1.     //ClientConfigPaths类
  2.     using Microsoft.Win32;
  3.     using System;
  4.     using System.Collections;
  5.     using System.Diagnostics;
  6.     using System.Globalization;
  7.     using System.IO;
  8.     using System.Reflection;
  9.     using System.Runtime.CompilerServices;
  10.     using System.Runtime.InteropServices;
  11.     using System.Runtime.Serialization.Formatters.Binary;
  12.     using System.Security.Cryptography;
  13.     using System.Security.Permissions;
  14.     using System.Security.Policy;
  15.     using System.Text;
  16.     internal class ClientConfigPaths
  17.     {
  18.         private string _applicationConfigUri;
  19.         private string _applicationUri;
  20.         private string _companyName;
  21.         private bool _includesUserConfig;
  22.         private string _productName;
  23.         private string _productVersion;
  24.         private const string ClickOnceDataDirectory = "DataDirectory";
  25.         private const string ConfigExtension = ".config";
  26.         private const string FILE_URI = "file:";
  27.         private const string FILE_URI_LOCAL = "file:///";
  28.         private const string FILE_URI_UNC = "file://";
  29.         private const string HTTP_URI = "http://";
  30.         private const int MAX_LENGTH_TO_USE = 0x19;
  31.         private const int MAX_PATH = 260;
  32.         private const string PathDesc = "Path";
  33.         private static char[] s_Base32Char = new char[] { 
  34.             'a''b''c''d''e''f''g''h''i''j''k''l''m''n''o''p'
  35.             'q''r''s''t''u''v''w''x''y''z''0''1''2''3''4''5'
  36.          };
  37.         private static SecurityPermission s_controlEvidencePerm;
  38.         private static SecurityPermission s_serializationPerm;
  39.         private const string StrongNameDesc = "StrongName";
  40.         private const string UrlDesc = "Url";
  41.         internal const string UserConfigFilename = "user.config";
  42.         public string GetUserConfigFilePath()
  43.         {
  44.             string exePath = null;
  45.             bool includeUserConfig = true;
  46.             string UserConfigFilePath = "";
  47.             this._includesUserConfig = includeUserConfig;
  48.             Assembly exeAssembly = null;
  49.             string codeBase = null;
  50.             string applicationFilename = null;
  51.             if (exePath == null)
  52.             {
  53.                 AppDomainSetup setupInformation = AppDomain.CurrentDomain.SetupInformation;
  54.                 this._applicationConfigUri = setupInformation.ConfigurationFile;
  55.                 exeAssembly = Assembly.GetEntryAssembly();
  56.                     codeBase = exeAssembly.CodeBase;
  57.                     bool flag = false;
  58.                     if (StringUtil.StartsWithIgnoreCase(codeBase, "file:///"))
  59.                     {
  60.                         flag = true;
  61.                         codeBase = codeBase.Substring("file:///".Length);
  62.                     }
  63.                     else if (StringUtil.StartsWithIgnoreCase(codeBase, "file://"))
  64.                     {
  65.                         flag = true;
  66.                         codeBase = codeBase.Substring("file:".Length);
  67.                     }
  68.                     if (flag)
  69.                     {
  70.                         codeBase = codeBase.Replace('/''//');
  71.                         applicationFilename = codeBase;
  72.                     }
  73.                     else
  74.                     {
  75.                         codeBase = exeAssembly.EscapedCodeBase;
  76.                     }
  77.             }
  78.             else
  79.             {
  80.                 codeBase = Path.GetFullPath(exePath);
  81.                 if (!File.Exists(codeBase))
  82.                 {
  83.                     throw new Exception();
  84.                 }
  85.                 applicationFilename = codeBase;
  86.             }
  87.             if (this._applicationConfigUri == null)
  88.             {
  89.                 this._applicationConfigUri = codeBase + ".config";
  90.             }
  91.             this._applicationUri = codeBase;
  92.             if ((exePath == null) && this._includesUserConfig)
  93.             {
  94.                 this.SetNamesAndVersion(applicationFilename, exeAssembly, false);
  95.                 string str5 = this.Validate(this._companyName, true);
  96.                 string str6 = this.Validate(AppDomain.CurrentDomain.FriendlyName, true);
  97.                 string str7 = !string.IsNullOrEmpty(this._applicationUri) ? this._applicationUri.ToLower
  98. (CultureInfo.InvariantCulture) : null;
  99.                 string str8 = !string.IsNullOrEmpty(str6) ? str6 : this.Validate(this._productName, true);
  100.                 string typeAndHashSuffix = this.GetTypeAndHashSuffix(AppDomain.CurrentDomain, str7);
  101.                     string str10 = (!string.IsNullOrEmpty(str8) && !string.IsNullOrEmpty(typeAndHashSuffix)) ? 
  102. (str8 + typeAndHashSuffix) : null;
  103.                     string str11 = this.Validate(this._productVersion, false);
  104.                     string str12 = this.CombineIfValid(this.CombineIfValid(str5, str10), str11);
  105.                     string path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
  106.                     if (Path.IsPathRooted(path))
  107.                     {
  108.                         UserConfigFilePath = this.CombineIfValid(path, str12);
  109.                         UserConfigFilePath = this.CombineIfValid(UserConfigFilePath, "user.config");
  110.                     }
  111.             }
  112.             return UserConfigFilePath;
  113.         }
  114.         private string CombineIfValid(string path1, string path2)
  115.         {
  116.             string str = null;
  117.             if ((path1 != null) && (path2 != null))
  118.             {
  119.                 try
  120.                 {
  121.                     string str2 = Path.Combine(path1, path2);
  122.                     if (str2.Length < 260)
  123.                     {
  124.                         str = str2;
  125.                     }
  126.                 }
  127.                 catch
  128.                 {
  129.                 }
  130.             }
  131.             return str;
  132.         }
  133.         private static object GetEvidenceInfo(AppDomain appDomain, string exePath, out string typeName)
  134.         {
  135.             ControlEvidencePermission.Assert();
  136.             Evidence evidence = appDomain.Evidence;
  137.             StrongName sn = null;
  138.             Url url = null;
  139.             if (evidence != null)
  140.             {
  141.                 IEnumerator hostEnumerator = evidence.GetHostEnumerator();
  142.                 object current = null;
  143.                 while (hostEnumerator.MoveNext())
  144.                 {
  145.                     current = hostEnumerator.Current;
  146.                     if (current is StrongName)
  147.                     {
  148.                         sn = (StrongName) current;
  149.                         break;
  150.                     }
  151.                     if (current is Url)
  152.                     {
  153.                         url = (Url) current;
  154.                     }
  155.                 }
  156.             }
  157.             object obj3 = null;
  158.             if (sn != null)
  159.             {
  160.                 obj3 = MakeVersionIndependent(sn);
  161.                 typeName = "StrongName";
  162.                 return obj3;
  163.             }
  164.             if (url != null)
  165.             {
  166.                 obj3 = url.Value.ToUpperInvariant();
  167.                 typeName = "Url";
  168.                 return obj3;
  169.             }
  170.             if (exePath != null)
  171.             {
  172.                 obj3 = exePath;
  173.                 typeName = "Path";
  174.                 return obj3;
  175.             }
  176.             typeName = null;
  177.             return obj3;
  178.         }
  179.         private static string GetHash(Stream s)
  180.         {
  181.             byte[] buffer;
  182.             using (SHA1 sha = new SHA1CryptoServiceProvider())
  183.             {
  184.                 buffer = sha.ComputeHash(s);
  185.             }
  186.             return ToBase32StringSuitableForDirName(buffer);
  187.         }
  188.         private string GetTypeAndHashSuffix(AppDomain appDomain, string exePath)
  189.         {
  190.             string str = null;
  191.             string typeName = null;
  192.             object graph = null;
  193.             graph = GetEvidenceInfo(appDomain, exePath, out typeName);
  194.             if ((graph != null) && !string.IsNullOrEmpty(typeName))
  195.             {
  196.                 MemoryStream serializationStream = new MemoryStream();
  197.                 BinaryFormatter formatter = new BinaryFormatter();
  198.                 SerializationFormatterPermission.Assert();
  199.                 formatter.Serialize(serializationStream, graph);
  200.                 serializationStream.Position = 0L;
  201.                 string hash = GetHash(serializationStream);
  202.                 if (!string.IsNullOrEmpty(hash))
  203.                 {
  204.                     str = "_" + typeName + "_" + hash;
  205.                 }
  206.             }
  207.             return str;
  208.         }
  209.         private static StrongName MakeVersionIndependent(StrongName sn)
  210.         {
  211.             return new StrongName(sn.PublicKey, sn.Name, new Version(0, 0, 0, 0));
  212.         }
  213.         private void SetNamesAndVersion(string applicationFilename, Assembly exeAssembly, bool isHttp)
  214.         {
  215.             Type reflectedType = null;
  216.             if (exeAssembly != null)
  217.             {
  218.                 object[] customAttributes = exeAssembly.GetCustomAttributes(typeof(AssemblyCompanyAttribute), 
  219. false);
  220.                 if ((customAttributes != null) && (customAttributes.Length > 0))
  221.                 {
  222.                     this._companyName = ((AssemblyCompanyAttribute) customAttributes[0]).Company;
  223.                     if (this._companyName != null)
  224.                     {
  225.                         this._companyName = this._companyName.Trim();
  226.                     }
  227.                 }
  228.                 customAttributes = exeAssembly.GetCustomAttributes(typeof(AssemblyProductAttribute), false);
  229.                 if ((customAttributes != null) && (customAttributes.Length > 0))
  230.                 {
  231.                     this._productName = ((AssemblyProductAttribute) customAttributes[0]).Product;
  232.                     if (this._productName != null)
  233.                     {
  234.                         this._productName = this._productName.Trim();
  235.                     }
  236.                 }
  237.                 this._productVersion = exeAssembly.GetName().Version.ToString();
  238.                 if (this._productVersion != null)
  239.                 {
  240.                     this._productVersion = this._productVersion.Trim();
  241.                 }
  242.             }
  243.             if (!isHttp && ((string.IsNullOrEmpty(this._companyName) || string.IsNullOrEmpty(this._productName)) || 
  244. string.IsNullOrEmpty(this._productVersion)))
  245.             {
  246.                 string fileName = null;
  247.                 if (exeAssembly != null)
  248.                 {
  249.                     MethodInfo entryPoint = exeAssembly.EntryPoint;
  250.                     if (entryPoint != null)
  251.                     {
  252.                         reflectedType = entryPoint.ReflectedType;
  253.                         if (reflectedType != null)
  254.                         {
  255.                             fileName = reflectedType.Module.FullyQualifiedName;
  256.                         }
  257.                     }
  258.                 }
  259.                 if (fileName == null)
  260.                 {
  261.                     fileName = applicationFilename;
  262.                 }
  263.                 if (fileName != null)
  264.                 {
  265.                     FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(fileName);
  266.                     if (versionInfo != null)
  267.                     {
  268.                         if (string.IsNullOrEmpty(this._companyName))
  269.                         {
  270.                             this._companyName = versionInfo.CompanyName;
  271.                             if (this._companyName != null)
  272.                             {
  273.                                 this._companyName = this._companyName.Trim();
  274.                             }
  275.                         }
  276.                         if (string.IsNullOrEmpty(this._productName))
  277.                         {
  278.                             this._productName = versionInfo.ProductName;
  279.                             if (this._productName != null)
  280.                             {
  281.                                 this._productName = this._productName.Trim();
  282.                             }
  283.                         }
  284.                         if (string.IsNullOrEmpty(this._productVersion))
  285.                         {
  286.                             this._productVersion = versionInfo.ProductVersion;
  287.                             if (this._productVersion != null)
  288.                             {
  289.                                 this._productVersion = this._productVersion.Trim();
  290.                             }
  291.                         }
  292.                     }
  293.                 }
  294.             }
  295.             if (string.IsNullOrEmpty(this._companyName) || string.IsNullOrEmpty(this._productName))
  296.             {
  297.                 string str2 = null;
  298.                 if (reflectedType != null)
  299.                 {
  300.                     str2 = reflectedType.Namespace;
  301.                 }
  302.                 if (string.IsNullOrEmpty(this._productName))
  303.                 {
  304.                     if (str2 != null)
  305.                     {
  306.                         int num = str2.LastIndexOf(".", StringComparison.Ordinal);
  307.                         if ((num != -1) && (num < (str2.Length - 1)))
  308.                         {
  309.                             this._productName = str2.Substring(num + 1);
  310.                         }
  311.                         else
  312.                         {
  313.                             this._productName = str2;
  314.                         }
  315.                         this._productName = this._productName.Trim();
  316.                     }
  317.                     if (string.IsNullOrEmpty(this._productName) && (reflectedType != null))
  318.                     {
  319.                         this._productName = reflectedType.Name.Trim();
  320.                     }
  321.                     if (this._productName == null)
  322.                     {
  323.                         this._productName = string.Empty;
  324.                     }
  325.                 }
  326.                 if (string.IsNullOrEmpty(this._companyName))
  327.                 {
  328.                     if (str2 != null)
  329.                     {
  330.                         int index = str2.IndexOf(".", StringComparison.Ordinal);
  331.                         if (index != -1)
  332.                         {
  333.                             this._companyName = str2.Substring(0, index);
  334.                         }
  335.                         else
  336.                         {
  337.                             this._companyName = str2;
  338.                         }
  339.                         this._companyName = this._companyName.Trim();
  340.                     }
  341.                     if (string.IsNullOrEmpty(this._companyName))
  342.                     {
  343.                         this._companyName = this._productName;
  344.                     }
  345.                 }
  346.             }
  347.             if (string.IsNullOrEmpty(this._productVersion))
  348.             {
  349.                 this._productVersion = "1.0.0.0";
  350.             }
  351.         }
  352.         private static string ToBase32StringSuitableForDirName(byte[] buff)
  353.         {
  354.             StringBuilder builder = new StringBuilder();
  355.             int length = buff.Length;
  356.             int num7 = 0;
  357.             do
  358.             {
  359.                 byte num = (num7 < length) ? buff[num7++] : ((byte) 0);
  360.                 byte num2 = (num7 < length) ? buff[num7++] : ((byte) 0);
  361.                 byte index = (num7 < length) ? buff[num7++] : ((byte) 0);
  362.                 byte num4 = (num7 < length) ? buff[num7++] : ((byte) 0);
  363.                 byte num5 = (num7 < length) ? buff[num7++] : ((byte) 0);
  364.                 builder.Append(s_Base32Char[num & 0x1f]);
  365.                 builder.Append(s_Base32Char[num2 & 0x1f]);
  366.                 builder.Append(s_Base32Char[index & 0x1f]);
  367.                 builder.Append(s_Base32Char[num4 & 0x1f]);
  368.                 builder.Append(s_Base32Char[num5 & 0x1f]);
  369.                 builder.Append(s_Base32Char[((num & 0xe0) >> 5) | ((num4 & 0x60) >> 2)]);
  370.                 builder.Append(s_Base32Char[((num2 & 0xe0) >> 5) | ((num5 & 0x60) >> 2)]);
  371.                 index = (byte) (index >> 5);
  372.                 if ((num4 & 0x80) != 0)
  373.                 {
  374.                     index = (byte) (index | 8);
  375.                 }
  376.                 if ((num5 & 0x80) != 0)
  377.                 {
  378.                     index = (byte) (index | 0x10);
  379.                 }
  380.                 builder.Append(s_Base32Char[index]);
  381.             }
  382.             while (num7 < length);
  383.             return builder.ToString();
  384.         }
  385.         private string Validate(string str, bool limitSize)
  386.         {
  387.             string str2 = str;
  388.             if (!string.IsNullOrEmpty(str2))
  389.             {
  390.                 foreach (char ch in Path.GetInvalidFileNameChars())
  391.                 {
  392.                     str2 = str2.Replace(ch, '_');
  393.                 }
  394.                 str2 = str2.Replace(' ''_');
  395.                 if (limitSize)
  396.                 {
  397.                     str2 = (str2.Length > 0x19) ? str2.Substring(0, 0x19) : str2;
  398.                 }
  399.             }
  400.             return str2;
  401.         }
  402.         private static SecurityPermission ControlEvidencePermission
  403.         {
  404.             get
  405.             {
  406.                 if (s_controlEvidencePerm == null)
  407.                 {
  408.                     s_controlEvidencePerm = new SecurityPermission(SecurityPermissionFlag.ControlEvidence);
  409.                 }
  410.                 return s_controlEvidencePerm;
  411.             }
  412.         }
  413.         private static SecurityPermission SerializationFormatterPermission
  414.         {
  415.             get
  416.             {
  417.                 if (s_serializationPerm == null)
  418.                 {
  419.                     s_serializationPerm = new SecurityPermission(SecurityPermissionFlag.SerializationFormatter);
  420.                 }
  421.                 return s_serializationPerm;
  422.             }
  423.         }
  424.     }

StringUtil类

 
  1.   //StringUtil类
  2.     using System;
  3.     internal static class StringUtil
  4.     {
  5.         internal static bool EqualsIgnoreCase(string s1, string s2)
  6.         {
  7.             return string.Equals(s1, s2, StringComparison.OrdinalIgnoreCase);
  8.         }
  9.         internal static bool EqualsNE(string s1, string s2)
  10.         {
  11.             if (s1 == null)
  12.             {
  13.                 s1 = string.Empty;
  14.             }
  15.             if (s2 == null)
  16.             {
  17.                 s2 = string.Empty;
  18.             }
  19.             return string.Equals(s1, s2, StringComparison.Ordinal);
  20.         }
  21.         internal static string[] ObjectArrayToStringArray(object[] objectArray)
  22.         {
  23.             string[] array = new string[objectArray.Length];
  24.             objectArray.CopyTo(array, 0);
  25.             return array;
  26.         }
  27.         internal static bool StartsWith(string s1, string s2)
  28.         {
  29.             if (s2 == null)
  30.             {
  31.                 return false;
  32.             }
  33.             return (0 == string.Compare(s1, 0, s2, 0, s2.Length, StringComparison.Ordinal));
  34.         }
  35.         internal static bool StartsWithIgnoreCase(string s1, string s2)
  36.         {
  37.             if (s2 == null)
  38.             {
  39.                 return false;
  40.             }
  41.             return (0 == string.Compare(s1, 0, s2, 0, s2.Length, StringComparison.OrdinalIgnoreCase));
  42.         }
  43.     }

 

你可能感兴趣的:(.NET技术)