Hinzufügen der Möglichkeit ein Programmstart auf dem Client durch die RDP Sitzung zu triggern
This commit is contained in:
@@ -9,12 +9,24 @@
|
||||
<RootNamespace>Plandent.MstscScriptHook.Configurator</RootNamespace>
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<PluginPayloadPath>$(MSBuildProjectDirectory)\..\artifacts\x64\$(Configuration)\PlandentMstscScriptHook.dll</PluginPayloadPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Beim normalen Visual-Studio-Debugging wird die lokal installierte .NET-8-Runtime benutzt.
|
||||
Dadurch werden keine win-x64 Runtime-Packs von NuGet benötigt. -->
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<SelfContained>false</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
<DebugType>portable</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Nur das Release-Publish erzeugt die verteilbare self-contained Single-File-EXE. -->
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>true</PublishSingleFile>
|
||||
<PublishReadyToRun>false</PublishReadyToRun>
|
||||
<DebugType>embedded</DebugType>
|
||||
<PluginPayloadPath>$(MSBuildProjectDirectory)\..\artifacts\x64\$(Configuration)\PlandentMstscScriptHook.dll</PluginPayloadPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -3,6 +3,9 @@ namespace Plandent.MstscScriptHook.Configurator;
|
||||
internal sealed class HookConfig
|
||||
{
|
||||
public bool Enabled { get; set; } = true;
|
||||
public bool EnableLogging { get; set; } = true;
|
||||
|
||||
// Automatischer Start bei erfolgreicher RDP-Verbindung.
|
||||
public string ScriptPath { get; set; } = string.Empty;
|
||||
public string Arguments { get; set; } = string.Empty;
|
||||
public string WorkingDirectory { get; set; } = string.Empty;
|
||||
@@ -10,5 +13,13 @@ internal sealed class HookConfig
|
||||
public bool StopOnDisconnect { get; set; }
|
||||
public bool Hidden { get; set; } = true;
|
||||
public bool PreventDuplicates { get; set; } = true;
|
||||
public bool EnableLogging { get; set; } = true;
|
||||
|
||||
// Separates lokales Programm, das ausschließlich durch den festen
|
||||
// START-Trigger vom Terminalserver gestartet werden kann.
|
||||
public bool TriggerEnabled { get; set; }
|
||||
public string TriggerProgramPath { get; set; } = string.Empty;
|
||||
public string TriggerArguments { get; set; } = string.Empty;
|
||||
public string TriggerWorkingDirectory { get; set; } = string.Empty;
|
||||
public bool TriggerHidden { get; set; } = true;
|
||||
public bool TriggerPreventDuplicates { get; set; } = true;
|
||||
}
|
||||
|
||||
+351
-120
@@ -1,21 +1,35 @@
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Plandent.MstscScriptHook.Configurator;
|
||||
|
||||
internal sealed class MainForm : Form
|
||||
{
|
||||
// Global
|
||||
private readonly CheckBox enabledCheckBox = new() { Text = "Plugin-Funktion aktiviert", AutoSize = true };
|
||||
private readonly CheckBox loggingCheckBox = new() { Text = "Plugin-Logging aktivieren", AutoSize = true };
|
||||
|
||||
// Automatischer Start bei RDP-Verbindung
|
||||
private readonly TextBox scriptPathTextBox = new() { Dock = DockStyle.Fill };
|
||||
private readonly TextBox argumentsTextBox = new() { Dock = DockStyle.Fill };
|
||||
private readonly TextBox workingDirectoryTextBox = new() { Dock = DockStyle.Fill };
|
||||
|
||||
private readonly CheckBox enabledCheckBox = new() { Text = "Plugin-Funktion aktiviert", AutoSize = true };
|
||||
private readonly CheckBox startOnConnectCheckBox = new() { Text = "Script bei erfolgreicher RDP-Verbindung starten", AutoSize = true };
|
||||
private readonly CheckBox stopOnDisconnectCheckBox = new() { Text = "Script bei RDP-Trennung beenden", AutoSize = true };
|
||||
private readonly CheckBox hiddenCheckBox = new() { Text = "Script unsichtbar starten", AutoSize = true };
|
||||
private readonly CheckBox startOnConnectCheckBox = new() { Text = "Bei erfolgreicher RDP-Verbindung starten", AutoSize = true };
|
||||
private readonly CheckBox stopOnDisconnectCheckBox = new() { Text = "Bei RDP-Trennung beenden", AutoSize = true };
|
||||
private readonly CheckBox hiddenCheckBox = new() { Text = "Unsichtbar starten", AutoSize = true };
|
||||
private readonly CheckBox preventDuplicatesCheckBox = new() { Text = "Mehrfachstart verhindern", AutoSize = true };
|
||||
private readonly CheckBox loggingCheckBox = new() { Text = "Plugin-Logging aktivieren", AutoSize = true };
|
||||
private readonly Button stopConnectionTestButton = new() { Text = "Test beenden", AutoSize = true, Enabled = false };
|
||||
private Process? connectionTestProcess;
|
||||
|
||||
// Separater Start durch Terminalserver-Trigger
|
||||
private readonly TextBox triggerProgramPathTextBox = new() { Dock = DockStyle.Fill };
|
||||
private readonly TextBox triggerArgumentsTextBox = new() { Dock = DockStyle.Fill };
|
||||
private readonly TextBox triggerWorkingDirectoryTextBox = new() { Dock = DockStyle.Fill };
|
||||
private readonly CheckBox triggerEnabledCheckBox = new() { Text = "Start durch Terminalserver-Trigger erlauben", AutoSize = true };
|
||||
private readonly CheckBox triggerHiddenCheckBox = new() { Text = "Unsichtbar starten", AutoSize = true };
|
||||
private readonly CheckBox triggerPreventDuplicatesCheckBox = new() { Text = "Mehrfachstart verhindern", AutoSize = true };
|
||||
private readonly Button stopTriggerTestButton = new() { Text = "Test beenden", AutoSize = true, Enabled = false };
|
||||
private Process? triggerTestProcess;
|
||||
|
||||
private readonly Label statusLabel = new()
|
||||
{
|
||||
@@ -25,20 +39,17 @@ internal sealed class MainForm : Form
|
||||
Padding = new Padding(8)
|
||||
};
|
||||
|
||||
private readonly Button stopTestButton = new() { Text = "Test beenden", AutoSize = true, Enabled = false };
|
||||
private Process? testProcess;
|
||||
|
||||
public MainForm()
|
||||
{
|
||||
Text = "Plandent MSTSC Script Hook";
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
MinimumSize = new Size(760, 590);
|
||||
Size = new Size(820, 640);
|
||||
MinimumSize = new Size(820, 720);
|
||||
Size = new Size(900, 800);
|
||||
Font = new Font("Segoe UI", 9F);
|
||||
|
||||
Controls.Add(BuildMainLayout());
|
||||
Load += (_, _) => LoadConfiguration();
|
||||
FormClosed += (_, _) => DisposeTestProcessHandle();
|
||||
FormClosed += (_, _) => DisposeAllTestProcesses();
|
||||
}
|
||||
|
||||
private Control BuildMainLayout()
|
||||
@@ -52,10 +63,10 @@ internal sealed class MainForm : Form
|
||||
};
|
||||
root.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||
root.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||
root.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
|
||||
root.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||
root.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||
root.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||
|
||||
var title = new Label
|
||||
{
|
||||
@@ -68,21 +79,201 @@ internal sealed class MainForm : Form
|
||||
|
||||
var description = new Label
|
||||
{
|
||||
Text = "Startet bei einer erfolgreichen klassischen Remotedesktop-Verbindung lokal ein konfiguriertes Script im Hintergrund.",
|
||||
Text = "Lokale Programme können automatisch beim RDP-Verbindungsaufbau oder gezielt durch eine Anwendung innerhalb der Terminalserver-Sitzung gestartet werden.",
|
||||
AutoSize = true,
|
||||
MaximumSize = new Size(740, 0),
|
||||
Margin = new Padding(0, 0, 0, 16)
|
||||
MaximumSize = new Size(820, 0),
|
||||
Margin = new Padding(0, 0, 0, 12)
|
||||
};
|
||||
root.Controls.Add(description, 0, 1);
|
||||
|
||||
root.Controls.Add(BuildFileGrid(), 0, 2);
|
||||
root.Controls.Add(BuildOptionsGroup(), 0, 3);
|
||||
root.Controls.Add(BuildStatusPanel(), 0, 4);
|
||||
root.Controls.Add(BuildButtons(), 0, 5);
|
||||
var scroll = new Panel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
AutoScroll = true,
|
||||
Margin = new Padding(0, 0, 0, 12)
|
||||
};
|
||||
|
||||
var content = new TableLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
AutoSize = true,
|
||||
ColumnCount = 1,
|
||||
RowCount = 3
|
||||
};
|
||||
content.Controls.Add(BuildGlobalOptionsGroup(), 0, 0);
|
||||
content.Controls.Add(BuildConnectionProgramGroup(), 0, 1);
|
||||
content.Controls.Add(BuildTriggerProgramGroup(), 0, 2);
|
||||
scroll.Controls.Add(content);
|
||||
root.Controls.Add(scroll, 0, 2);
|
||||
|
||||
root.Controls.Add(BuildStatusPanel(), 0, 3);
|
||||
|
||||
var hint = new Label
|
||||
{
|
||||
Text = "Hinweis: PlandentRdpClientTrigger.exe auf dem Terminalserver übermittelt ausschließlich einen festen START-Befehl. Programmpfad und Parameter werden niemals vom Server übertragen.",
|
||||
AutoSize = true,
|
||||
MaximumSize = new Size(820, 0),
|
||||
Margin = new Padding(0, 0, 0, 10)
|
||||
};
|
||||
root.Controls.Add(hint, 0, 4);
|
||||
|
||||
root.Controls.Add(BuildMainButtons(), 0, 5);
|
||||
return root;
|
||||
}
|
||||
|
||||
private Control BuildFileGrid()
|
||||
private Control BuildGlobalOptionsGroup()
|
||||
{
|
||||
var group = CreateGroup("Allgemein");
|
||||
var options = new FlowLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
FlowDirection = FlowDirection.TopDown,
|
||||
WrapContents = false,
|
||||
AutoSize = true
|
||||
};
|
||||
options.Controls.Add(enabledCheckBox);
|
||||
options.Controls.Add(loggingCheckBox);
|
||||
group.Controls.Add(options);
|
||||
return group;
|
||||
}
|
||||
|
||||
private Control BuildConnectionProgramGroup()
|
||||
{
|
||||
var group = CreateGroup("Automatischer Start bei RDP-Verbindung");
|
||||
|
||||
var layout = new TableLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
AutoSize = true,
|
||||
ColumnCount = 1,
|
||||
RowCount = 4
|
||||
};
|
||||
|
||||
layout.Controls.Add(new Label
|
||||
{
|
||||
Text = "Optionales lokales Programm/Script, das direkt nach erfolgreichem Aufbau der klassischen MSTSC-Verbindung gestartet wird.",
|
||||
AutoSize = true,
|
||||
MaximumSize = new Size(780, 0),
|
||||
Margin = new Padding(0, 0, 0, 8)
|
||||
}, 0, 0);
|
||||
|
||||
layout.Controls.Add(BuildFileGrid(
|
||||
scriptPathTextBox,
|
||||
argumentsTextBox,
|
||||
workingDirectoryTextBox,
|
||||
() => BrowseProgram(scriptPathTextBox, workingDirectoryTextBox, useRemoteVddsPreset: true),
|
||||
() => BrowseWorkingDirectory(workingDirectoryTextBox)), 0, 1);
|
||||
|
||||
var options = new FlowLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
FlowDirection = FlowDirection.LeftToRight,
|
||||
WrapContents = true,
|
||||
AutoSize = true,
|
||||
Margin = new Padding(0, 4, 0, 6)
|
||||
};
|
||||
options.Controls.Add(startOnConnectCheckBox);
|
||||
options.Controls.Add(stopOnDisconnectCheckBox);
|
||||
options.Controls.Add(hiddenCheckBox);
|
||||
options.Controls.Add(preventDuplicatesCheckBox);
|
||||
layout.Controls.Add(options, 0, 2);
|
||||
|
||||
var testButtons = new FlowLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
FlowDirection = FlowDirection.LeftToRight,
|
||||
WrapContents = true,
|
||||
AutoSize = true,
|
||||
Margin = new Padding(0)
|
||||
};
|
||||
var testButton = new Button { Text = "Verbindungs-Programm testen", AutoSize = true };
|
||||
testButton.Click += (_, _) => StartConnectionTest();
|
||||
stopConnectionTestButton.Click += (_, _) => StopConnectionTest(silent: false);
|
||||
testButtons.Controls.Add(testButton);
|
||||
testButtons.Controls.Add(stopConnectionTestButton);
|
||||
layout.Controls.Add(testButtons, 0, 3);
|
||||
|
||||
group.Controls.Add(layout);
|
||||
return group;
|
||||
}
|
||||
|
||||
private Control BuildTriggerProgramGroup()
|
||||
{
|
||||
var group = CreateGroup("Programmstart durch Terminalserver");
|
||||
|
||||
var layout = new TableLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
AutoSize = true,
|
||||
ColumnCount = 1,
|
||||
RowCount = 4
|
||||
};
|
||||
|
||||
layout.Controls.Add(new Label
|
||||
{
|
||||
Text = "Optionales lokales Programm/Script mit eigenen Parametern. Es wird nur gestartet, wenn PlandentRdpClientTrigger.exe innerhalb derselben RDP-Sitzung auf dem Terminalserver ausgeführt wird.",
|
||||
AutoSize = true,
|
||||
MaximumSize = new Size(780, 0),
|
||||
Margin = new Padding(0, 0, 0, 8)
|
||||
}, 0, 0);
|
||||
|
||||
layout.Controls.Add(BuildFileGrid(
|
||||
triggerProgramPathTextBox,
|
||||
triggerArgumentsTextBox,
|
||||
triggerWorkingDirectoryTextBox,
|
||||
() => BrowseProgram(triggerProgramPathTextBox, triggerWorkingDirectoryTextBox, useRemoteVddsPreset: false),
|
||||
() => BrowseWorkingDirectory(triggerWorkingDirectoryTextBox)), 0, 1);
|
||||
|
||||
var options = new FlowLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
FlowDirection = FlowDirection.LeftToRight,
|
||||
WrapContents = true,
|
||||
AutoSize = true,
|
||||
Margin = new Padding(0, 4, 0, 6)
|
||||
};
|
||||
options.Controls.Add(triggerEnabledCheckBox);
|
||||
options.Controls.Add(triggerHiddenCheckBox);
|
||||
options.Controls.Add(triggerPreventDuplicatesCheckBox);
|
||||
layout.Controls.Add(options, 0, 2);
|
||||
|
||||
var testButtons = new FlowLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
FlowDirection = FlowDirection.LeftToRight,
|
||||
WrapContents = true,
|
||||
AutoSize = true,
|
||||
Margin = new Padding(0)
|
||||
};
|
||||
var testButton = new Button { Text = "Trigger-Programm testen", AutoSize = true };
|
||||
testButton.Click += (_, _) => StartTriggerTest();
|
||||
stopTriggerTestButton.Click += (_, _) => StopTriggerTest(silent: false);
|
||||
testButtons.Controls.Add(testButton);
|
||||
testButtons.Controls.Add(stopTriggerTestButton);
|
||||
layout.Controls.Add(testButtons, 0, 3);
|
||||
|
||||
group.Controls.Add(layout);
|
||||
return group;
|
||||
}
|
||||
|
||||
private static GroupBox CreateGroup(string title)
|
||||
{
|
||||
return new GroupBox
|
||||
{
|
||||
Text = title,
|
||||
Dock = DockStyle.Top,
|
||||
AutoSize = true,
|
||||
Padding = new Padding(12),
|
||||
Margin = new Padding(0, 0, 0, 12)
|
||||
};
|
||||
}
|
||||
|
||||
private static Control BuildFileGrid(
|
||||
TextBox pathTextBox,
|
||||
TextBox argumentsTextBox,
|
||||
TextBox workingDirectoryTextBox,
|
||||
Action browseProgram,
|
||||
Action browseWorkingDirectory)
|
||||
{
|
||||
var grid = new TableLayoutPanel
|
||||
{
|
||||
@@ -90,17 +281,17 @@ internal sealed class MainForm : Form
|
||||
AutoSize = true,
|
||||
ColumnCount = 3,
|
||||
RowCount = 3,
|
||||
Margin = new Padding(0, 0, 0, 14)
|
||||
Margin = new Padding(0)
|
||||
};
|
||||
grid.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
|
||||
grid.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
|
||||
grid.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
|
||||
|
||||
grid.Controls.Add(CreateFieldLabel("Script:"), 0, 0);
|
||||
grid.Controls.Add(scriptPathTextBox, 1, 0);
|
||||
var browseScriptButton = new Button { Text = "…", Width = 42, Height = scriptPathTextBox.PreferredHeight + 4 };
|
||||
browseScriptButton.Click += (_, _) => BrowseScript();
|
||||
grid.Controls.Add(browseScriptButton, 2, 0);
|
||||
grid.Controls.Add(CreateFieldLabel("Programm/Script:"), 0, 0);
|
||||
grid.Controls.Add(pathTextBox, 1, 0);
|
||||
var browseProgramButton = new Button { Text = "…", Width = 42, Height = pathTextBox.PreferredHeight + 4 };
|
||||
browseProgramButton.Click += (_, _) => browseProgram();
|
||||
grid.Controls.Add(browseProgramButton, 2, 0);
|
||||
|
||||
grid.Controls.Add(CreateFieldLabel("Argumente:"), 0, 1);
|
||||
grid.Controls.Add(argumentsTextBox, 1, 1);
|
||||
@@ -109,7 +300,7 @@ internal sealed class MainForm : Form
|
||||
grid.Controls.Add(CreateFieldLabel("Arbeitsverzeichnis:"), 0, 2);
|
||||
grid.Controls.Add(workingDirectoryTextBox, 1, 2);
|
||||
var browseWorkingButton = new Button { Text = "…", Width = 42, Height = workingDirectoryTextBox.PreferredHeight + 4 };
|
||||
browseWorkingButton.Click += (_, _) => BrowseWorkingDirectory();
|
||||
browseWorkingButton.Click += (_, _) => browseWorkingDirectory();
|
||||
grid.Controls.Add(browseWorkingButton, 2, 2);
|
||||
|
||||
return grid;
|
||||
@@ -126,48 +317,20 @@ internal sealed class MainForm : Form
|
||||
};
|
||||
}
|
||||
|
||||
private Control BuildOptionsGroup()
|
||||
{
|
||||
var group = new GroupBox
|
||||
{
|
||||
Text = "Verhalten",
|
||||
Dock = DockStyle.Top,
|
||||
AutoSize = true,
|
||||
Padding = new Padding(12),
|
||||
Margin = new Padding(0, 0, 0, 14)
|
||||
};
|
||||
|
||||
var options = new FlowLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
FlowDirection = FlowDirection.TopDown,
|
||||
WrapContents = false,
|
||||
AutoSize = true
|
||||
};
|
||||
options.Controls.Add(enabledCheckBox);
|
||||
options.Controls.Add(startOnConnectCheckBox);
|
||||
options.Controls.Add(stopOnDisconnectCheckBox);
|
||||
options.Controls.Add(hiddenCheckBox);
|
||||
options.Controls.Add(preventDuplicatesCheckBox);
|
||||
options.Controls.Add(loggingCheckBox);
|
||||
group.Controls.Add(options);
|
||||
return group;
|
||||
}
|
||||
|
||||
private Control BuildStatusPanel()
|
||||
{
|
||||
var panel = new Panel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
Height = 58,
|
||||
Height = 70,
|
||||
BorderStyle = BorderStyle.FixedSingle,
|
||||
Margin = new Padding(0, 0, 0, 14)
|
||||
Margin = new Padding(0, 0, 0, 10)
|
||||
};
|
||||
panel.Controls.Add(statusLabel);
|
||||
return panel;
|
||||
}
|
||||
|
||||
private Control BuildButtons()
|
||||
private Control BuildMainButtons()
|
||||
{
|
||||
var buttons = new FlowLayoutPanel
|
||||
{
|
||||
@@ -178,10 +341,6 @@ internal sealed class MainForm : Form
|
||||
Margin = new Padding(0)
|
||||
};
|
||||
|
||||
var testButton = new Button { Text = "Script testen", AutoSize = true };
|
||||
testButton.Click += (_, _) => StartTest();
|
||||
stopTestButton.Click += (_, _) => StopTest();
|
||||
|
||||
var saveButton = new Button { Text = "Konfiguration speichern", AutoSize = true };
|
||||
saveButton.Click += (_, _) => SaveConfiguration(showConfirmation: true);
|
||||
|
||||
@@ -194,8 +353,6 @@ internal sealed class MainForm : Form
|
||||
var logButton = new Button { Text = "Log öffnen", AutoSize = true };
|
||||
logButton.Click += (_, _) => OpenLog();
|
||||
|
||||
buttons.Controls.Add(testButton);
|
||||
buttons.Controls.Add(stopTestButton);
|
||||
buttons.Controls.Add(saveButton);
|
||||
buttons.Controls.Add(installButton);
|
||||
buttons.Controls.Add(removeButton);
|
||||
@@ -203,18 +360,18 @@ internal sealed class MainForm : Form
|
||||
return buttons;
|
||||
}
|
||||
|
||||
private void BrowseScript()
|
||||
private void BrowseProgram(TextBox pathTextBox, TextBox workingDirectoryTextBox, bool useRemoteVddsPreset)
|
||||
{
|
||||
using var dialog = new OpenFileDialog
|
||||
{
|
||||
Title = "Script oder Programm auswählen",
|
||||
Filter = "Unterstützte Dateien (*.bat;*.cmd;*.ps1;*.exe)|*.bat;*.cmd;*.ps1;*.exe|Alle Dateien (*.*)|*.*",
|
||||
Title = "Programm oder Script auswählen",
|
||||
Filter = "Unterstützte Dateien (*.exe;*.bat;*.cmd;*.ps1)|*.exe;*.bat;*.cmd;*.ps1|Alle Dateien (*.*)|*.*",
|
||||
CheckFileExists = true
|
||||
};
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(scriptPathTextBox.Text))
|
||||
if (!string.IsNullOrWhiteSpace(pathTextBox.Text))
|
||||
{
|
||||
string expanded = Environment.ExpandEnvironmentVariables(scriptPathTextBox.Text);
|
||||
string expanded = Environment.ExpandEnvironmentVariables(pathTextBox.Text);
|
||||
if (File.Exists(expanded))
|
||||
{
|
||||
dialog.InitialDirectory = Path.GetDirectoryName(expanded);
|
||||
@@ -227,20 +384,21 @@ internal sealed class MainForm : Form
|
||||
return;
|
||||
}
|
||||
|
||||
scriptPathTextBox.Text = dialog.FileName;
|
||||
pathTextBox.Text = dialog.FileName;
|
||||
if (string.IsNullOrWhiteSpace(workingDirectoryTextBox.Text))
|
||||
{
|
||||
workingDirectoryTextBox.Text = Path.GetDirectoryName(dialog.FileName) ?? string.Empty;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(argumentsTextBox.Text) &&
|
||||
if (useRemoteVddsPreset &&
|
||||
string.IsNullOrWhiteSpace(argumentsTextBox.Text) &&
|
||||
Path.GetFileName(dialog.FileName).Contains("RemoteVDDS_Receiver_TS", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
argumentsTextBox.Text = "MIN";
|
||||
}
|
||||
}
|
||||
|
||||
private void BrowseWorkingDirectory()
|
||||
private void BrowseWorkingDirectory(TextBox target)
|
||||
{
|
||||
using var dialog = new FolderBrowserDialog
|
||||
{
|
||||
@@ -249,7 +407,7 @@ internal sealed class MainForm : Form
|
||||
ShowNewFolderButton = true
|
||||
};
|
||||
|
||||
string expanded = Environment.ExpandEnvironmentVariables(workingDirectoryTextBox.Text);
|
||||
string expanded = Environment.ExpandEnvironmentVariables(target.Text);
|
||||
if (Directory.Exists(expanded))
|
||||
{
|
||||
dialog.SelectedPath = expanded;
|
||||
@@ -257,7 +415,7 @@ internal sealed class MainForm : Form
|
||||
|
||||
if (dialog.ShowDialog(this) == DialogResult.OK)
|
||||
{
|
||||
workingDirectoryTextBox.Text = dialog.SelectedPath;
|
||||
target.Text = dialog.SelectedPath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,6 +424,8 @@ internal sealed class MainForm : Form
|
||||
return new HookConfig
|
||||
{
|
||||
Enabled = enabledCheckBox.Checked,
|
||||
EnableLogging = loggingCheckBox.Checked,
|
||||
|
||||
ScriptPath = scriptPathTextBox.Text.Trim(),
|
||||
Arguments = argumentsTextBox.Text.Trim(),
|
||||
WorkingDirectory = workingDirectoryTextBox.Text.Trim(),
|
||||
@@ -273,22 +433,37 @@ internal sealed class MainForm : Form
|
||||
StopOnDisconnect = stopOnDisconnectCheckBox.Checked,
|
||||
Hidden = hiddenCheckBox.Checked,
|
||||
PreventDuplicates = preventDuplicatesCheckBox.Checked,
|
||||
EnableLogging = loggingCheckBox.Checked
|
||||
|
||||
TriggerEnabled = triggerEnabledCheckBox.Checked,
|
||||
TriggerProgramPath = triggerProgramPathTextBox.Text.Trim(),
|
||||
TriggerArguments = triggerArgumentsTextBox.Text.Trim(),
|
||||
TriggerWorkingDirectory = triggerWorkingDirectoryTextBox.Text.Trim(),
|
||||
TriggerHidden = triggerHiddenCheckBox.Checked,
|
||||
TriggerPreventDuplicates = triggerPreventDuplicatesCheckBox.Checked
|
||||
};
|
||||
}
|
||||
|
||||
private void LoadConfiguration()
|
||||
{
|
||||
HookConfig config = RegistryConfig.Load();
|
||||
enabledCheckBox.Checked = config.Enabled;
|
||||
loggingCheckBox.Checked = config.EnableLogging;
|
||||
|
||||
scriptPathTextBox.Text = config.ScriptPath;
|
||||
argumentsTextBox.Text = config.Arguments;
|
||||
workingDirectoryTextBox.Text = config.WorkingDirectory;
|
||||
enabledCheckBox.Checked = config.Enabled;
|
||||
startOnConnectCheckBox.Checked = config.StartOnConnect;
|
||||
stopOnDisconnectCheckBox.Checked = config.StopOnDisconnect;
|
||||
hiddenCheckBox.Checked = config.Hidden;
|
||||
preventDuplicatesCheckBox.Checked = config.PreventDuplicates;
|
||||
loggingCheckBox.Checked = config.EnableLogging;
|
||||
|
||||
triggerEnabledCheckBox.Checked = config.TriggerEnabled;
|
||||
triggerProgramPathTextBox.Text = config.TriggerProgramPath;
|
||||
triggerArgumentsTextBox.Text = config.TriggerArguments;
|
||||
triggerWorkingDirectoryTextBox.Text = config.TriggerWorkingDirectory;
|
||||
triggerHiddenCheckBox.Checked = config.TriggerHidden;
|
||||
triggerPreventDuplicatesCheckBox.Checked = config.TriggerPreventDuplicates;
|
||||
|
||||
RefreshStatus();
|
||||
}
|
||||
|
||||
@@ -297,7 +472,7 @@ internal sealed class MainForm : Form
|
||||
try
|
||||
{
|
||||
HookConfig config = ReadForm();
|
||||
ValidateConfig(config, requireScript: false);
|
||||
ValidateConfiguredTargets(config, installationValidation: false);
|
||||
RegistryConfig.Save(config);
|
||||
if (showConfirmation)
|
||||
{
|
||||
@@ -318,14 +493,14 @@ internal sealed class MainForm : Form
|
||||
try
|
||||
{
|
||||
HookConfig config = ReadForm();
|
||||
ValidateConfig(config, requireScript: true);
|
||||
ValidateConfiguredTargets(config, installationValidation: true);
|
||||
RegistryConfig.Save(config);
|
||||
PluginInstaller.Install();
|
||||
RefreshStatus();
|
||||
MessageBox.Show(
|
||||
this,
|
||||
"Plugin wurde für den aktuellen Benutzer installiert und die Konfiguration gespeichert.\n\n" +
|
||||
"Bereits geöffnete mstsc.exe-Fenster vollständig schließen und anschließend neu starten, damit die DLL geladen wird.",
|
||||
"Bereits geöffnete mstsc.exe-Fenster vollständig schließen und anschließend neu starten, damit die neue DLL geladen wird.",
|
||||
"Installation abgeschlossen",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Information);
|
||||
@@ -348,63 +523,92 @@ internal sealed class MainForm : Form
|
||||
result.FullyRemoved ? MessageBoxIcon.Information : MessageBoxIcon.Warning);
|
||||
}
|
||||
|
||||
private void StartTest()
|
||||
private void StartConnectionTest()
|
||||
{
|
||||
try
|
||||
{
|
||||
StopTest(silent: true);
|
||||
StopConnectionTest(silent: true);
|
||||
HookConfig config = ReadForm();
|
||||
ValidateConfig(config, requireScript: true);
|
||||
testProcess = ScriptTestLauncher.Start(config);
|
||||
stopTestButton.Enabled = true;
|
||||
statusLabel.Text = $"Testprozess gestartet: PID {testProcess.Id}. Der Test läuft unabhängig von MSTSC.";
|
||||
ValidateLaunchTarget(config.ScriptPath, config.WorkingDirectory, "RDP-Verbindungsprogramm", required: true);
|
||||
connectionTestProcess = ScriptTestLauncher.StartConnectionProgram(config);
|
||||
stopConnectionTestButton.Enabled = true;
|
||||
statusLabel.Text = $"Verbindungs-Test gestartet: PID {connectionTestProcess.Id}. Der Test läuft unabhängig von MSTSC.";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(this, ex.Message, "Script-Test fehlgeschlagen", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
MessageBox.Show(this, ex.Message, "Test fehlgeschlagen", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void StopTest() => StopTest(silent: false);
|
||||
|
||||
private void StopTest(bool silent)
|
||||
private void StartTriggerTest()
|
||||
{
|
||||
if (testProcess is null)
|
||||
try
|
||||
{
|
||||
stopTestButton.Enabled = false;
|
||||
StopTriggerTest(silent: true);
|
||||
HookConfig config = ReadForm();
|
||||
ValidateLaunchTarget(config.TriggerProgramPath, config.TriggerWorkingDirectory, "Trigger-Programm", required: true);
|
||||
triggerTestProcess = ScriptTestLauncher.StartTriggerProgram(config);
|
||||
stopTriggerTestButton.Enabled = true;
|
||||
statusLabel.Text = $"Trigger-Programm-Test gestartet: PID {triggerTestProcess.Id}. Der Test läuft ohne Terminalserver-Trigger.";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(this, ex.Message, "Trigger-Programm-Test fehlgeschlagen", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void StopConnectionTest(bool silent)
|
||||
{
|
||||
StopTestProcess(ref connectionTestProcess, stopConnectionTestButton, "Verbindungs-Test", silent);
|
||||
}
|
||||
|
||||
private void StopTriggerTest(bool silent)
|
||||
{
|
||||
StopTestProcess(ref triggerTestProcess, stopTriggerTestButton, "Trigger-Programm-Test", silent);
|
||||
}
|
||||
|
||||
private void StopTestProcess(ref Process? process, Button button, string description, bool silent)
|
||||
{
|
||||
if (process is null)
|
||||
{
|
||||
button.Enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (!testProcess.HasExited)
|
||||
if (!process.HasExited)
|
||||
{
|
||||
testProcess.Kill(entireProcessTree: true);
|
||||
testProcess.WaitForExit(3000);
|
||||
process.Kill(entireProcessTree: true);
|
||||
process.WaitForExit(3000);
|
||||
}
|
||||
|
||||
if (!silent)
|
||||
{
|
||||
statusLabel.Text = "Testprozess wurde beendet.";
|
||||
statusLabel.Text = description + " wurde beendet.";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!silent)
|
||||
{
|
||||
MessageBox.Show(this, ex.Message, "Testprozess konnte nicht beendet werden", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
MessageBox.Show(this, ex.Message, description + " konnte nicht beendet werden", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
DisposeTestProcessHandle();
|
||||
process?.Dispose();
|
||||
process = null;
|
||||
button.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void DisposeTestProcessHandle()
|
||||
private void DisposeAllTestProcesses()
|
||||
{
|
||||
testProcess?.Dispose();
|
||||
testProcess = null;
|
||||
stopTestButton.Enabled = false;
|
||||
connectionTestProcess?.Dispose();
|
||||
triggerTestProcess?.Dispose();
|
||||
connectionTestProcess = null;
|
||||
triggerTestProcess = null;
|
||||
}
|
||||
|
||||
private void OpenLog()
|
||||
@@ -426,42 +630,69 @@ internal sealed class MainForm : Form
|
||||
private void RefreshStatus()
|
||||
{
|
||||
bool installed = PluginInstaller.IsInstalled(out string pluginStatus);
|
||||
string configStatus = string.IsNullOrWhiteSpace(scriptPathTextBox.Text)
|
||||
? " Kein Script konfiguriert."
|
||||
: $" Script: {scriptPathTextBox.Text}";
|
||||
statusLabel.Text = (installed ? "✓ " : "○ ") + pluginStatus + configStatus;
|
||||
|
||||
string connectStatus = startOnConnectCheckBox.Checked
|
||||
? (string.IsNullOrWhiteSpace(scriptPathTextBox.Text) ? " RDP-Start: nicht konfiguriert." : " RDP-Start: konfiguriert.")
|
||||
: " RDP-Start: aus.";
|
||||
|
||||
string triggerStatus = triggerEnabledCheckBox.Checked
|
||||
? (string.IsNullOrWhiteSpace(triggerProgramPathTextBox.Text) ? " Server-Trigger: nicht konfiguriert." : " Server-Trigger: konfiguriert.")
|
||||
: " Server-Trigger: aus.";
|
||||
|
||||
statusLabel.Text = (installed ? "✓ " : "○ ") + pluginStatus + connectStatus + triggerStatus;
|
||||
}
|
||||
|
||||
private static void ValidateConfig(HookConfig config, bool requireScript)
|
||||
private static void ValidateConfiguredTargets(HookConfig config, bool installationValidation)
|
||||
{
|
||||
if (!requireScript && string.IsNullOrWhiteSpace(config.ScriptPath))
|
||||
// Bereits ausgefüllte Pfade immer prüfen, damit Tippfehler nicht gespeichert werden.
|
||||
ValidateLaunchTarget(config.ScriptPath, config.WorkingDirectory, "RDP-Verbindungsprogramm", required: false);
|
||||
ValidateLaunchTarget(config.TriggerProgramPath, config.TriggerWorkingDirectory, "Trigger-Programm", required: false);
|
||||
|
||||
if (!installationValidation || !config.Enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string scriptPath = Environment.ExpandEnvironmentVariables(config.ScriptPath);
|
||||
if (string.IsNullOrWhiteSpace(scriptPath))
|
||||
if (config.StartOnConnect)
|
||||
{
|
||||
throw new InvalidOperationException("Bitte ein Script auswählen.");
|
||||
ValidateLaunchTarget(config.ScriptPath, config.WorkingDirectory, "RDP-Verbindungsprogramm", required: true);
|
||||
}
|
||||
|
||||
if (!File.Exists(scriptPath))
|
||||
if (config.TriggerEnabled)
|
||||
{
|
||||
throw new FileNotFoundException("Das ausgewählte Script wurde nicht gefunden.", scriptPath);
|
||||
ValidateLaunchTarget(config.TriggerProgramPath, config.TriggerWorkingDirectory, "Trigger-Programm", required: true);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ValidateLaunchTarget(string configuredPath, string configuredWorkingDirectory, string displayName, bool required)
|
||||
{
|
||||
string path = Environment.ExpandEnvironmentVariables(configuredPath ?? string.Empty);
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
if (required)
|
||||
{
|
||||
throw new InvalidOperationException($"Bitte für „{displayName}“ ein Programm oder Script auswählen.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
string extension = Path.GetExtension(scriptPath).ToLowerInvariant();
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
throw new FileNotFoundException($"{displayName} wurde nicht gefunden.", path);
|
||||
}
|
||||
|
||||
string extension = Path.GetExtension(path).ToLowerInvariant();
|
||||
if (extension is not (".bat" or ".cmd" or ".ps1" or ".exe"))
|
||||
{
|
||||
throw new NotSupportedException("Unterstützt werden .bat, .cmd, .ps1 und .exe.");
|
||||
throw new NotSupportedException($"{displayName}: Unterstützt werden .bat, .cmd, .ps1 und .exe.");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(config.WorkingDirectory))
|
||||
if (!string.IsNullOrWhiteSpace(configuredWorkingDirectory))
|
||||
{
|
||||
string workDir = Environment.ExpandEnvironmentVariables(config.WorkingDirectory);
|
||||
string workDir = Environment.ExpandEnvironmentVariables(configuredWorkingDirectory);
|
||||
if (!Directory.Exists(workDir))
|
||||
{
|
||||
throw new DirectoryNotFoundException("Das Arbeitsverzeichnis wurde nicht gefunden: " + workDir);
|
||||
throw new DirectoryNotFoundException($"Arbeitsverzeichnis für „{displayName}“ wurde nicht gefunden: {workDir}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ internal static class RegistryConfig
|
||||
}
|
||||
|
||||
config.Enabled = ReadBool(key, "Enabled", true);
|
||||
config.EnableLogging = ReadBool(key, "EnableLogging", true);
|
||||
|
||||
config.ScriptPath = ReadString(key, "ScriptPath");
|
||||
config.Arguments = ReadString(key, "Arguments");
|
||||
config.WorkingDirectory = ReadString(key, "WorkingDirectory");
|
||||
@@ -24,7 +26,13 @@ internal static class RegistryConfig
|
||||
config.StopOnDisconnect = ReadBool(key, "StopOnDisconnect", false);
|
||||
config.Hidden = ReadBool(key, "Hidden", true);
|
||||
config.PreventDuplicates = ReadBool(key, "PreventDuplicates", true);
|
||||
config.EnableLogging = ReadBool(key, "EnableLogging", true);
|
||||
|
||||
config.TriggerEnabled = ReadBool(key, "TriggerEnabled", false);
|
||||
config.TriggerProgramPath = ReadString(key, "TriggerProgramPath");
|
||||
config.TriggerArguments = ReadString(key, "TriggerArguments");
|
||||
config.TriggerWorkingDirectory = ReadString(key, "TriggerWorkingDirectory");
|
||||
config.TriggerHidden = ReadBool(key, "TriggerHidden", true);
|
||||
config.TriggerPreventDuplicates = ReadBool(key, "TriggerPreventDuplicates", true);
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -34,6 +42,8 @@ internal static class RegistryConfig
|
||||
?? throw new InvalidOperationException("Registry-Schlüssel konnte nicht erstellt werden.");
|
||||
|
||||
key.SetValue("Enabled", config.Enabled ? 1 : 0, RegistryValueKind.DWord);
|
||||
key.SetValue("EnableLogging", config.EnableLogging ? 1 : 0, RegistryValueKind.DWord);
|
||||
|
||||
key.SetValue("ScriptPath", config.ScriptPath ?? string.Empty, RegistryValueKind.ExpandString);
|
||||
key.SetValue("Arguments", config.Arguments ?? string.Empty, RegistryValueKind.String);
|
||||
key.SetValue("WorkingDirectory", config.WorkingDirectory ?? string.Empty, RegistryValueKind.ExpandString);
|
||||
@@ -41,7 +51,13 @@ internal static class RegistryConfig
|
||||
key.SetValue("StopOnDisconnect", config.StopOnDisconnect ? 1 : 0, RegistryValueKind.DWord);
|
||||
key.SetValue("Hidden", config.Hidden ? 1 : 0, RegistryValueKind.DWord);
|
||||
key.SetValue("PreventDuplicates", config.PreventDuplicates ? 1 : 0, RegistryValueKind.DWord);
|
||||
key.SetValue("EnableLogging", config.EnableLogging ? 1 : 0, RegistryValueKind.DWord);
|
||||
|
||||
key.SetValue("TriggerEnabled", config.TriggerEnabled ? 1 : 0, RegistryValueKind.DWord);
|
||||
key.SetValue("TriggerProgramPath", config.TriggerProgramPath ?? string.Empty, RegistryValueKind.ExpandString);
|
||||
key.SetValue("TriggerArguments", config.TriggerArguments ?? string.Empty, RegistryValueKind.String);
|
||||
key.SetValue("TriggerWorkingDirectory", config.TriggerWorkingDirectory ?? string.Empty, RegistryValueKind.ExpandString);
|
||||
key.SetValue("TriggerHidden", config.TriggerHidden ? 1 : 0, RegistryValueKind.DWord);
|
||||
key.SetValue("TriggerPreventDuplicates", config.TriggerPreventDuplicates ? 1 : 0, RegistryValueKind.DWord);
|
||||
}
|
||||
|
||||
public static string? GetRegisteredPluginPath()
|
||||
|
||||
@@ -4,24 +4,36 @@ namespace Plandent.MstscScriptHook.Configurator;
|
||||
|
||||
internal static class ScriptTestLauncher
|
||||
{
|
||||
public static Process Start(HookConfig config)
|
||||
public static Process StartConnectionProgram(HookConfig config) => Start(
|
||||
config.ScriptPath,
|
||||
config.Arguments,
|
||||
config.WorkingDirectory,
|
||||
config.Hidden);
|
||||
|
||||
public static Process StartTriggerProgram(HookConfig config) => Start(
|
||||
config.TriggerProgramPath,
|
||||
config.TriggerArguments,
|
||||
config.TriggerWorkingDirectory,
|
||||
config.TriggerHidden);
|
||||
|
||||
private static Process Start(string configuredPath, string configuredArguments, string configuredWorkingDirectory, bool hidden)
|
||||
{
|
||||
string scriptPath = Environment.ExpandEnvironmentVariables(config.ScriptPath ?? string.Empty);
|
||||
if (string.IsNullOrWhiteSpace(scriptPath) || !File.Exists(scriptPath))
|
||||
string programPath = Environment.ExpandEnvironmentVariables(configuredPath ?? string.Empty);
|
||||
if (string.IsNullOrWhiteSpace(programPath) || !File.Exists(programPath))
|
||||
{
|
||||
throw new FileNotFoundException("Das ausgewählte Script wurde nicht gefunden.", scriptPath);
|
||||
throw new FileNotFoundException("Das ausgewählte Programm/Script wurde nicht gefunden.", programPath);
|
||||
}
|
||||
|
||||
string extension = Path.GetExtension(scriptPath).ToLowerInvariant();
|
||||
string workingDirectory = string.IsNullOrWhiteSpace(config.WorkingDirectory)
|
||||
? Path.GetDirectoryName(scriptPath) ?? Environment.CurrentDirectory
|
||||
: Environment.ExpandEnvironmentVariables(config.WorkingDirectory);
|
||||
string extension = Path.GetExtension(programPath).ToLowerInvariant();
|
||||
string workingDirectory = string.IsNullOrWhiteSpace(configuredWorkingDirectory)
|
||||
? Path.GetDirectoryName(programPath) ?? Environment.CurrentDirectory
|
||||
: Environment.ExpandEnvironmentVariables(configuredWorkingDirectory);
|
||||
|
||||
var startInfo = new ProcessStartInfo
|
||||
{
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = config.Hidden,
|
||||
WindowStyle = config.Hidden ? ProcessWindowStyle.Hidden : ProcessWindowStyle.Normal,
|
||||
CreateNoWindow = hidden,
|
||||
WindowStyle = hidden ? ProcessWindowStyle.Hidden : ProcessWindowStyle.Normal,
|
||||
WorkingDirectory = workingDirectory
|
||||
};
|
||||
|
||||
@@ -34,7 +46,7 @@ internal static class ScriptTestLauncher
|
||||
startInfo.ArgumentList.Add("/D");
|
||||
startInfo.ArgumentList.Add("/S");
|
||||
startInfo.ArgumentList.Add("/C");
|
||||
startInfo.ArgumentList.Add(BuildCmdCommand(scriptPath, config.Arguments));
|
||||
startInfo.ArgumentList.Add(BuildCmdCommand(programPath, configuredArguments));
|
||||
break;
|
||||
|
||||
case ".ps1":
|
||||
@@ -49,13 +61,13 @@ internal static class ScriptTestLauncher
|
||||
startInfo.ArgumentList.Add("-ExecutionPolicy");
|
||||
startInfo.ArgumentList.Add("Bypass");
|
||||
startInfo.ArgumentList.Add("-File");
|
||||
startInfo.ArgumentList.Add(scriptPath);
|
||||
AddRawArguments(startInfo, config.Arguments);
|
||||
startInfo.ArgumentList.Add(programPath);
|
||||
AddRawArguments(startInfo, configuredArguments);
|
||||
break;
|
||||
|
||||
case ".exe":
|
||||
startInfo.FileName = scriptPath;
|
||||
AddRawArguments(startInfo, config.Arguments);
|
||||
startInfo.FileName = programPath;
|
||||
AddRawArguments(startInfo, configuredArguments);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -66,9 +78,9 @@ internal static class ScriptTestLauncher
|
||||
?? throw new InvalidOperationException("Der Testprozess konnte nicht gestartet werden.");
|
||||
}
|
||||
|
||||
private static string BuildCmdCommand(string scriptPath, string? arguments)
|
||||
private static string BuildCmdCommand(string programPath, string? arguments)
|
||||
{
|
||||
string command = QuoteForCmd(scriptPath);
|
||||
string command = QuoteForCmd(programPath);
|
||||
if (!string.IsNullOrWhiteSpace(arguments))
|
||||
{
|
||||
command += " " + arguments;
|
||||
@@ -81,9 +93,6 @@ internal static class ScriptTestLauncher
|
||||
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))
|
||||
|
||||
Reference in New Issue
Block a user