Initialversion
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
using System.Reflection;
|
||||
|
||||
namespace Plandent.MstscScriptHook.Configurator;
|
||||
|
||||
internal static class PluginInstaller
|
||||
{
|
||||
private const string ResourceName = "PlandentMstscScriptHook.Native.PlandentMstscScriptHook.dll";
|
||||
public const string DllFileName = "PlandentMstscScriptHook.dll";
|
||||
|
||||
public static string InstallDirectory => Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||||
"Plandent",
|
||||
"MstscScriptHook");
|
||||
|
||||
public static string InstalledDllPath => Path.Combine(InstallDirectory, DllFileName);
|
||||
|
||||
public static void Install()
|
||||
{
|
||||
Directory.CreateDirectory(InstallDirectory);
|
||||
ExtractPluginBinary(InstalledDllPath);
|
||||
RegistryConfig.RegisterPlugin(InstalledDllPath);
|
||||
}
|
||||
|
||||
public static UninstallResult Uninstall()
|
||||
{
|
||||
RegistryConfig.UnregisterPlugin();
|
||||
|
||||
if (!File.Exists(InstalledDllPath))
|
||||
{
|
||||
return new UninstallResult(true, "Plugin-Registrierung entfernt.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
File.Delete(InstalledDllPath);
|
||||
TryDeleteEmptyInstallDirectory();
|
||||
return new UninstallResult(true, "Plugin-Registrierung und DLL wurden entfernt.");
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
return new UninstallResult(
|
||||
false,
|
||||
"Die Registrierung wurde entfernt. Die DLL wird noch von mstsc.exe verwendet. " +
|
||||
"Alle Remote-Desktop-Clients schließen und die Datei anschließend löschen bzw. erneut auf „Plugin entfernen“ klicken.");
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
return new UninstallResult(false, "Registrierung entfernt, DLL konnte aber nicht gelöscht werden: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsInstalled(out string status)
|
||||
{
|
||||
string? registered = RegistryConfig.GetRegisteredPluginPath();
|
||||
if (string.IsNullOrWhiteSpace(registered))
|
||||
{
|
||||
status = "Plugin ist nicht registriert.";
|
||||
return false;
|
||||
}
|
||||
|
||||
string expanded = Environment.ExpandEnvironmentVariables(registered);
|
||||
if (!File.Exists(expanded))
|
||||
{
|
||||
status = $"Plugin ist registriert, DLL fehlt jedoch: {expanded}";
|
||||
return false;
|
||||
}
|
||||
|
||||
status = $"Plugin ist registriert: {expanded}";
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void ExtractPluginBinary(string destination)
|
||||
{
|
||||
Assembly assembly = Assembly.GetExecutingAssembly();
|
||||
using Stream? resource = assembly.GetManifestResourceStream(ResourceName);
|
||||
if (resource is not null)
|
||||
{
|
||||
using FileStream output = new(destination, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
resource.CopyTo(output);
|
||||
return;
|
||||
}
|
||||
|
||||
// Praktischer Fallback für Debugging/Entwicklung: DLL direkt neben der EXE akzeptieren.
|
||||
string adjacent = Path.Combine(AppContext.BaseDirectory, DllFileName);
|
||||
if (File.Exists(adjacent))
|
||||
{
|
||||
File.Copy(adjacent, destination, overwrite: true);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new FileNotFoundException(
|
||||
"Die native Plugin-DLL ist weder als Resource eingebettet noch neben der Konfigurations-EXE vorhanden. " +
|
||||
"Bitte zuerst build-release.ps1 ausführen.",
|
||||
DllFileName);
|
||||
}
|
||||
|
||||
private static void TryDeleteEmptyInstallDirectory()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(InstallDirectory) && !Directory.EnumerateFileSystemEntries(InstallDirectory).Any())
|
||||
{
|
||||
Directory.Delete(InstallDirectory);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Unkritisch: ein leeres Verzeichnis darf bestehen bleiben.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed record UninstallResult(bool FullyRemoved, string Message);
|
||||
Reference in New Issue
Block a user