如何在用户中获取哈希值.配置路径

本文关键字:哈希值 配置 路径 获取 用户 | 更新日期: 2023-09-27 18:12:16

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

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

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

根据MSDN, user.config路径模板为

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

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

我注意到以下事情:

  • [hash]随着应用程序安装路径的改变而改变。
  • [hash]总是32个字符长,所以它不是SHA1的十六进制表示,SHA1是40个字符长。似乎[hash]=base32(sha1([install path]))

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

c: '程序文件…
file:///c:'Program Files....
文件:///c: '程序% 20文件…等

[hash]总是错的

如何在用户中获取哈希值.配置路径

在尝试计算程序的user.config(本地)路径的相同问题之后,我决定用一个代码片段来补充@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的链接中找到的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();
}

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

基本上,对于Uri类型,它采用

形式的Uri
file:///c:'app'app.exe

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