Как получить хеш-значение в пути user.config?

Я установил.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 длиной 40 символов. Кажется, что [hash]=base32(sha1([install path]))

Я пробовал разные значения для [install path]

c: \ Program Files...
file: /// c: \ Program Files....
file: /// c: \ Program% 20Files... и т. д.

но [hash] всегда неправильно.

2 ответа

Пройдя через ту же проблему, пытаясь вычислить программу user.config (локальный) путь, я решил дополнить ответ @Gerard Sexton фрагментом кода. Следующий метод был сделан с предположением, что [eid] равняется "Url" а также [appdomainname] имя исполняемого файла

public string GetExeLocalAppDataUserConfigPath(string exeFullPath)
{
    //E.g.: exeFullPath = @"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(appDataLocalPath, companyName, exeName+"_Url_"+hashstring, version, "user.config");

    return userConfigLocalAppDataPath;
}

А вот и 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 вы можете увидеть, как хеш определяется из данных текущего домена приложений.

В основном, для типа Uri, он принимает Uri в виде

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

Затем этот uri преобразуется в верхний регистр (инвариант), затем хэшируется SHA-1, затем хеш кодируется в base32. Я не знаю, является ли base32, используемый в указанном источнике, стандартной реализацией base32 или нет (если она существует).

Другие вопросы по тегам