Alexander Ulanov
Alexander Ulanov

Reputation: 71

Get values of evidence eid and hash in user settings path construction

By default user settings of win application are stored in the following directory

Vista/7

C:\Users\<userId>\AppData\Local\Application Data\<companyname>\appdomainname>_<eid>_<hash>\<verison>

XP

C:\Documents and Settings>\<username>\[Local Settings\]Application Data\<companyname>\appdomainname>_<eid>_<hash>\<verison>

I need to know how to get values of eid and hash.

I'm trying to get that information from the AppDomain.CurrentDomain.Evidence and then check values I'm getting from GetHostEnumerator() but they aren't fit the actual directory path values.

For Example I have the following values

Some.exe_StrongName_fymjkuum4xrf5aopfjlsem3elhvjbgag

But the information I recieved from code is

<StrongName version="1"
Key="002400000480000094000000060200000024000052534131000400000100010027BFE9320943DDB4271C78B6B890E7BF02ECAA65585E252D8FBF07888FAAC54D8F8EF25C65061D4F8B904699701BF437F5A69BBDB6A496B989F8FD96853E43C621A84C187AF9EA90C0DAF7F32134A3BD42E94023DBB601C864CA1FF0B5E520CD090A4B90EDB1F95628F750316DBCC9593603E033D72FD67F2707D2670A2D1EB2"
Name="Some"
Version="0.0.0.0"/>

<System.Security.Policy.Url version="1">
<Url>file:///R:/Some/Some.Utilities/bin/Debug/Some.EXE</Url>
</System.Security.Policy.Url>

<System.Security.Policy.Zone version="1">
<Zone>MyComputer</Zone>
</System.Security.Policy.Zone>

<System.Security.Policy.Hash version="2">
<hash algorithm="SHA1"
value="8B19FB026023FE0C239D96EECDDC0266D36B415B"/>
<hash algorithm="SHA256"
value="46AA666701E20EF698ABE20F60CD52162BD0D7B72B43D1B1EB82826E525ACE73"/>
<hash algorithm="MD5"
value="244B4EA2E084F98345FE56FB4460A436"/>
</System.Security.Policy.Hash>

By the way, my assembly is signing. May be it's the value from my key ?

Upvotes: 5

Views: 1396

Answers (2)

user566399
user566399

Reputation: 19

This may be bumping an old thread but figured I should add to this.

I tried to work out how to reconstruct the file path and ultimately gave up.

My use case was that user config files were sometimes corrupt and caused exceptions. Why/how they corrupted is not clear; users would often claim they didn't modify them, maybe freak crash mid-write of the XML?

Solution; try and open the config file, if it fails, catch the error, extract the config file path from the message, and delete it.

public static class ConfigFunctions
{
public const string CONFIG_EXT = ".CONFIG";

/// <summary>
/// Check that the config file can be opened - by default the localappdata user.config for entry assembly.
/// If it fails we may attempt to auto fix it (delete corrupt config file). For my use this was acceptable - but you may want to be more cautious.
/// Note: this *must* be run from the original entry assembly. You cannot access the config from a different EXE. If the EXE file is moved and executed elsewhere it will *also* be different
/// Note: I tried but could not manually create the EXE_URL_XXXX section of the file path of local user.config (I believe it's a URL to FILE PATH that's been hashed SHA1 Base36 but not sure).
/// </summary>
public static bool TryOpenConfig(System.Configuration.ConfigurationUserLevel configUserLevel = System.Configuration.ConfigurationUserLevel.PerUserRoamingAndLocal, bool attemptAutoFix = true)
{
    try
    {
    string errorMsg;
    var configFilePath = GetConfigFilePath(configUserLevel, attemptAutoFix, out errorMsg); // Try and get the config file path
    var errorOccurred = !string.IsNullOrWhiteSpace(errorMsg); // If we got an error message then an error occurred
    // Log config file path and/or error message?
    return !errorOccurred;
    }
    catch (Exception exc)
    {
    // Log this unexpected exception?
    throw; // Rethrow it preserving call stack
    }
}

/// <summary>
/// We try and get the config file path by opening the exe configuration.
/// If this fails, we try and get it from the config exception message.
/// We optionally delete the config file (helps auto fix problems)
/// We return the path, and if it errored or not (irrespective if we fixed it via delete).
/// </summary>
private static string GetConfigFilePath(System.Configuration.ConfigurationUserLevel configUserLevelLocal, bool deleteOnError, out string errorMsg)
{
    errorMsg = null; // Set this initially
    try
    {
    var config = System.Configuration.ConfigurationManager.OpenExeConfiguration(configUserLevelLocal); // Try and open using ConfigurationManager
    return config?.FilePath; // Return the file path from it (i.e. we opened successfully)
    }
    catch (System.Configuration.ConfigurationException configExc) // We had a configuration exc
    {
    errorMsg = configExc?.Message; // Set the message so we can return it but don't rethrow it - it's an "acceptable error"
    var configFilePathFromExc = configExc?.GetFilePath(); // Use our extension method to get the file path from this
    if (deleteOnError // If we want to delete on error (i.e. auto fix corrupt file) and the file exists...
        && !string.IsNullOrWhiteSpace(configFilePathFromExc)
        && System.IO.File.Exists(configFilePathFromExc))
    {
        System.IO.File.Delete(configFilePathFromExc); // Try and delete it (note, may throw exc)
    }
    return configFilePathFromExc;
    }
}

/// <summary>
/// We can try and get the file path from the exception message via some string manipulation.
/// </summary>
private static string GetFilePath(this System.Configuration.ConfigurationException configExc)
{
    var configExcMsg = configExc?.Message; // Get the error message
    var configExcMsgSplitOnBrackets = configExcMsg?.Split(new[] { '(', ')' }); // Split it on brackets (i.e. the config file is in here)
    var configExcMsgSubStrHasConfigExt = configExcMsgSplitOnBrackets?.LastOrDefault(s => s.IndexOf(CONFIG_EXT, StringComparison.OrdinalIgnoreCase) >= 0);
    if (!string.IsNullOrWhiteSpace(configExcMsgSubStrHasConfigExt))
    {
    configExcMsgSubStrHasConfigExt = configExcMsgSubStrHasConfigExt?.Trim(); // Trim it just incase leading space.
    var configExtPos = configExcMsgSubStrHasConfigExt?.LastIndexOf(CONFIG_EXT, StringComparison.OrdinalIgnoreCase) ?? -1; // Get where the extension of the file path is in the str
    if (configExtPos >= 0) // Paranoia guard - it will exist because we checked before
    {
        var configFilePathLen = configExtPos + CONFIG_EXT.Length; // The length of the file path will be the pos of the ext + length of the ext
        var configFilePath = configExcMsgSubStrHasConfigExt?.Substring(0, configFilePathLen); // Get the file path.
        return configFilePath; // Return it.
    }
    }
    return null; // Didn't find the path.
}

}

Upvotes: 0

Adam
Adam

Reputation: 2802

You can get the location where the settings file is saved to by default for your application by using the following line of code. From this you could extract the eid and hash.

string configPath = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath;

Upvotes: 3

Related Questions