如何在用户中获取哈希值.配置路径
本文关键字:哈希值 配置 路径 获取 用户 | 更新日期: 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类型,它采用
形式的Urifile:///c:'app'app.exe
这个uri然后被转换成大写(不变),然后SHA-1哈希,然后哈希用base32编码。我不知道参考源中使用的base32是否是标准的base32实现(如果存在的话)。