【问题标题】:How to get hash value in user.config path?如何在 user.config 路径中​​获取哈希值?
【发布时间】:2014-08-30 20:37:05
【问题描述】:

我已经安装了 .NET 应用程序。它的配置位置是

%AppData%\[CompanyName]\[ExeName]_Url_[hash]\[version]\user.config.

我需要从另一个应用程序获取[hash] 值。

根据MSDNuser.config路径模板为

[c:\Documents and Settings]\[username]\[Local Settings]\Application Data\[companyname]\[appdomainname]_[eid]_[hash]\[version]

[hash] 是证据的 SHA1 哈希值(在我的例子中是 eid=Url)。

我注意到以下几点:

  • [hash] 随应用安装路径的变化而变化。
  • [hash] 始终是 32 个字符长,因此它不是 SHA1 的 40 个字符长的十六进制表示。看来[hash]=base32(sha1([install path]))

我为[install path] 尝试了不同的值

c:\Program Files...
file:///c:\Program Files....
file:///c:\Program%20Files...等

[hash] 总是错的。

【问题讨论】:

  • 您如何将 install path 转换为 byte[] 以输入 sha1?
  • 我的应用程序是用 C 编写的。它可以正确生成 SHA1(十六进制表示与在线 SHA1 生成器提供给我的相同)。
  • 您真的只需要获取哈希部分,还是在寻找user.config 文件的完整路径?如果是后者,请使用ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath

标签: c# .net hash user.config


【解决方案1】:

写入自定义位置的建议是提供您自己的SettingsProvider。默认设置提供程序是LocalFileSettingsProvider。 所以从LocalFileSettingsProvider 开始,然后按照代码到ConfigurationManagerInternalFactory,然后是ConfigurationManagerInternal,最后是ClientConfigPaths。在ClientConfigPaths:412 中,您可以看到 hash 是如何根据当前 AppDomain 的证据确定的。

基本上,对于 Uri 类型,它采用表单中的 Uri

file:///c:\app\app.exe

然后这个 uri 被转换为大写(不变),然后 SHA-1 散列,然后散列在 base32 中编码。我不知道引用源中使用的 base32 是否是标准的 base32 实现(如果存在)。

【讨论】:

    【解决方案2】:

    在尝试计算程序的user.config(本地)路径的相同问题后,我决定用代码 sn-p 补充@Gerard Sexton 的答案。以下方法是在假设[eid]等于"Url"[appdomainname]是可执行文件名的情况下完成的。

    public string GetExeLocalAppDataUserConfigPath(string fullExePath)
    {
        //E.g.: fullExePath = @"C:\Program Files (x86)\MyExeFolder\MyProgram.exe"
        var localAppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
    
        var versionInfo = FileVersionInfo.GetVersionInfo(fullExePath);
        var companyName = versionInfo.CompanyName;
        var exeName = versionInfo.OriginalFilename;// or 'AppDomain.CurrentDomain.FriendlyName'
    
        var assemblyName = AssemblyName.GetAssemblyName(fullExePath);
        var version = assemblyName.Version.ToString();
    
        var uri = "file:///" + fullExePath; //or 'assemblyName.CodeBase' if vshost (you can check the 'FriendlyName')
        uri = uri.ToUpperInvariant();
    
        var ms = new MemoryStream();
        var bSer = new BinaryFormatter();
        bSer.Serialize(ms, uri);
        ms.Position = 0;
        var sha1 = new SHA1CryptoServiceProvider();
        var hash = sha1.ComputeHash(ms);
        var hashstring = ToBase32StringSuitableForDirName(hash);
    
        //<AppData Local User Path> + <Company Name> + <[ExeName]_[eid]_[Hash]> + <Version> + user.config
        var userConfigLocalAppDataPath = Path.Combine(localAppDataPath, companyName, exeName+"_Url_"+hashstring, version, "user.config");
    
        return userConfigLocalAppDataPath;
    }
    

    这是 Gerard 的 link 中的 ToBase32StringSuitableForDirName 实现!

    static Char[] s_Base32Char = {
                '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 string ToBase32StringSuitableForDirName(byte[] buff)
    {
        StringBuilder sb = new StringBuilder();
        byte b0, b1, b2, b3, b4;
        int l, i;
    
        l = buff.Length;
        i = 0;
    
        // Create l chars using the last 5 bits of each byte.  
        // Consume 3 MSB bits 5 bytes at a time.
    
        do
        {
            b0 = (i < l) ? buff[i++] : (byte)0;
            b1 = (i < l) ? buff[i++] : (byte)0;
            b2 = (i < l) ? buff[i++] : (byte)0;
            b3 = (i < l) ? buff[i++] : (byte)0;
            b4 = (i < l) ? buff[i++] : (byte)0;
    
            // Consume the 5 Least significant bits of each byte
            sb.Append(s_Base32Char[b0 & 0x1F]);
            sb.Append(s_Base32Char[b1 & 0x1F]);
            sb.Append(s_Base32Char[b2 & 0x1F]);
            sb.Append(s_Base32Char[b3 & 0x1F]);
            sb.Append(s_Base32Char[b4 & 0x1F]);
    
            // Consume 3 MSB of b0, b1, MSB bits 6, 7 of b3, b4
            sb.Append(s_Base32Char[(
                ((b0 & 0xE0) >> 5) |
                ((b3 & 0x60) >> 2))]);
    
            sb.Append(s_Base32Char[(
                ((b1 & 0xE0) >> 5) |
                ((b4 & 0x60) >> 2))]);
    
            // Consume 3 MSB bits of b2, 1 MSB bit of b3, b4
    
            b2 >>= 5;
    
            if ((b3 & 0x80) != 0)
                b2 |= 0x08;
            if ((b4 & 0x80) != 0)
                b2 |= 0x10;
    
            sb.Append(s_Base32Char[b2]);
    
        } while (i < l);
    
        return sb.ToString();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-30
      • 1970-01-01
      • 2013-01-09
      • 2010-12-19
      • 2013-09-07
      • 1970-01-01
      • 1970-01-01
      • 2012-07-05
      相关资源
      最近更新 更多