ClientConfigPaths
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
namespace System.Configuration
{
internal sealed class ClientConfigPaths
{
internal const string UserConfigFilename = "user.config";
private const string ConfigExtension = ".config";
private const int MaxLengthToUse = 25;
private const string HttpUri = "http://";
private const string StrongNameDesc = "StrongName";
private const string UrlDesc = "Url";
private const string PathDesc = "Path";
private static volatile ClientConfigPaths s_current;
private static volatile bool s_currentIncludesUserConfig;
private readonly bool _includesUserConfig;
private string _companyName;
internal static ClientConfigPaths Current => GetPaths(null, true);
internal bool HasEntryAssembly { get; }
internal string ApplicationUri { get; }
internal string ApplicationConfigUri { get; }
internal string RoamingConfigFilename { get; }
internal string RoamingConfigDirectory { get; }
internal bool HasRoamingConfig {
get {
if (RoamingConfigFilename == null)
return !_includesUserConfig;
return true;
}
}
internal string LocalConfigFilename { get; }
internal string LocalConfigDirectory { get; }
internal bool HasLocalConfig {
get {
if (LocalConfigFilename == null)
return !_includesUserConfig;
return true;
}
}
internal string ProductName { get; set; }
internal string ProductVersion { get; set; }
[UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file", Justification = "Code handles single file case")]
[UnconditionalSuppressMessage("SingleFile", "IL3002: RequiresAssemblyFiles on Module.Name", Justification = "Code handles single file case")]
private ClientConfigPaths(string exePath, bool includeUserConfig)
{
_includesUserConfig = includeUserConfig;
Assembly assembly = null;
bool flag = false;
if (exePath != null) {
ApplicationUri = Path.GetFullPath(exePath);
if (!File.Exists(ApplicationUri))
throw ExceptionUtil.ParameterInvalid("exePath");
} else {
assembly = Assembly.GetEntryAssembly();
if ((object)assembly != null && assembly.Location.Length == 0) {
flag = true;
HasEntryAssembly = true;
}
if (!(assembly != (Assembly)null) || flag)
try {
using (Process process = Process.GetCurrentProcess())
ApplicationUri = process.MainModule?.FileName;
} catch (PlatformNotSupportedException) {
ApplicationUri = string.Empty;
}
else {
HasEntryAssembly = true;
ApplicationUri = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, assembly.ManifestModule.Name);
}
}
string text = AppDomain.CurrentDomain.GetData("APP_CONFIG_FILE") as string;
if (!string.IsNullOrEmpty(text)) {
if (Uri.IsWellFormedUriString(text, UriKind.Absolute)) {
Uri uri = new Uri(text, UriKind.Absolute);
if (uri.IsFile)
ApplicationConfigUri = uri.LocalPath;
} else {
if (!Path.IsPathRooted(text))
text = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, text);
ApplicationConfigUri = Path.GetFullPath(text);
}
} else if (!string.IsNullOrEmpty(ApplicationUri)) {
string str = ApplicationUri;
if (flag)
str = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? Path.ChangeExtension(ApplicationUri, ".dll") : (ApplicationUri + ".dll"));
ApplicationConfigUri = str + ".config";
}
if (exePath == null && _includesUserConfig) {
bool flag2 = StringUtil.StartsWithOrdinalIgnoreCase(ApplicationConfigUri, "http://");
SetNamesAndVersion(assembly, flag2);
if (!flag2) {
string path = Validate(_companyName, true);
string text2 = Validate(AppDomain.CurrentDomain.FriendlyName, true);
if (string.IsNullOrEmpty(text2))
text2 = Validate(ProductName, true);
string exePath2 = (!string.IsNullOrEmpty(ApplicationUri)) ? ApplicationUri.ToLowerInvariant() : null;
string typeAndHashSuffix = GetTypeAndHashSuffix(exePath2, flag);
string path2 = (!string.IsNullOrEmpty(text2) && !string.IsNullOrEmpty(typeAndHashSuffix)) ? (text2 + typeAndHashSuffix) : null;
string path3 = Validate(ProductVersion, false);
string path4 = CombineIfValid(CombineIfValid(path, path2), path3);
string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
if (Path.IsPathRooted(folderPath)) {
RoamingConfigDirectory = CombineIfValid(folderPath, path4);
RoamingConfigFilename = CombineIfValid(RoamingConfigDirectory, "user.config");
}
string folderPath2 = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
if (Path.IsPathRooted(folderPath2)) {
LocalConfigDirectory = CombineIfValid(folderPath2, path4);
LocalConfigFilename = CombineIfValid(LocalConfigDirectory, "user.config");
}
}
}
}
internal static ClientConfigPaths GetPaths(string exePath, bool includeUserConfig)
{
if (exePath != null)
return new ClientConfigPaths(exePath, includeUserConfig);
if (s_current == null || (includeUserConfig && !s_currentIncludesUserConfig)) {
s_current = new ClientConfigPaths(null, includeUserConfig);
s_currentIncludesUserConfig = includeUserConfig;
}
return s_current;
}
internal static void RefreshCurrent()
{
s_currentIncludesUserConfig = false;
s_current = null;
}
private static string CombineIfValid(string path1, string path2)
{
if (path1 != null && path2 != null)
try {
return Path.Combine(path1, path2);
} catch {
return null;
}
return null;
}
[UnconditionalSuppressMessage("SingleFile", "IL3002: RequiresAssemblyFiles on Module.Name", Justification = "Code handles single file case")]
private static string GetTypeAndHashSuffix(string exePath, bool isSingleFile)
{
Assembly entryAssembly = Assembly.GetEntryAssembly();
string result = null;
string str = null;
string text = null;
if (entryAssembly != (Assembly)null && !isSingleFile) {
AssemblyName name = entryAssembly.GetName();
try {
text = IdentityHelper.GetNormalizedStrongNameHash(name);
} catch (PlatformNotSupportedException) {
}
Uri result2;
if (text != null)
str = "StrongName";
else if (Uri.TryCreate(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, entryAssembly.ManifestModule.Name), UriKind.Absolute, out result2)) {
try {
text = IdentityHelper.GetNormalizedUriHash(result2);
str = "Url";
} catch (PlatformNotSupportedException) {
}
}
} else if (!string.IsNullOrEmpty(exePath)) {
try {
text = IdentityHelper.GetStrongHashSuitableForObjectName(exePath);
str = "Path";
} catch (PlatformNotSupportedException) {
}
}
if (!string.IsNullOrEmpty(text))
result = "_" + str + "_" + text;
return result;
}
private void SetNamesAndVersion(Assembly exeAssembly, bool isHttp)
{
Type type = null;
if (exeAssembly != (Assembly)null) {
object[] customAttributes = exeAssembly.GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
if (customAttributes != null && customAttributes.Length != 0)
_companyName = ((AssemblyCompanyAttribute)customAttributes[0]).Company?.Trim();
customAttributes = exeAssembly.GetCustomAttributes(typeof(AssemblyProductAttribute), false);
if (customAttributes != null && customAttributes.Length != 0)
ProductName = ((AssemblyProductAttribute)customAttributes[0]).Product?.Trim();
ProductVersion = exeAssembly.GetName().Version.ToString().Trim();
}
if (!isHttp && (string.IsNullOrEmpty(_companyName) || string.IsNullOrEmpty(ProductName) || string.IsNullOrEmpty(ProductVersion))) {
if (exeAssembly != (Assembly)null) {
MethodInfo entryPoint = exeAssembly.EntryPoint;
if (entryPoint != (MethodInfo)null)
type = entryPoint.ReflectedType;
}
string text = null;
if (type != (Type)null)
text = type.Namespace;
if (string.IsNullOrEmpty(ProductName)) {
if (text != null) {
int num = text.LastIndexOf('.');
if (num != -1 && num < text.Length - 1)
ProductName = text.Substring(num + 1);
else
ProductName = text;
ProductName = ProductName.Trim();
}
if (string.IsNullOrEmpty(ProductName) && type != (Type)null)
ProductName = type.Name.Trim();
if (ProductName == null)
ProductName = string.Empty;
}
if (string.IsNullOrEmpty(_companyName)) {
if (text != null) {
int num2 = text.IndexOf('.');
_companyName = ((num2 != -1) ? text.Substring(0, num2) : text);
_companyName = _companyName.Trim();
}
if (string.IsNullOrEmpty(_companyName))
_companyName = ProductName;
}
}
if (string.IsNullOrEmpty(ProductVersion))
ProductVersion = "1.0.0.0";
}
private static string Validate(string str, bool limitSize)
{
string text = str;
if (string.IsNullOrEmpty(text))
return text;
char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
foreach (char oldChar in invalidFileNameChars) {
text = text.Replace(oldChar, '_');
}
text = text.Replace(' ', '_');
if (limitSize)
text = ((text.Length > 25) ? text.Substring(0, 25) : text);
return text;
}
}
}