Выполните несколько команд с тем же процессом, используя .NET.
Я пытаюсь выполнить несколько команд без создания нового процесса каждый раз. В принципе, я хочу запустить командную оболочку DOS, переключиться на командную оболочку MySQL и выполнить команду. Вот как я называю процедуру (также ниже). Кроме того, как мне обрабатывать "\" в команде?
ExecuteCommand("mysql --user=root --password=sa casemanager", 100, false);
ExecuteCommand(@"\. " + Environment.CurrentDirectory + @"\MySQL\CaseManager.sql", 100, true);
private void ExecuteCommand(string Command, int Timeout, Boolean closeProcess)
{
ProcessStartInfo ProcessInfo;
Process Process;
ProcessInfo = new ProcessStartInfo("cmd.exe", "/C " + Command);
ProcessInfo.CreateNoWindow = false;
ProcessInfo.UseShellExecute = false;
Process = Process.Start(ProcessInfo);
Process.WaitForExit(Timeout);
if (closeProcess == true) { Process.Close(); }
}
Ответы
Ответ 1
Вы можете перенаправить стандартный ввод и использовать StreamWriter для его записи:
Process p = new Process();
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = "cmd.exe";
info.RedirectStandardInput = true;
info.UseShellExecute = false;
p.StartInfo = info;
p.Start();
using (StreamWriter sw = p.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
sw.WriteLine("mysql -u root -p");
sw.WriteLine("mypassword");
sw.WriteLine("use mydb;");
}
}
Ответ 2
const string strCmdText = "/C command1&command2";
Process.Start("CMD.exe", strCmdText);
Ответ 3
Не могли бы вы просто написать все команды в .cmd файл в папке temp и затем выполнить этот файл?
Ответ 4
ProcessStartInfo pStartInfo = new ProcessStartInfo();
pStartInfo.FileName = "CMD";
pStartInfo.Arguments = @"/C mysql --user=root --password=sa casemanager && \. " + Environment.CurrentDirectory + @"\MySQL\CaseManager.sql"
pStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(pStartInfo);
&&
- это способ сообщить командной оболочке, что есть другая команда для выполнения.
Ответ 5
Процесс командной строки, такой как cmd.exe
или mysql.exe
, обычно будет читать (и выполнять) все, что вы (пользователь) введите (на клавиатуре).
Чтобы подражать этому, я думаю, вы хотите использовать свойство RedirectStandardInput
: http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardinput.aspx
Ответ 6
Поместите наши команды в переменную С#. Так же, как мы печатаем на консоли.
var cmdCommands = [email protected]"
CD /
CALL none_existing_command /oops
ping example.com -n 5
CALL MsBuild SomeProject.csproj^
/target:Build^
/p:Configuration=Release^
/verbosity:normal^
/maxCpuCount
ECHO ErrorLever = %ERRORLEVEL%";
Теперь перейдите к
new CmdShell()
.Exec(cmdCommands);
И здесь реализация
public class CmdShell
{
public void Exec(string cmdCommands, bool throwExceptions = false, TimeSpan? executionLimit = null)
{
var commandsList = cmdCommands
.Replace("\r", string.Empty)
.Split('\n')
.ToList();
var info = new ProcessStartInfo
{
FileName = "cmd.exe",
// The false allows to access IO streams.
UseShellExecute = false,
// Allows write commands directly to a CMD-shell.
RedirectStandardInput = true,
};
var proc = new Process { StartInfo = info };
using (proc)
{
proc.Start();
commandsList.ForEach(command => proc
.StandardInput.WriteLine(command));
// Allows exiting from a CMD side.
proc.StandardInput.WriteLine("EXIT");
var span = executionLimit ?? TimeSpan.FromMinutes(15);
var milliseconds = span.TotalMilliseconds;
var duration = milliseconds < int.MaxValue
? (int)milliseconds
: int.MaxValue;
var interrupted = !proc.WaitForExit(duration);
if (!throwExceptions)
return;
if (interrupted)
throw new Exception("Duration limit is exceeded");
if (proc.ExitCode != 0)
throw new Exception(string.Format("Error exit code {0} received.", proc.ExitCode));
}
}
}
Известные проблемы
- Предпочитает использовать команду CALL CMD для вызова пакетных файлов. В противном случае вы можете повесить выполнение CMD в некоторых редких случаях.
Ответ 7
Вы также можете сказать MySQL выполнить команды в данном файле, например:
mysql --user=root --password=sa casemanager < CaseManager.sql
Ответ 8
Вам нужно ПРОЧИТАТЬ ВСЕ данные с ввода, прежде чем отправить другую команду!
И вы не можете просить ЧИТАТЬ, если нет данных... немного сосать нет?
Мои решения... когда прошу прочитать... попросите прочитать большой буфер... как 1 МЕГА...
И вам нужно подождать минут 100 миллисекунд... пример кода...
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim oProcess As New Process()
Dim oStartInfo As New ProcessStartInfo("cmd.exe", "")
oStartInfo.UseShellExecute = False
oStartInfo.RedirectStandardOutput = True
oStartInfo.RedirectStandardInput = True
oStartInfo.CreateNoWindow = True
oProcess.StartInfo = oStartInfo
oProcess.Start()
Dim Response As String = String.Empty
Dim BuffSize As Integer = 1024 * 1024
Dim x As Char() = New Char(BuffSize - 1) {}
Dim bytesRead As Integer = 0
oProcess.StandardInput.WriteLine("dir")
Threading.Thread.Sleep(100)
bytesRead = oProcess.StandardOutput.Read(x, 0, BuffSize)
Response = String.Concat(Response, String.Join("", x).Substring(0, bytesRead))
MsgBox(Response)
Response = String.Empty
oProcess.StandardInput.WriteLine("dir c:\")
Threading.Thread.Sleep(100)
bytesRead = 0
bytesRead = oProcess.StandardOutput.Read(x, 0, BuffSize)
Response = String.Concat(Response, String.Join("", x).Substring(0, bytesRead))
MsgBox(Response)
End Sub
End Class