-
Notifications
You must be signed in to change notification settings - Fork 19
/
Command.cs
166 lines (144 loc) · 5.79 KB
/
Command.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Windows.Forms;
using CDBurnerXP;
using Ketarin.Forms;
namespace Ketarin
{
/// <summary>
/// Represents a user command, which can be any kind of scripting language.
/// </summary>
internal class Command
{
/// <summary>
/// Gets or sets the scripting language.
/// </summary>
public ScriptType Type { get; set; }
/// <summary>
/// Gets or sets the command text.
/// </summary>
public string Text { get; set; }
public Command(string text, ScriptType type)
{
this.Text = text;
this.Type = type;
}
public Command(string text, string type)
{
this.Text = text;
this.Type = ConvertToScriptType(type);
}
/// <summary>
/// Executes the command.
/// </summary>
/// <param name="targetFileName">Content for variable "{url:...}"</param>
public virtual int Execute(ApplicationJob application, string targetFileName = null, ApplicationJobError errorInfo = null)
{
switch (Type)
{
case ScriptType.CS:
UserCSScript script = new UserCSScript(this.Text);
script.Execute(application);
break;
case ScriptType.PowerShell:
PowerShellScript psScript = new PowerShellScript(this.Text);
psScript.Execute(application, errorInfo);
return Conversion.ToInt(psScript.LastOutput);
default:
return ExecuteBatchCommand(application, this.Text, targetFileName);
}
return 0;
}
/// <summary>
/// Executes a given command for the given application (also resolves variables).
/// </summary>
/// <returns>Exit code of the command, if not run in background</returns>
private static int ExecuteBatchCommand(ApplicationJob job, string commandText, string targetFileName)
{
// Ignore empty commands
if (string.IsNullOrEmpty(commandText)) return 0;
commandText = commandText.Replace("\r\n", "\n");
// Job specific data
commandText = job != null ? job.Variables.ReplaceAllInString(commandText, DateTime.MinValue, targetFileName, false) : UrlVariable.GlobalVariables.ReplaceAllInString(commandText);
// Replace variable: root
try
{
commandText = UrlVariable.Replace(commandText, "root", Path.GetPathRoot(Application.StartupPath), job);
}
catch (ArgumentException) { }
// Feed cmd.exe with our commands
ProcessStartInfo cmdExe = new ProcessStartInfo("cmd.exe")
{
RedirectStandardInput = true,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true
};
bool executeBackground = commandText.EndsWith("&");
commandText = commandText.TrimEnd('&');
using (Process proc = Process.Start(cmdExe))
{
StringBuilder commandResult = new StringBuilder();
// Set the event handler to asynchronously read the command output.
proc.OutputDataReceived += delegate(object sendingProcess, DataReceivedEventArgs outLine)
{
if (!string.IsNullOrEmpty(outLine.Data)) commandResult.AppendLine(outLine.Data);
};
proc.ErrorDataReceived += delegate(object sendingProcess, DataReceivedEventArgs outLine)
{
if (!string.IsNullOrEmpty(outLine.Data)) commandResult.AppendLine(outLine.Data);
};
// Start the asynchronous read of the command output stream.
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
// Input commands
using (proc.StandardInput)
{
string[] commands = commandText.Split('\n');
foreach (string command in commands)
{
if (!string.IsNullOrEmpty(command))
{
LogDialog.Log(job, "Executing command: " + command);
}
proc.StandardInput.WriteLine(command);
}
}
// Read output
if (!executeBackground)
{
proc.WaitForExit();
string commandResultString = commandResult.ToString();
if (!string.IsNullOrEmpty(commandResultString))
{
LogDialog.Log(job, "Command result: " + commandResultString);
}
return proc.ExitCode;
}
}
return 0;
}
/// <summary>
/// Converts a given string to a valid script type.
/// Batch is the default.
/// </summary>
public static ScriptType ConvertToScriptType(string text)
{
try
{
if (string.IsNullOrEmpty(text))
{
return ScriptType.Batch;
}
return (ScriptType)Enum.Parse(typeof(ScriptType), text);
}
catch (Exception)
{
return ScriptType.Batch;
}
}
}
}