Updates project to add powershell module
This commit is contained in:
@@ -0,0 +1,24 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.Loader;
|
||||||
|
|
||||||
|
namespace Lithnet.CredentialProvider.RegistrationTool
|
||||||
|
{
|
||||||
|
internal static class AssemblyContextResourceLoader
|
||||||
|
{
|
||||||
|
private static readonly DependencyAssemblyLoadContext dependencyLoadContext = new DependencyAssemblyLoadContext();
|
||||||
|
|
||||||
|
public static Assembly LoadIntoAlc(Stream stream)
|
||||||
|
{
|
||||||
|
return dependencyLoadContext.LoadFromStream(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DependencyAssemblyLoadContext : AssemblyLoadContext
|
||||||
|
{
|
||||||
|
protected override Assembly Load(AssemblyName assemblyName)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Lithnet.CredentialProvider.RegistrationTool
|
||||||
|
{
|
||||||
|
public class CredentialProviderRegistrationData
|
||||||
|
{
|
||||||
|
public bool IsComRegistered { get; set; }
|
||||||
|
|
||||||
|
public bool IsCredentialProviderRegistered { get; set; }
|
||||||
|
|
||||||
|
public bool IsCredentalProviderEnabled { get; set; }
|
||||||
|
|
||||||
|
public string CredentialProviderName { get; set; }
|
||||||
|
|
||||||
|
public Guid Clsid { get; set; }
|
||||||
|
|
||||||
|
public string ProgId { get; set; }
|
||||||
|
|
||||||
|
public string DllPath { get; set; }
|
||||||
|
|
||||||
|
public DllType DllType { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,443 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Metadata;
|
||||||
|
using System.Reflection.PortableExecutable;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Microsoft.Win32;
|
||||||
|
|
||||||
|
namespace Lithnet.CredentialProvider.RegistrationTool
|
||||||
|
{
|
||||||
|
public static class CredentialProviderRegistrationServices
|
||||||
|
{
|
||||||
|
public static bool IsManagedAssembly(string path)
|
||||||
|
{
|
||||||
|
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||||
|
{
|
||||||
|
using (var peReader = new PEReader(fs))
|
||||||
|
{
|
||||||
|
if (!peReader.HasMetadata)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MetadataReader reader = peReader.GetMetadataReader();
|
||||||
|
return reader.IsAssembly;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<CredentialProviderRegistrationData> GetCredentalProviders()
|
||||||
|
{
|
||||||
|
var cpKeys = Registry.LocalMachine.OpenSubKey($@"Software\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers");
|
||||||
|
foreach (var clsid in cpKeys.GetSubKeyNames())
|
||||||
|
{
|
||||||
|
if (Guid.TryParse(clsid, out Guid result))
|
||||||
|
{
|
||||||
|
yield return GetCredentialProvider(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CredentialProviderRegistrationData GetCredentialProvider(Type type)
|
||||||
|
{
|
||||||
|
var comGuid = GetComGuid(type);
|
||||||
|
return GetCredentialProvider(comGuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CredentialProviderRegistrationData GetCredentialProvider(string progId)
|
||||||
|
{
|
||||||
|
var clsid = GetClsidFromProgId(progId);
|
||||||
|
return GetCredentialProvider(clsid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CredentialProviderRegistrationData GetCredentialProvider(Guid clsid)
|
||||||
|
{
|
||||||
|
CredentialProviderRegistrationData data = new CredentialProviderRegistrationData();
|
||||||
|
|
||||||
|
data.Clsid = clsid;
|
||||||
|
|
||||||
|
var clsidKey = Registry.ClassesRoot.OpenSubKey($@"CLSID\{clsid:B}");
|
||||||
|
if (clsidKey != null)
|
||||||
|
{
|
||||||
|
var inprocKey = clsidKey.OpenSubKey("InprocServer32");
|
||||||
|
data.IsComRegistered = inprocKey != null;
|
||||||
|
|
||||||
|
if (data.IsComRegistered)
|
||||||
|
{
|
||||||
|
var coreLib = inprocKey.GetValue(string.Empty) as string;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(coreLib))
|
||||||
|
{
|
||||||
|
data.IsComRegistered = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (string.Equals(coreLib, "mscoree.dll", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
data.DllType = DllType.NetFramework;
|
||||||
|
data.DllPath = inprocKey.GetValue("CodeBase") as string;
|
||||||
|
}
|
||||||
|
else if (coreLib.EndsWith(".comhost.dll", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
data.DllType = DllType.NetCore;
|
||||||
|
var i = coreLib.IndexOf(".comhost.dll", StringComparison.OrdinalIgnoreCase);
|
||||||
|
data.DllPath = coreLib.Substring(0, i) + ".dll";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.DllType = DllType.Native;
|
||||||
|
data.DllPath = coreLib;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data.ProgId = Registry.ClassesRoot.OpenSubKey($@"CLSID\{clsid:B}\ProgId")?.GetValue(string.Empty) as string;
|
||||||
|
|
||||||
|
var cpkey = Registry.LocalMachine.OpenSubKey($@"Software\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{clsid:B}");
|
||||||
|
data.IsCredentialProviderRegistered = cpkey != null;
|
||||||
|
|
||||||
|
if (data.IsCredentialProviderRegistered)
|
||||||
|
{
|
||||||
|
int? disabled = cpkey.GetValue("Disabled", 0) as int?;
|
||||||
|
data.IsCredentalProviderEnabled = disabled == null || disabled == 0;
|
||||||
|
data.CredentialProviderName = cpkey.GetValue(string.Empty) as string;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UnregisterCredentialProvider(Type type, bool unregisterCom)
|
||||||
|
{
|
||||||
|
DeleteCredentialProviderRegistration(type);
|
||||||
|
|
||||||
|
if (unregisterCom)
|
||||||
|
{
|
||||||
|
if (IsFrameworkType(type))
|
||||||
|
{
|
||||||
|
UnregisterFrameworkAssembly(type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UnregisterNetCoreAssembly(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UnregisterCredentialProvider(Guid clsid, bool unregisterCom)
|
||||||
|
{
|
||||||
|
DeleteCredentialProviderRegistration(clsid);
|
||||||
|
|
||||||
|
if (unregisterCom)
|
||||||
|
{
|
||||||
|
UnregisterClass(clsid);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RegisterCredentialProvider(Type type)
|
||||||
|
{
|
||||||
|
CreateCredentialProviderRegistration(type);
|
||||||
|
|
||||||
|
if (IsFrameworkType(type))
|
||||||
|
{
|
||||||
|
RegisterFrameworkAssembly(type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RegisterNetCoreAssembly(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DisableCredentialProvider(Type type)
|
||||||
|
{
|
||||||
|
var comGuid = GetComGuid(type);
|
||||||
|
DisableCredentialProvider(comGuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DisableCredentialProvider(Guid comGuid)
|
||||||
|
{
|
||||||
|
var key = Registry.LocalMachine.OpenSubKey($@"SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{comGuid:B}", true);
|
||||||
|
key?.SetValue("Disabled", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EnableCredentialProvider(string progId)
|
||||||
|
{
|
||||||
|
var clsid = GetClsidFromProgId(progId);
|
||||||
|
EnableCredentialProvider(clsid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DisableCredentialProvider(string progId)
|
||||||
|
{
|
||||||
|
var clsid = GetClsidFromProgId(progId);
|
||||||
|
DisableCredentialProvider(clsid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EnableCredentialProvider(Guid comGuid)
|
||||||
|
{
|
||||||
|
var key = Registry.LocalMachine.OpenSubKey($@"SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{comGuid:B}", true);
|
||||||
|
key?.SetValue("Disabled", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EnableCredentialProvider(Type type)
|
||||||
|
{
|
||||||
|
var comGuid = GetComGuid(type);
|
||||||
|
EnableCredentialProvider(comGuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateCredentialProviderRegistration(Type t)
|
||||||
|
{
|
||||||
|
var comGuid = GetComGuid(t);
|
||||||
|
var typeName = GetTypeFullName(t);
|
||||||
|
|
||||||
|
var key = Registry.LocalMachine.CreateSubKey($@"SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{comGuid:B}", true);
|
||||||
|
key.SetValue(null, typeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DeleteCredentialProviderRegistration(Type t)
|
||||||
|
{
|
||||||
|
var comGuid = GetComGuid(t);
|
||||||
|
DeleteCredentialProviderRegistration(comGuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DeleteCredentialProviderRegistration(Guid clsid)
|
||||||
|
{
|
||||||
|
Registry.LocalMachine.DeleteSubKeyTree($@"SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{clsid:B}", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RegisterNetCoreAssembly(Type t)
|
||||||
|
{
|
||||||
|
var comGuid = GetComGuid(t);
|
||||||
|
var typeName = GetTypeFullName(t);
|
||||||
|
var progId = GetComProgId(t);
|
||||||
|
var assemblyLocation = GetTypeAssemblyLocation(t);
|
||||||
|
|
||||||
|
var dir = Path.GetDirectoryName(assemblyLocation);
|
||||||
|
var assemblyFile = Path.GetFileNameWithoutExtension(assemblyLocation);
|
||||||
|
var comHostLocation = Path.Combine(dir, assemblyFile + ".comhost.dll");
|
||||||
|
|
||||||
|
var rootClsid = Registry.LocalMachine.CreateSubKey($@"Software\Classes\CLSID\{comGuid:B}", true);
|
||||||
|
rootClsid.SetValue(null, "CoreCLR COMHost Server");
|
||||||
|
|
||||||
|
var inprocKey = rootClsid.CreateSubKey("InprocServer32", true);
|
||||||
|
inprocKey.SetValue(null, comHostLocation);
|
||||||
|
inprocKey.SetValue("ThreadingModel", "Both");
|
||||||
|
|
||||||
|
var progIdKey = rootClsid.CreateSubKey("ProgId", true);
|
||||||
|
progIdKey.SetValue(null, progId);
|
||||||
|
|
||||||
|
var progIdRoot = Registry.LocalMachine.CreateSubKey($@"Software\Classes\{progId}", true);
|
||||||
|
progIdRoot.SetValue(null, typeName);
|
||||||
|
var progIdSubKey = progIdRoot.CreateSubKey("CLSID");
|
||||||
|
progIdSubKey.SetValue(null, comGuid.ToString("B"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UnregisterNetCoreAssembly(Type t)
|
||||||
|
{
|
||||||
|
var comGuid = GetComGuid(t);
|
||||||
|
var progId = GetComProgId(t);
|
||||||
|
|
||||||
|
UnregisterClass(comGuid, progId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UnregisterClass(Guid? clsid, string progId)
|
||||||
|
{
|
||||||
|
if (clsid != null)
|
||||||
|
{
|
||||||
|
Registry.LocalMachine.DeleteSubKeyTree($@"Software\Classes\CLSID\{clsid}", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(progId))
|
||||||
|
{
|
||||||
|
Registry.LocalMachine.DeleteSubKeyTree($@"Software\Classes\{progId}", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RegisterFrameworkAssembly(Type t)
|
||||||
|
{
|
||||||
|
var comGuid = GetComGuid(t);
|
||||||
|
var typeName = GetTypeFullName(t);
|
||||||
|
var progId = GetComProgId(t);
|
||||||
|
|
||||||
|
var rootClsid = Registry.LocalMachine.CreateSubKey($@"Software\Classes\CLSID\{comGuid:B}", true);
|
||||||
|
rootClsid.SetValue(null, typeName);
|
||||||
|
|
||||||
|
rootClsid.CreateSubKey("Implemented Categories");
|
||||||
|
rootClsid.CreateSubKey(@"Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}");
|
||||||
|
|
||||||
|
var inprocKey = rootClsid.CreateSubKey("InprocServer32", true);
|
||||||
|
inprocKey.SetValue(null, "mscoree.dll");
|
||||||
|
inprocKey.SetValue("ThreadingModel", "Both");
|
||||||
|
inprocKey.SetValue("Class", typeName);
|
||||||
|
inprocKey.SetValue("RuntimeVersion", "v4.0.30319");
|
||||||
|
inprocKey.SetValue("Assembly", GetTypeAssemblyName(t));
|
||||||
|
inprocKey.SetValue("CodeBase", GetTypeAssemblyLocation(t));
|
||||||
|
|
||||||
|
var progIdKey = rootClsid.CreateSubKey("ProgId", true);
|
||||||
|
progIdKey.SetValue(null, progId);
|
||||||
|
|
||||||
|
var progIdRoot = Registry.LocalMachine.CreateSubKey($@"Software\Classes\{progId}", true);
|
||||||
|
progIdRoot.SetValue(null, typeName);
|
||||||
|
var progIdSubKey = progIdRoot.CreateSubKey("CLSID");
|
||||||
|
progIdSubKey.SetValue(null, comGuid.ToString("B"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UnregisterFrameworkAssembly(Type t)
|
||||||
|
{
|
||||||
|
var comGuid = GetComGuid(t);
|
||||||
|
var progId = GetComProgId(t);
|
||||||
|
|
||||||
|
UnregisterClass(comGuid, progId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UnregisterClass(Guid clsid)
|
||||||
|
{
|
||||||
|
string progid = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
progid = GetProgIdFromClasid(clsid);
|
||||||
|
}
|
||||||
|
catch (NotFoundException) { }
|
||||||
|
|
||||||
|
UnregisterClass(clsid, progid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UnregisterClass(string progId)
|
||||||
|
{
|
||||||
|
Guid? clsid = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
clsid = GetClsidFromProgId(progId);
|
||||||
|
}
|
||||||
|
catch (NotFoundException) { }
|
||||||
|
|
||||||
|
UnregisterClass(clsid, progId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Guid GetClsidFromProgId(string progId)
|
||||||
|
{
|
||||||
|
var value = Registry.ClassesRoot.OpenSubKey($@"{progId}\CLSID")?.GetValue(string.Empty) as string;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(value))
|
||||||
|
{
|
||||||
|
throw new ClsidNotFoundException($"The clsid for ProgId was not found {progId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Guid.Parse(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetProgIdFromClasid(Guid clsid)
|
||||||
|
{
|
||||||
|
var value = Registry.ClassesRoot.OpenSubKey($@"CLSID\{clsid:B}\ProgId")?.GetValue(string.Empty) as string;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(value))
|
||||||
|
{
|
||||||
|
throw new ProgIdNotFoundException($"The ProgId for clsid was not found {clsid}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetTypeAssemblyLocation(Type type)
|
||||||
|
{
|
||||||
|
return type.Assembly.Location;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetTypeAssemblyName(Type type)
|
||||||
|
{
|
||||||
|
return type.Assembly.FullName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetTypeClassName(Type type)
|
||||||
|
{
|
||||||
|
return type.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetTypeFullName(Type type)
|
||||||
|
{
|
||||||
|
return type.FullName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Guid GetComGuid(Type type)
|
||||||
|
{
|
||||||
|
var typeId = type.GetCustomAttributeValue("GuidAttribute");
|
||||||
|
|
||||||
|
if (typeId == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"The type {type.Name} does not have the Guid attribute present");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Guid(typeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetComProgId(Type type)
|
||||||
|
{
|
||||||
|
var typeId = type.GetCustomAttributeValue("ProgIdAttribute");
|
||||||
|
|
||||||
|
if (typeId == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"The type {type.Name} does not have the ProgId attribute present");
|
||||||
|
}
|
||||||
|
|
||||||
|
return typeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsFrameworkType(Type type)
|
||||||
|
{
|
||||||
|
return IsFrameworkAssembly(type.Assembly);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsFrameworkAssembly(Assembly assembly)
|
||||||
|
{
|
||||||
|
var framework = assembly.GetCustomAttributeValue("TargetFrameworkAttribute");
|
||||||
|
return framework.StartsWith(".NETFramework");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static string GetCustomAttributeValue(this Type type, string attributeName)
|
||||||
|
{
|
||||||
|
var cads = type.GetCustomAttributesData();
|
||||||
|
foreach (CustomAttributeData cad in cads.Where(a => a.AttributeType.Name == attributeName))
|
||||||
|
{
|
||||||
|
return cad.ConstructorArguments.FirstOrDefault().Value as string;
|
||||||
|
}
|
||||||
|
|
||||||
|
return String.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetCustomAttributeValue(this Assembly assembly, string attributeName)
|
||||||
|
{
|
||||||
|
foreach (CustomAttributeData cad in assembly.GetCustomAttributesData().Where(a => a.AttributeType.Name == attributeName))
|
||||||
|
{
|
||||||
|
return cad.ConstructorArguments.FirstOrDefault().Value as string;
|
||||||
|
}
|
||||||
|
|
||||||
|
return String.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<Type> GetCredentialProviders(Assembly assembly)
|
||||||
|
{
|
||||||
|
return assembly.GetExportedTypes().Where(t => t.GetInterfaces().Any(ifn => ifn.Name == "ICredentialProvider") && !t.IsAbstract && !t.IsInterface);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Assembly LoadAssembly(string assemblyPath)
|
||||||
|
{
|
||||||
|
string assemblyBasePath = Path.GetDirectoryName(assemblyPath);
|
||||||
|
|
||||||
|
List<string> paths = new List<string>();
|
||||||
|
paths.AddRange(Directory.GetFiles(assemblyBasePath));
|
||||||
|
paths.Add(typeof(object).Assembly.Location);
|
||||||
|
|
||||||
|
// needs to be the .net fx or net core fx location
|
||||||
|
paths.AddRange(Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll"));
|
||||||
|
|
||||||
|
var resolver = new PathAssemblyResolver(paths);
|
||||||
|
MetadataLoadContext mlc = new MetadataLoadContext(resolver);
|
||||||
|
return mlc.LoadFromAssemblyPath(assemblyPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using System.Management.Automation;
|
||||||
|
|
||||||
|
namespace Lithnet.CredentialProvider.RegistrationTool
|
||||||
|
{
|
||||||
|
[Cmdlet(VerbsLifecycle.Disable, "CredentialProvider", DefaultParameterSetName = "DisableByFileName")]
|
||||||
|
public class DisableCredentialProviderCmdlet : PSCmdlet
|
||||||
|
{
|
||||||
|
[Parameter(ParameterSetName = "DisableByFileName")]
|
||||||
|
public string File { get; set; }
|
||||||
|
|
||||||
|
[Parameter(ParameterSetName = "DisableByClsid")]
|
||||||
|
public Guid Clsid { get; set; }
|
||||||
|
|
||||||
|
[Parameter(ParameterSetName = "DisableByProgId")]
|
||||||
|
public string ProgId { get; set; }
|
||||||
|
|
||||||
|
protected override void ProcessRecord()
|
||||||
|
{
|
||||||
|
if (this.ParameterSetName == "DisableByFileName")
|
||||||
|
{
|
||||||
|
if (!CredentialProviderRegistrationServices.IsManagedAssembly(this.File))
|
||||||
|
{
|
||||||
|
throw new System.Exception("This tool cannot disable managed assemblies by file name. You can disable native assemblies using the CLSID or ProgID");
|
||||||
|
}
|
||||||
|
var assembly = CredentialProviderRegistrationServices.LoadAssembly(this.File);
|
||||||
|
|
||||||
|
foreach (var type in CredentialProviderRegistrationServices.GetCredentialProviders(assembly))
|
||||||
|
{
|
||||||
|
CredentialProviderRegistrationServices.DisableCredentialProvider(type);
|
||||||
|
this.WriteVerbose($"Disabled credential provider {type.FullName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (this.ParameterSetName == "DisableByClsid")
|
||||||
|
{
|
||||||
|
CredentialProviderRegistrationServices.DisableCredentialProvider(this.Clsid);
|
||||||
|
}
|
||||||
|
else if (this.ParameterSetName == "DisableByProgId")
|
||||||
|
{
|
||||||
|
var clsid = CredentialProviderRegistrationServices.GetClsidFromProgId(this.ProgId);
|
||||||
|
CredentialProviderRegistrationServices.DisableCredentialProvider(clsid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Lithnet.CredentialProvider.RegistrationTool
|
||||||
|
{
|
||||||
|
public enum DllType
|
||||||
|
{
|
||||||
|
Unknown,
|
||||||
|
NetFramework,
|
||||||
|
NetCore,
|
||||||
|
Native
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
using System;
|
||||||
|
using System.Management.Automation;
|
||||||
|
|
||||||
|
namespace Lithnet.CredentialProvider.RegistrationTool
|
||||||
|
{
|
||||||
|
[Cmdlet(VerbsLifecycle.Enable, "CredentialProvider", DefaultParameterSetName = "EnableByFileName")]
|
||||||
|
public class EnableCredentialProviderCmdlet : PSCmdlet
|
||||||
|
{
|
||||||
|
[Parameter(ParameterSetName = "EnableByFileName")]
|
||||||
|
public string File { get; set; }
|
||||||
|
|
||||||
|
[Parameter(ParameterSetName = "EnableByClsid")]
|
||||||
|
public Guid Clsid { get; set; }
|
||||||
|
|
||||||
|
[Parameter(ParameterSetName = "EnableByProgId")]
|
||||||
|
public string ProgId { get; set; }
|
||||||
|
|
||||||
|
protected override void ProcessRecord()
|
||||||
|
{
|
||||||
|
if (this.ParameterSetName == "EnableByFileName")
|
||||||
|
{
|
||||||
|
if (!CredentialProviderRegistrationServices.IsManagedAssembly(this.File))
|
||||||
|
{
|
||||||
|
throw new System.Exception("This tool cannot enable managed assemblies by file name. You can enable native assemblies using the CLSID or ProgID");
|
||||||
|
}
|
||||||
|
|
||||||
|
var assembly = CredentialProviderRegistrationServices.LoadAssembly(this.File);
|
||||||
|
|
||||||
|
foreach (var type in CredentialProviderRegistrationServices.GetCredentialProviders(assembly))
|
||||||
|
{
|
||||||
|
CredentialProviderRegistrationServices.EnableCredentialProvider(type);
|
||||||
|
this.WriteVerbose($"Enabled credential provider {type.FullName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (this.ParameterSetName == "EnableByClsid")
|
||||||
|
{
|
||||||
|
CredentialProviderRegistrationServices.EnableCredentialProvider(this.Clsid);
|
||||||
|
}
|
||||||
|
else if (this.ParameterSetName == "EnableByProgId")
|
||||||
|
{
|
||||||
|
var clsid = CredentialProviderRegistrationServices.GetClsidFromProgId(this.ProgId);
|
||||||
|
CredentialProviderRegistrationServices.EnableCredentialProvider(clsid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Lithnet.CredentialProvider
|
||||||
|
{
|
||||||
|
public class ClsidNotFoundException : NotFoundException
|
||||||
|
{
|
||||||
|
public ClsidNotFoundException() : base()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClsidNotFoundException(string message) : base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClsidNotFoundException(string message, Exception innerException) : base(message, innerException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Lithnet.CredentialProvider
|
||||||
|
{
|
||||||
|
public class NotFoundException : Exception
|
||||||
|
{
|
||||||
|
public NotFoundException() : base()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotFoundException(string message) : base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotFoundException(string message, Exception innerException) : base(message, innerException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Lithnet.CredentialProvider
|
||||||
|
{
|
||||||
|
public class ProgIdNotFoundException : NotFoundException
|
||||||
|
{
|
||||||
|
public ProgIdNotFoundException() : base()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProgIdNotFoundException(string message) : base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProgIdNotFoundException(string message, Exception innerException) : base(message, innerException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
using System;
|
||||||
|
using System.Management.Automation;
|
||||||
|
|
||||||
|
namespace Lithnet.CredentialProvider.RegistrationTool
|
||||||
|
{
|
||||||
|
[Cmdlet(VerbsCommon.Get, "CredentialProvider", DefaultParameterSetName = "None")]
|
||||||
|
public class GetCredentialProviderCmdlet : PSCmdlet
|
||||||
|
{
|
||||||
|
[Parameter(ParameterSetName = "GetByFileName")]
|
||||||
|
public string File { get; set; }
|
||||||
|
|
||||||
|
[Parameter(ParameterSetName = "GetByClsid")]
|
||||||
|
public Guid Clsid { get; set; }
|
||||||
|
|
||||||
|
[Parameter(ParameterSetName = "GetByProgId")]
|
||||||
|
public string ProgId { get; set; }
|
||||||
|
|
||||||
|
protected override void ProcessRecord()
|
||||||
|
{
|
||||||
|
if (this.ParameterSetName == "None")
|
||||||
|
{
|
||||||
|
foreach (var item in CredentialProviderRegistrationServices.GetCredentalProviders())
|
||||||
|
{
|
||||||
|
this.WriteObject(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (this.ParameterSetName == "GetByFileName")
|
||||||
|
{
|
||||||
|
var assembly = CredentialProviderRegistrationServices.LoadAssembly(this.File);
|
||||||
|
|
||||||
|
foreach (var type in CredentialProviderRegistrationServices.GetCredentialProviders(assembly))
|
||||||
|
{
|
||||||
|
CredentialProviderRegistrationServices.GetCredentialProvider(type);
|
||||||
|
this.WriteVerbose($"Got credential provider {type.FullName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (this.ParameterSetName == "GetByClsid")
|
||||||
|
{
|
||||||
|
CredentialProviderRegistrationServices.GetCredentialProvider(this.Clsid);
|
||||||
|
}
|
||||||
|
else if (this.ParameterSetName == "GetByProgId")
|
||||||
|
{
|
||||||
|
var clsid = CredentialProviderRegistrationServices.GetClsidFromProgId(this.ProgId);
|
||||||
|
CredentialProviderRegistrationServices.GetCredentialProvider(clsid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net461</TargetFramework>
|
||||||
|
<Platform>AnyCPU</Platform>
|
||||||
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="Lithnet.CredentialProvider.Management.psd1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
|
||||||
|
<PackageReference Include="PowerShellStandard.Library" Version="5.1.1" />
|
||||||
|
<PackageReference Include="System.Reflection.MetadataLoadContext" Version="6.0.0" />
|
||||||
|
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Lithnet.CredentialProvider.Management.psd1">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
<Target Name="AfterResolveReferences2" AfterTargets="ResolveAssemblyReferences">
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.Extension)' == '.dll'">
|
||||||
|
<LogicalName>%(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension)</LogicalName>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<ReferenceCopyLocalPaths Remove="@(ReferenceCopyLocalPaths)" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Target>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
@{
|
||||||
|
|
||||||
|
# Script module or binary module file associated with this manifest.
|
||||||
|
RootModule = 'Lithnet.CredentialProvider.Management.dll'
|
||||||
|
|
||||||
|
# Version number of this module.
|
||||||
|
ModuleVersion = '1.0.0'
|
||||||
|
|
||||||
|
# Supported PSEditions
|
||||||
|
CompatiblePSEditions = @('Desktop' ,'Core')
|
||||||
|
|
||||||
|
# ID used to uniquely identify this module
|
||||||
|
GUID = '7cbafd6a-cfe0-4380-b3f3-a161a9b96792'
|
||||||
|
|
||||||
|
# Author of this module
|
||||||
|
Author = 'Lithnet Pty Ltd'
|
||||||
|
|
||||||
|
# Company or vendor of this module
|
||||||
|
CompanyName = 'Lithnet Pty Ltd'
|
||||||
|
|
||||||
|
# Copyright statement for this module
|
||||||
|
Copyright = '(c) Lithnet Pty Ltd 2023. All rights reserved.'
|
||||||
|
|
||||||
|
# Description of the functionality provided by this module
|
||||||
|
Description = 'This module provides cmdlets fot the management of Windows Credential providers'
|
||||||
|
|
||||||
|
# Minimum version of the PowerShell engine required by this module
|
||||||
|
PowerShellVersion = '5.1'
|
||||||
|
|
||||||
|
# Name of the PowerShell host required by this module
|
||||||
|
# PowerShellHostName = ''
|
||||||
|
|
||||||
|
# Minimum version of the PowerShell host required by this module
|
||||||
|
# PowerShellHostVersion = ''
|
||||||
|
|
||||||
|
# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
|
||||||
|
DotNetFrameworkVersion = '4.6.1'
|
||||||
|
|
||||||
|
# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
|
||||||
|
ClrVersion = '4.0'
|
||||||
|
|
||||||
|
# Processor architecture (None, X86, Amd64) required by this module
|
||||||
|
# ProcessorArchitecture = ''
|
||||||
|
|
||||||
|
# Modules that must be imported into the global environment prior to importing this module
|
||||||
|
# RequiredModules = @()
|
||||||
|
|
||||||
|
# Assemblies that must be loaded prior to importing this module
|
||||||
|
# RequiredAssemblies = @()
|
||||||
|
|
||||||
|
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
|
||||||
|
# ScriptsToProcess = @()
|
||||||
|
|
||||||
|
# Type files (.ps1xml) to be loaded when importing this module
|
||||||
|
# TypesToProcess = @()
|
||||||
|
|
||||||
|
# Format files (.ps1xml) to be loaded when importing this module
|
||||||
|
# FormatsToProcess = @()
|
||||||
|
|
||||||
|
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
|
||||||
|
# NestedModules = @()
|
||||||
|
|
||||||
|
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
|
||||||
|
FunctionsToExport = @()
|
||||||
|
|
||||||
|
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
|
||||||
|
CmdletsToExport = @('Register-CredentialProvider', 'Unregister-CredentialProvider', 'Enable-CredentialProvider', 'Disable-CredentialProvider', 'Get-CredentialProvider')
|
||||||
|
|
||||||
|
# Variables to export from this module
|
||||||
|
VariablesToExport = '*'
|
||||||
|
|
||||||
|
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
|
||||||
|
AliasesToExport = @()
|
||||||
|
|
||||||
|
# DSC resources to export from this module
|
||||||
|
# DscResourcesToExport = @()
|
||||||
|
|
||||||
|
# List of all modules packaged with this module
|
||||||
|
# ModuleList = @()
|
||||||
|
|
||||||
|
# List of all files packaged with this module
|
||||||
|
# FileList = @()
|
||||||
|
|
||||||
|
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
|
||||||
|
PrivateData = @{
|
||||||
|
|
||||||
|
PSData = @{
|
||||||
|
|
||||||
|
# Tags applied to this module. These help with module discovery in online galleries.
|
||||||
|
Tags = @("Windows" ,"PSEdition_Desktop", "PSEdition_Core")
|
||||||
|
|
||||||
|
# A URL to the license for this module.
|
||||||
|
LicenseUri = 'https://github.com/lithnet/windows-credential-provider/blob/main/LICENSE'
|
||||||
|
|
||||||
|
# A URL to the main website for this project.
|
||||||
|
ProjectUri = 'https://github.com/lithnet/windows-credential-provider'
|
||||||
|
|
||||||
|
# A URL to an icon representing this module.
|
||||||
|
# IconUri = ''
|
||||||
|
|
||||||
|
# ReleaseNotes of this module
|
||||||
|
ReleaseNotes = 'https://github.com/lithnet/windows-credential-provider'
|
||||||
|
|
||||||
|
# Prerelease string of this module
|
||||||
|
# Prerelease = ''
|
||||||
|
|
||||||
|
# Flag to indicate whether the module requires explicit user acceptance for install/update/save
|
||||||
|
RequireLicenseAcceptance = $false
|
||||||
|
|
||||||
|
# External dependent modules of this module
|
||||||
|
# ExternalModuleDependencies = @()
|
||||||
|
|
||||||
|
} # End of PSData hashtable
|
||||||
|
|
||||||
|
} # End of PrivateData hashtable
|
||||||
|
|
||||||
|
# HelpInfo URI of this module
|
||||||
|
# HelpInfoURI = ''
|
||||||
|
|
||||||
|
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
|
||||||
|
# DefaultCommandPrefix = ''
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Management.Automation;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.Loader;
|
||||||
|
|
||||||
|
namespace Lithnet.CredentialProvider.RegistrationTool
|
||||||
|
{
|
||||||
|
public class ModuleInitializer : IModuleAssemblyInitializer, IModuleAssemblyCleanup
|
||||||
|
{
|
||||||
|
public static bool IsFullFramework => typeof(object).Assembly.FullName.StartsWith("mscorlib", StringComparison.OrdinalIgnoreCase);
|
||||||
|
private Dictionary<string, Assembly> assemblies = new Dictionary<string, Assembly>();
|
||||||
|
|
||||||
|
public void OnImport()
|
||||||
|
{
|
||||||
|
Trace.WriteLine($"Initializing PowerShell module loaded in {(IsFullFramework ? "netfx" : "netcore")}");
|
||||||
|
|
||||||
|
this.PreloadAssemblies();
|
||||||
|
this.HookResolvers();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnRemove(PSModuleInfo psModuleInfo)
|
||||||
|
{
|
||||||
|
this.UnhookResolvers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PreloadAssemblies()
|
||||||
|
{
|
||||||
|
var executingAssembly = Assembly.GetExecutingAssembly();
|
||||||
|
|
||||||
|
foreach (string resource in executingAssembly.GetManifestResourceNames().Where(n => n.EndsWith(".dll")))
|
||||||
|
{
|
||||||
|
using (var stream = executingAssembly.GetManifestResourceStream(resource))
|
||||||
|
{
|
||||||
|
if (stream == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Trace.WriteLine("Preloading assembly: " + resource);
|
||||||
|
|
||||||
|
if (IsFullFramework)
|
||||||
|
{
|
||||||
|
var bytes = new byte[stream.Length];
|
||||||
|
stream.Read(bytes, 0, bytes.Length);
|
||||||
|
this.assemblies.Add(resource, Assembly.Load(bytes));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.assemblies.Add(resource, AssemblyContextResourceLoader.LoadIntoAlc(stream));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Trace.TraceError("Failed to load: {0}\r\n", resource, ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HookResolvers()
|
||||||
|
{
|
||||||
|
AppDomain.CurrentDomain.AssemblyResolve += this.ResolveAssembly;
|
||||||
|
|
||||||
|
if (!IsFullFramework)
|
||||||
|
{
|
||||||
|
this.HookAssemblyLoadContextResolver();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UnhookResolvers()
|
||||||
|
{
|
||||||
|
AppDomain.CurrentDomain.AssemblyResolve -= this.ResolveAssembly;
|
||||||
|
|
||||||
|
if (!IsFullFramework)
|
||||||
|
{
|
||||||
|
this.UnhookAssemblyLoadContextResolver();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HookAssemblyLoadContextResolver()
|
||||||
|
{
|
||||||
|
AssemblyLoadContext.Default.Resolving += this.ResolveAssembly;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UnhookAssemblyLoadContextResolver()
|
||||||
|
{
|
||||||
|
AssemblyLoadContext.Default.Resolving += this.ResolveAssembly;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Assembly ResolveAssembly(object s, ResolveEventArgs e)
|
||||||
|
{
|
||||||
|
var assemblyName = new AssemblyName(e.Name);
|
||||||
|
return this.ResolveAssemblyFromCache(assemblyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Assembly ResolveAssembly(AssemblyLoadContext defaultAlc, AssemblyName assemblyName)
|
||||||
|
{
|
||||||
|
return this.ResolveAssemblyFromCache(assemblyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Assembly ResolveAssemblyFromCache(AssemblyName assemblyName)
|
||||||
|
{
|
||||||
|
var path = string.Format("{0}.dll", assemblyName.Name);
|
||||||
|
|
||||||
|
if (this.assemblies.ContainsKey(path))
|
||||||
|
{
|
||||||
|
return this.assemblies[path];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
using System.Management.Automation;
|
||||||
|
|
||||||
|
namespace Lithnet.CredentialProvider.RegistrationTool
|
||||||
|
{
|
||||||
|
[Cmdlet(VerbsLifecycle.Register, "CredentialProvider")]
|
||||||
|
public class RegisterCredentialProviderCmdlet : PSCmdlet
|
||||||
|
{
|
||||||
|
[Parameter]
|
||||||
|
public string File { get; set; }
|
||||||
|
|
||||||
|
protected override void ProcessRecord()
|
||||||
|
{
|
||||||
|
if (!CredentialProviderRegistrationServices.IsManagedAssembly(this.File))
|
||||||
|
{
|
||||||
|
throw new System.Exception("This tool can only register managed assemblies");
|
||||||
|
}
|
||||||
|
|
||||||
|
var assembly = CredentialProviderRegistrationServices.LoadAssembly(this.File);
|
||||||
|
|
||||||
|
foreach (var type in CredentialProviderRegistrationServices.GetCredentialProviders(assembly))
|
||||||
|
{
|
||||||
|
CredentialProviderRegistrationServices.RegisterCredentialProvider(type);
|
||||||
|
this.WriteVerbose($"Registered credential provider {type.FullName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
using System;
|
||||||
|
using System.Management.Automation;
|
||||||
|
|
||||||
|
namespace Lithnet.CredentialProvider.RegistrationTool
|
||||||
|
{
|
||||||
|
[Cmdlet(VerbsLifecycle.Unregister, "CredentialProvider", DefaultParameterSetName = "UnregisterByFileName")]
|
||||||
|
public class UnregisterCredentialProviderCmdlet : PSCmdlet
|
||||||
|
{
|
||||||
|
[Parameter(ParameterSetName = "UnregisterByFileName")]
|
||||||
|
public string File { get; set; }
|
||||||
|
|
||||||
|
[Parameter(ParameterSetName = "UnregisterByClsid")]
|
||||||
|
public Guid Clsid { get; set; }
|
||||||
|
|
||||||
|
[Parameter(ParameterSetName = "UnregisterByProgId")]
|
||||||
|
public string ProgId { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public SwitchParameter UnregisterCom { get; set; }
|
||||||
|
|
||||||
|
protected override void ProcessRecord()
|
||||||
|
{
|
||||||
|
if (this.ParameterSetName == "UnregisterByFileName")
|
||||||
|
{
|
||||||
|
if (!CredentialProviderRegistrationServices.IsManagedAssembly(this.File))
|
||||||
|
{
|
||||||
|
throw new Exception("This tool cannot unregister managed assemblies by file name. You can unregister native assemblies using the CLSID or ProgID");
|
||||||
|
}
|
||||||
|
|
||||||
|
var assembly = CredentialProviderRegistrationServices.LoadAssembly(this.File);
|
||||||
|
|
||||||
|
foreach (var type in CredentialProviderRegistrationServices.GetCredentialProviders(assembly))
|
||||||
|
{
|
||||||
|
CredentialProviderRegistrationServices.UnregisterCredentialProvider(type, this.GetSwitchValue(this.UnregisterCom, nameof(this.UnregisterCom)));
|
||||||
|
this.WriteVerbose($"Unregistered credential provider {type.FullName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (this.ParameterSetName == "UnregisterByClsid")
|
||||||
|
{
|
||||||
|
CredentialProviderRegistrationServices.UnregisterCredentialProvider(this.Clsid, this.GetSwitchValue(this.UnregisterCom, nameof(this.UnregisterCom)));
|
||||||
|
}
|
||||||
|
else if (this.ParameterSetName == "UnregisterByProgId")
|
||||||
|
{
|
||||||
|
var clsid = CredentialProviderRegistrationServices.GetClsidFromProgId(this.ProgId);
|
||||||
|
CredentialProviderRegistrationServices.UnregisterCredentialProvider(clsid, this.GetSwitchValue(this.UnregisterCom, nameof(this.UnregisterCom)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool GetSwitchValue(SwitchParameter parameter, string name)
|
||||||
|
{
|
||||||
|
if (this.MyInvocation.BoundParameters.ContainsKey(name))
|
||||||
|
{
|
||||||
|
return parameter.ToBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
-225
@@ -1,225 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using Microsoft.Win32;
|
|
||||||
|
|
||||||
namespace Lithnet.CredentialProvider
|
|
||||||
{
|
|
||||||
public static class CredentialProviderRegistrationServices
|
|
||||||
{
|
|
||||||
public static void UnregisterCredentialProvider(Type type)
|
|
||||||
{
|
|
||||||
DeleteCredentialProviderRegistration(type);
|
|
||||||
|
|
||||||
if (IsFrameworkType(type))
|
|
||||||
{
|
|
||||||
UnregisterFrameworkAssembly(type);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UnregisterNetCoreAssembly(type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void RegisterCredentialProvider(Type type)
|
|
||||||
{
|
|
||||||
CreateCredentialProviderRegistration(type);
|
|
||||||
|
|
||||||
if (IsFrameworkType(type))
|
|
||||||
{
|
|
||||||
RegisterFrameworkAssembly(type);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RegisterNetCoreAssembly(type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void DisableCredentialProvider(Type type)
|
|
||||||
{
|
|
||||||
var comGuid = GetComGuid(type);
|
|
||||||
DisableCredentialProvider(comGuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void DisableCredentialProvider(Guid comGuid)
|
|
||||||
{
|
|
||||||
var key = Registry.LocalMachine.OpenSubKey($@"SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{comGuid:B}", true);
|
|
||||||
key?.SetValue("Disabled", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void EnableCredentialProvider(Guid comGuid)
|
|
||||||
{
|
|
||||||
var key = Registry.LocalMachine.OpenSubKey($@"SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{comGuid:B}", true);
|
|
||||||
key?.SetValue("Disabled", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void EnableCredentialProvider(Type type)
|
|
||||||
{
|
|
||||||
var comGuid = GetComGuid(type);
|
|
||||||
EnableCredentialProvider(comGuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void CreateCredentialProviderRegistration(Type t)
|
|
||||||
{
|
|
||||||
var comGuid = GetComGuid(t);
|
|
||||||
var typeName = GetTypeFullName(t);
|
|
||||||
|
|
||||||
var key = Registry.LocalMachine.CreateSubKey($@"SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{comGuid:B}", true);
|
|
||||||
key.SetValue(null, typeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void DeleteCredentialProviderRegistration(Type t)
|
|
||||||
{
|
|
||||||
var comGuid = GetComGuid(t);
|
|
||||||
|
|
||||||
Registry.LocalMachine.DeleteSubKeyTree($@"SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{comGuid:B}", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RegisterNetCoreAssembly(Type t)
|
|
||||||
{
|
|
||||||
var comGuid = GetComGuid(t);
|
|
||||||
var typeName = GetTypeFullName(t);
|
|
||||||
var progId = GetComProgId(t);
|
|
||||||
var assemblyLocation = GetTypeAssemblyLocation(t);
|
|
||||||
|
|
||||||
var dir = Path.GetDirectoryName(assemblyLocation);
|
|
||||||
var assemblyFile = Path.GetFileNameWithoutExtension(assemblyLocation);
|
|
||||||
var comHostLocation = Path.Combine(dir, assemblyFile + ".comhost.dll");
|
|
||||||
|
|
||||||
var rootClsid = Registry.LocalMachine.CreateSubKey($@"Software\Classes\CLSID\{comGuid:B}", true);
|
|
||||||
rootClsid.SetValue(null, "CoreCLR COMHost Server");
|
|
||||||
|
|
||||||
var inprocKey = rootClsid.CreateSubKey("InprocServer32", true);
|
|
||||||
inprocKey.SetValue(null, comHostLocation);
|
|
||||||
inprocKey.SetValue("ThreadingModel", "Both");
|
|
||||||
|
|
||||||
var progIdKey = rootClsid.CreateSubKey("ProgId", true);
|
|
||||||
progIdKey.SetValue(null, progId);
|
|
||||||
|
|
||||||
var progIdRoot = Registry.LocalMachine.CreateSubKey($@"Software\Classes\{progId}", true);
|
|
||||||
progIdRoot.SetValue(null, typeName);
|
|
||||||
var progIdSubKey = progIdRoot.CreateSubKey("CLSID");
|
|
||||||
progIdSubKey.SetValue(null, comGuid.ToString("B"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void UnregisterNetCoreAssembly(Type t)
|
|
||||||
{
|
|
||||||
var comGuid = GetComGuid(t);
|
|
||||||
var progId = GetComProgId(t);
|
|
||||||
|
|
||||||
Registry.LocalMachine.DeleteSubKeyTree($@"Software\Classes\CLSID\{comGuid:B}", false);
|
|
||||||
Registry.LocalMachine.DeleteSubKeyTree($@"Software\Classes\{progId}", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RegisterFrameworkAssembly(Type t)
|
|
||||||
{
|
|
||||||
var comGuid = GetComGuid(t);
|
|
||||||
var typeName = GetTypeFullName(t);
|
|
||||||
var progId = GetComProgId(t);
|
|
||||||
|
|
||||||
var rootClsid = Registry.LocalMachine.CreateSubKey($@"Software\Classes\CLSID\{comGuid:B}", true);
|
|
||||||
rootClsid.SetValue(null, typeName);
|
|
||||||
|
|
||||||
rootClsid.CreateSubKey("Implemented Categories");
|
|
||||||
rootClsid.CreateSubKey(@"Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}");
|
|
||||||
|
|
||||||
var inprocKey = rootClsid.CreateSubKey("InprocServer32", true);
|
|
||||||
inprocKey.SetValue(null, "mscoree.dll");
|
|
||||||
inprocKey.SetValue("ThreadingModel", "Both");
|
|
||||||
inprocKey.SetValue("Class", typeName);
|
|
||||||
inprocKey.SetValue("RuntimeVersion", "v4.0.30319");
|
|
||||||
inprocKey.SetValue("Assembly", GetTypeAssemblyName(t));
|
|
||||||
inprocKey.SetValue("CodeBase", GetTypeAssemblyLocation(t));
|
|
||||||
|
|
||||||
var progIdKey = rootClsid.CreateSubKey("ProgId", true);
|
|
||||||
progIdKey.SetValue(null, progId);
|
|
||||||
|
|
||||||
var progIdRoot = Registry.LocalMachine.CreateSubKey($@"Software\Classes\{progId}", true);
|
|
||||||
progIdRoot.SetValue(null, typeName);
|
|
||||||
var progIdSubKey = progIdRoot.CreateSubKey("CLSID");
|
|
||||||
progIdSubKey.SetValue(null, comGuid.ToString("B"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void UnregisterFrameworkAssembly(Type t)
|
|
||||||
{
|
|
||||||
var comGuid = GetComGuid(t);
|
|
||||||
var progId = GetComProgId(t);
|
|
||||||
|
|
||||||
Registry.LocalMachine.DeleteSubKeyTree($@"Software\Classes\CLSID\{comGuid:B}", false);
|
|
||||||
Registry.LocalMachine.DeleteSubKeyTree($@"Software\Classes\{progId}", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetTypeAssemblyLocation(Type type)
|
|
||||||
{
|
|
||||||
return type.Assembly.Location;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetTypeAssemblyName(Type type)
|
|
||||||
{
|
|
||||||
return type.Assembly.FullName;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetTypeClassName(Type type)
|
|
||||||
{
|
|
||||||
return type.Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetTypeFullName(Type type)
|
|
||||||
{
|
|
||||||
return type.FullName;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Guid GetComGuid(Type type)
|
|
||||||
{
|
|
||||||
var typeId = type.GetCustomAttributeValue("GuidAttribute");
|
|
||||||
|
|
||||||
if (typeId == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentException($"The type {type.Name} does not have the Guid attribute present");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Guid(typeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetComProgId(Type type)
|
|
||||||
{
|
|
||||||
var typeId = type.GetCustomAttributeValue("ProgIdAttribute");
|
|
||||||
|
|
||||||
if (typeId == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentException($"The type {type.Name} does not have the ProgId attribute present");
|
|
||||||
}
|
|
||||||
|
|
||||||
return typeId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsFrameworkType(Type type)
|
|
||||||
{
|
|
||||||
var framework = type.Assembly.GetCustomAttributeValue("TargetFrameworkAttribute");
|
|
||||||
return framework.StartsWith(".NETFramework");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetCustomAttributeValue(this Type type, string attributeName)
|
|
||||||
{
|
|
||||||
var cads = type.GetCustomAttributesData();
|
|
||||||
foreach (CustomAttributeData cad in cads.Where(a => a.AttributeType.Name == attributeName))
|
|
||||||
{
|
|
||||||
return cad.ConstructorArguments.FirstOrDefault().Value as string;
|
|
||||||
}
|
|
||||||
|
|
||||||
return String.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetCustomAttributeValue(this Assembly assembly, string attributeName)
|
|
||||||
{
|
|
||||||
foreach (CustomAttributeData cad in assembly.GetCustomAttributesData().Where(a => a.AttributeType.Name == attributeName))
|
|
||||||
{
|
|
||||||
return cad.ConstructorArguments.FirstOrDefault().Value as string;
|
|
||||||
}
|
|
||||||
|
|
||||||
return String.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
// This file is used by Code Analysis to maintain SuppressMessage
|
|
||||||
// attributes that are applied to this project.
|
|
||||||
// Project-level suppressions either have no target or are given
|
|
||||||
// a specific target and scoped to a namespace, type, member, etc.
|
|
||||||
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
|
|
||||||
[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility")]
|
|
||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net6.0-windows</TargetFramework>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
|
|
||||||
<PackageReference Include="System.Reflection.MetadataLoadContext" Version="7.0.0" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,187 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.CommandLine;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Lithnet.CredentialProvider.RegistrationTool
|
|
||||||
{
|
|
||||||
internal static class Program
|
|
||||||
{
|
|
||||||
static async Task<int> Main(string[] args)
|
|
||||||
{
|
|
||||||
var rootCommand = new RootCommand("Lithnet credential provider registration tool");
|
|
||||||
|
|
||||||
var registerCommand = new Command("--register", "Registers the specified credential provider on this system");
|
|
||||||
registerCommand.AddAlias("-r");
|
|
||||||
var registerArgument = new Argument<FileInfo>("file name", "The name of the file to register");
|
|
||||||
registerCommand.AddArgument(registerArgument);
|
|
||||||
registerCommand.SetHandler((file) => RegisterAssembly(file), registerArgument);
|
|
||||||
rootCommand.Add(registerCommand);
|
|
||||||
|
|
||||||
|
|
||||||
var unregisterCommand = new Command("--unregister", "Unregisters the specified credential provider on this system");
|
|
||||||
unregisterCommand.AddAlias("-u");
|
|
||||||
var unregisterArgument = new Argument<FileInfo>("file name", "The name of the file to register");
|
|
||||||
unregisterCommand.AddArgument(unregisterArgument);
|
|
||||||
unregisterCommand.SetHandler((file) => UnregisterAssembly(file), unregisterArgument);
|
|
||||||
rootCommand.Add(unregisterCommand);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var enableCommand = new Command("--enable", "Enables the specified credential provider on this system");
|
|
||||||
enableCommand.AddAlias("-e");
|
|
||||||
var enableFileOption = new Option<FileInfo>("file", "The path to the credential provider to enable");
|
|
||||||
|
|
||||||
var enableGuidOption = new Option<Guid>("providerid", "The GUID of the provider to enable");
|
|
||||||
|
|
||||||
enableCommand.AddOption(enableFileOption);
|
|
||||||
enableCommand.AddOption(enableGuidOption);
|
|
||||||
enableCommand.SetHandler((file) => EnableProviders(file), enableFileOption);
|
|
||||||
enableCommand.SetHandler((id) => EnableProviders(id), enableGuidOption);
|
|
||||||
rootCommand.Add(enableCommand);
|
|
||||||
|
|
||||||
|
|
||||||
//var unregisterOption = new Option<FileInfo>(
|
|
||||||
// name: "--unregister",
|
|
||||||
// description: "Unregisters the specified file as a credential provider on this system");
|
|
||||||
|
|
||||||
//var enableOption = new Option<string>(
|
|
||||||
// name: "--enable",
|
|
||||||
// description: "Enables a credential provider on this system");
|
|
||||||
|
|
||||||
//var disableOption = new Option<string>(
|
|
||||||
// name: "--disable",
|
|
||||||
// description: "Disables a credential provider on this system");
|
|
||||||
|
|
||||||
|
|
||||||
//rootCommand.AddOption(registerOptions);
|
|
||||||
//rootCommand.AddOption(unregisterOption);
|
|
||||||
//rootCommand.AddOption(enableOption);
|
|
||||||
//rootCommand.AddOption(disableOption);
|
|
||||||
|
|
||||||
|
|
||||||
//rootCommand.SetHandler((file) => RegisterAssembly(file), registerOptions);
|
|
||||||
//rootCommand.SetHandler((file) => UnregisterAssembly(file), unregisterOption);
|
|
||||||
//rootCommand.SetHandler((file) => EnableProviders(file), enableOption);
|
|
||||||
//rootCommand.SetHandler((file) => DisableProviders(file), disableOption);
|
|
||||||
|
|
||||||
return await rootCommand.InvokeAsync(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void UnregisterAssembly(FileInfo file)
|
|
||||||
{
|
|
||||||
var assembly = LoadAssembly(file.FullName);
|
|
||||||
|
|
||||||
foreach (var type in GetCredentialProviders(assembly))
|
|
||||||
{
|
|
||||||
CredentialProviderRegistrationServices.UnregisterCredentialProvider(type);
|
|
||||||
Console.WriteLine($"Unregistered credential provider {type.Name}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void EnableProviders(FileInfo file)
|
|
||||||
{
|
|
||||||
var assembly = LoadAssembly(file.FullName);
|
|
||||||
|
|
||||||
foreach (var type in GetCredentialProviders(assembly))
|
|
||||||
{
|
|
||||||
CredentialProviderRegistrationServices.EnableCredentialProvider(type);
|
|
||||||
Console.WriteLine($"Enabled credential provider {type.FullName}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void EnableProviders(Guid id)
|
|
||||||
{
|
|
||||||
CredentialProviderRegistrationServices.EnableCredentialProvider(id);
|
|
||||||
Console.WriteLine($"Enabled credential provider {id}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void DisableProviders(FileInfo file)
|
|
||||||
{
|
|
||||||
var assembly = LoadAssembly(file.FullName);
|
|
||||||
|
|
||||||
foreach (var type in GetCredentialProviders(assembly))
|
|
||||||
{
|
|
||||||
CredentialProviderRegistrationServices.DisableCredentialProvider(type);
|
|
||||||
Console.WriteLine($"Disabled credential provider {type.FullName}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private static void DisableProviders(string id)
|
|
||||||
{
|
|
||||||
if (Guid.TryParse(id, out var providerId))
|
|
||||||
{
|
|
||||||
CredentialProviderRegistrationServices.DisableCredentialProvider(providerId);
|
|
||||||
Console.WriteLine($"Disabled credential provider {providerId}");
|
|
||||||
}
|
|
||||||
|
|
||||||
var assembly = LoadAssembly(Path.GetFullPath(id));
|
|
||||||
|
|
||||||
foreach (var type in GetCredentialProviders(assembly))
|
|
||||||
{
|
|
||||||
CredentialProviderRegistrationServices.DisableCredentialProvider(type);
|
|
||||||
Console.WriteLine($"Disabled credential provider {type.FullName}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RegisterAssembly(FileInfo file)
|
|
||||||
{
|
|
||||||
var assembly = LoadAssembly(file.FullName);
|
|
||||||
|
|
||||||
foreach (var type in GetCredentialProviders(assembly))
|
|
||||||
{
|
|
||||||
CredentialProviderRegistrationServices.RegisterCredentialProvider(type);
|
|
||||||
Console.WriteLine($"Registered credential provider {type.FullName}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<Type> GetCredentialProviders(Assembly assembly)
|
|
||||||
{
|
|
||||||
return assembly.GetExportedTypes().Where(t => t.GetInterfaces().Any(ifn => ifn.Name == "ICredentialProvider") && !t.IsAbstract && !t.IsInterface);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Assembly LoadAssembly(string assemblyPath)
|
|
||||||
{
|
|
||||||
string assemblyBasePath = Path.GetDirectoryName(assemblyPath);
|
|
||||||
|
|
||||||
List<string> paths = new List<string>();
|
|
||||||
paths.AddRange(Directory.GetFiles(Path.GetDirectoryName(assemblyPath)));
|
|
||||||
paths.Add(typeof(object).Assembly.Location);
|
|
||||||
paths.AddRange(Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll"));
|
|
||||||
|
|
||||||
var resolver = new PathAssemblyResolver(paths);
|
|
||||||
MetadataLoadContext mlc = new MetadataLoadContext(resolver);
|
|
||||||
return mlc.LoadFromAssemblyPath(assemblyPath);
|
|
||||||
|
|
||||||
//AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += (s, args) =>
|
|
||||||
//{
|
|
||||||
// var name = new AssemblyName(args.Name);
|
|
||||||
// string assyPath = Path.Combine(assemblyBasePath, $"{name.Name}.dll");
|
|
||||||
// Trace.WriteLine($"Request for {args.Name}");
|
|
||||||
|
|
||||||
// if (File.Exists(assyPath))
|
|
||||||
// {
|
|
||||||
// Trace.WriteLine($"Found at {assyPath}");
|
|
||||||
// return Assembly.ReflectionOnlyLoadFrom(assyPath);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// assyPath = Path.Combine(RuntimeEnvironment.GetRuntimeDirectory(), $"{name.Name}.dll");
|
|
||||||
|
|
||||||
// if (File.Exists(assyPath))
|
|
||||||
// {
|
|
||||||
// Trace.WriteLine($"Found at {assyPath}");
|
|
||||||
// return Assembly.ReflectionOnlyLoadFrom(assyPath);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Trace.WriteLine($"Assembly {args.Name} not found");
|
|
||||||
// return null;
|
|
||||||
|
|
||||||
//};
|
|
||||||
|
|
||||||
//var assembly = Assembly.ReflectionOnlyLoadFrom(assemblyPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,6 +8,7 @@ EndProject
|
|||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9E97082E-4E8D-4E8B-A320-40E2A1494C74}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9E97082E-4E8D-4E8B-A320-40E2A1494C74}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
.editorconfig = .editorconfig
|
.editorconfig = .editorconfig
|
||||||
|
..\azure-pipelines.yml = ..\azure-pipelines.yml
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lithnet.CredentialProvider.Sample.net6.0.x64", "samples\Lithnet.CredentialProvider.Sample.net6.0.x64\Lithnet.CredentialProvider.Sample.net6.0.x64.csproj", "{163E16D0-9FF3-40D3-AE96-3F221C922AA3}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lithnet.CredentialProvider.Sample.net6.0.x64", "samples\Lithnet.CredentialProvider.Sample.net6.0.x64\Lithnet.CredentialProvider.Sample.net6.0.x64.csproj", "{163E16D0-9FF3-40D3-AE96-3F221C922AA3}"
|
||||||
@@ -22,7 +23,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lithnet.CredentialProvider.
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lithnet.CredentialProvider.TestApp.x86", "samples\Lithnet.CredentialProvider.TestApp.x86\Lithnet.CredentialProvider.TestApp.x86.csproj", "{F39C84F2-60C2-45EB-BC87-0ED095D41C96}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lithnet.CredentialProvider.TestApp.x86", "samples\Lithnet.CredentialProvider.TestApp.x86\Lithnet.CredentialProvider.TestApp.x86.csproj", "{F39C84F2-60C2-45EB-BC87-0ED095D41C96}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lithnet.CredentialProvider.RegistrationTool", "Lithnet.CredentialProvider.RegistrationTool\Lithnet.CredentialProvider.RegistrationTool.csproj", "{6A9A22A9-A2BB-4329-A0A5-2539E464CE5F}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lithnet.CredentialProvider.Management", "Lithnet.CredentialProvider.Management\Lithnet.CredentialProvider.Management.csproj", "{6A9A22A9-A2BB-4329-A0A5-2539E464CE5F}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
|||||||
Reference in New Issue
Block a user