mirror of
https://github.com/dorssel/usbipd-win.git
synced 2026-11-10 22:50:48 +08:00
90 lines
3.5 KiB
C#
90 lines
3.5 KiB
C#
// SPDX-FileCopyrightText: 2022 Frans van Dorsselaer
|
|
//
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
using System.Diagnostics;
|
|
using System.Management.Automation;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace Usbipd.PowerShell;
|
|
|
|
static class Installation
|
|
{
|
|
static string GetRegistryStringValue(string regOutput, string valueName)
|
|
{
|
|
// Example regOutput:
|
|
//
|
|
// HKEY_LOCAL_MACHINE\SOFTWARE\usbipd-win
|
|
// APPLICATIONFOLDER REG_SZ C:\Program Files\usbipd-win\
|
|
// Version REG_SZ 3.0.0
|
|
//
|
|
// HKEY_LOCAL_MACHINE\SOFTWARE\usbipd-win\Devices
|
|
|
|
var match = Regex.Match(regOutput, @$"^\s*{valueName}\s+REG_SZ\s+(.*)$", RegexOptions.Multiline);
|
|
return match.Success ? match.Groups[1].Value.TrimEnd() : throw new ApplicationFailedException("usbipd-win is not installed.");
|
|
}
|
|
|
|
public static string ExePath
|
|
{
|
|
get
|
|
{
|
|
// NOTE: User may be running 32-bit PowerShell, so we must explicitly ask for 64-bit registry.
|
|
var regExe = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "reg.exe");
|
|
|
|
var startInfo = new ProcessStartInfo
|
|
{
|
|
FileName = regExe,
|
|
Arguments = @"query HKLM\SOFTWARE\usbipd-win /reg:64",
|
|
UseShellExecute = false,
|
|
StandardOutputEncoding = Encoding.UTF8,
|
|
StandardErrorEncoding = Encoding.UTF8,
|
|
RedirectStandardInput = true,
|
|
RedirectStandardOutput = true,
|
|
RedirectStandardError = true,
|
|
};
|
|
|
|
using var process = Process.Start(startInfo) ?? throw new ApplicationFailedException($"Cannot execute '{regExe}'.");
|
|
var stdout = string.Empty;
|
|
var stderr = string.Empty;
|
|
|
|
var captureTasks = new[]
|
|
{
|
|
Task.Run(async () => stdout = await process.StandardOutput.ReadToEndAsync()),
|
|
Task.Run(async () => stderr = await process.StandardError.ReadToEndAsync()),
|
|
};
|
|
|
|
process.WaitForExit();
|
|
Task.WhenAll(captureTasks).Wait();
|
|
|
|
if (process.ExitCode != 0)
|
|
{
|
|
throw new ApplicationFailedException($"reg.exe failed with exit code {process.ExitCode}.");
|
|
}
|
|
if (!string.IsNullOrEmpty(stderr))
|
|
{
|
|
throw new ApplicationFailedException($"reg.exe returned unexpected error text:\n\n{stderr}");
|
|
}
|
|
|
|
var applicationFolder = GetRegistryStringValue(stdout, "APPLICATIONFOLDER");
|
|
var exeFile = Path.Combine(Path.GetFullPath(applicationFolder), "usbipd.exe");
|
|
if (!File.Exists(exeFile))
|
|
{
|
|
throw new ApplicationFailedException("usbipd-win is not installed.");
|
|
}
|
|
var installedVersion = GetRegistryStringValue(stdout, "Version");
|
|
if (installedVersion != ThisAssembly.NuGetPackageVersion)
|
|
{
|
|
throw new ApplicationFailedException(
|
|
$"PowerShell module version {ThisAssembly.NuGetPackageVersion} does not match installed usbipd-win version {installedVersion}.");
|
|
}
|
|
#if DEBUG
|
|
return Path.GetFullPath(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().Location),
|
|
@"..\..\..\..\Usbipd\bin\x64\Debug\net10.0\usbipd.exe"));
|
|
#else
|
|
return exeFile;
|
|
#endif
|
|
}
|
|
}
|
|
}
|