Initialversion
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Plandent.MstscScriptHook.Configurator;
|
||||
|
||||
internal static class ScriptTestLauncher
|
||||
{
|
||||
public static Process Start(HookConfig config)
|
||||
{
|
||||
string scriptPath = Environment.ExpandEnvironmentVariables(config.ScriptPath ?? string.Empty);
|
||||
if (string.IsNullOrWhiteSpace(scriptPath) || !File.Exists(scriptPath))
|
||||
{
|
||||
throw new FileNotFoundException("Das ausgewählte Script wurde nicht gefunden.", scriptPath);
|
||||
}
|
||||
|
||||
string extension = Path.GetExtension(scriptPath).ToLowerInvariant();
|
||||
string workingDirectory = string.IsNullOrWhiteSpace(config.WorkingDirectory)
|
||||
? Path.GetDirectoryName(scriptPath) ?? Environment.CurrentDirectory
|
||||
: Environment.ExpandEnvironmentVariables(config.WorkingDirectory);
|
||||
|
||||
var startInfo = new ProcessStartInfo
|
||||
{
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = config.Hidden,
|
||||
WindowStyle = config.Hidden ? ProcessWindowStyle.Hidden : ProcessWindowStyle.Normal,
|
||||
WorkingDirectory = workingDirectory
|
||||
};
|
||||
|
||||
switch (extension)
|
||||
{
|
||||
case ".bat":
|
||||
case ".cmd":
|
||||
startInfo.FileName = Environment.GetEnvironmentVariable("ComSpec")
|
||||
?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "cmd.exe");
|
||||
startInfo.ArgumentList.Add("/D");
|
||||
startInfo.ArgumentList.Add("/S");
|
||||
startInfo.ArgumentList.Add("/C");
|
||||
startInfo.ArgumentList.Add(BuildCmdCommand(scriptPath, config.Arguments));
|
||||
break;
|
||||
|
||||
case ".ps1":
|
||||
startInfo.FileName = Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.System),
|
||||
"WindowsPowerShell",
|
||||
"v1.0",
|
||||
"powershell.exe");
|
||||
startInfo.ArgumentList.Add("-NoLogo");
|
||||
startInfo.ArgumentList.Add("-NoProfile");
|
||||
startInfo.ArgumentList.Add("-NonInteractive");
|
||||
startInfo.ArgumentList.Add("-ExecutionPolicy");
|
||||
startInfo.ArgumentList.Add("Bypass");
|
||||
startInfo.ArgumentList.Add("-File");
|
||||
startInfo.ArgumentList.Add(scriptPath);
|
||||
AddRawArguments(startInfo, config.Arguments);
|
||||
break;
|
||||
|
||||
case ".exe":
|
||||
startInfo.FileName = scriptPath;
|
||||
AddRawArguments(startInfo, config.Arguments);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotSupportedException("Unterstützt werden .bat, .cmd, .ps1 und .exe.");
|
||||
}
|
||||
|
||||
return Process.Start(startInfo)
|
||||
?? throw new InvalidOperationException("Der Testprozess konnte nicht gestartet werden.");
|
||||
}
|
||||
|
||||
private static string BuildCmdCommand(string scriptPath, string? arguments)
|
||||
{
|
||||
string command = QuoteForCmd(scriptPath);
|
||||
if (!string.IsNullOrWhiteSpace(arguments))
|
||||
{
|
||||
command += " " + arguments;
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
private static string QuoteForCmd(string value)
|
||||
{
|
||||
return "\"" + value.Replace("\"", "\\\"") + "\"";
|
||||
}
|
||||
|
||||
// Die GUI behandelt das Argumentfeld bewusst als Kommandozeilen-Argumentstring.
|
||||
// Für den Test wird eine einfache Windows-Argumentzerlegung verwendet. Das Plugin selbst
|
||||
// übergibt den String unverändert an cmd.exe/PowerShell bzw. an die EXE-Kommandozeile.
|
||||
private static void AddRawArguments(ProcessStartInfo startInfo, string? raw)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(raw))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string argument in CommandLineSplitter.Split(raw))
|
||||
{
|
||||
startInfo.ArgumentList.Add(argument);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static class CommandLineSplitter
|
||||
{
|
||||
public static IReadOnlyList<string> Split(string commandLine)
|
||||
{
|
||||
var result = new List<string>();
|
||||
var current = new System.Text.StringBuilder();
|
||||
bool inQuotes = false;
|
||||
int backslashes = 0;
|
||||
|
||||
for (int i = 0; i < commandLine.Length; i++)
|
||||
{
|
||||
char ch = commandLine[i];
|
||||
|
||||
if (ch == '\\')
|
||||
{
|
||||
backslashes++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == '"')
|
||||
{
|
||||
current.Append('\\', backslashes / 2);
|
||||
if (backslashes % 2 == 0)
|
||||
{
|
||||
inQuotes = !inQuotes;
|
||||
}
|
||||
else
|
||||
{
|
||||
current.Append('"');
|
||||
}
|
||||
backslashes = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
current.Append('\\', backslashes);
|
||||
backslashes = 0;
|
||||
|
||||
if (char.IsWhiteSpace(ch) && !inQuotes)
|
||||
{
|
||||
if (current.Length > 0)
|
||||
{
|
||||
result.Add(current.ToString());
|
||||
current.Clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
current.Append(ch);
|
||||
}
|
||||
}
|
||||
|
||||
current.Append('\\', backslashes);
|
||||
if (current.Length > 0)
|
||||
{
|
||||
result.Add(current.ToString());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user