因此,我使用自己的.NET Process来启动命令行进程,如下所示:
ProcessStartInfo startInfo = new ProcessStartInfo();
Process p = new Process();
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = redirectOutput;
startInfo.RedirectStandardError = redirectError;
//startInfo.WindowStyle = ProcessWindowStyle.Hidden; //is this necessary for cmd line commands?
startInfo.RedirectStandardInput = false;
startInfo.UseShellExecute = false;
String arguments = "/C PYTHON_SCRIPT";
startInfo.Arguments = arguments;
String pathToProcess = "cmd.exe";
startInfo.FileName = pathToProcess;
startInfo.WorkingDirectory = workingDirectory;
p.StartInfo = startInfo;
p.Start();
Process p = new Process();
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = redirectOutput;
startInfo.RedirectStandardError = redirectError;
//startInfo.WindowStyle = ProcessWindowStyle.Hidden; //is this necessary for cmd line commands?
startInfo.RedirectStandardInput = false;
startInfo.UseShellExecute = false;
String arguments = "/C PYTHON_SCRIPT";
startInfo.Arguments = arguments;
String pathToProcess = "cmd.exe";
startInfo.FileName = pathToProcess;
startInfo.WorkingDirectory = workingDirectory;
p.StartInfo = startInfo;
p.Start();
该过程执行得很好,我得到它的输出/错误。当我想在完成执行之前将其删除时,问题就出现了。由于cmd行在技术上从“PYTHON_SCRIPT”进程本身开始,我不知道该进程的进程ID是什么!因为那是我真正想要杀死的那个(不是cmd线),我搞砸了。事实上,我已经杀死了cmd行进程以查看它是否有任何效果,但事实并非如此。
任何帮助将不胜感激。
如果不清楚,问题是:“我如何杀掉PYTHON_SCRIPT(或任何其他)进程?”
编辑:对不起,我不清楚......我正在使用PYTHON_SCRIPT作为填充物。我以这种方式启动了许多不同的进程,并非所有进程都是python脚本。有些是批处理文件,有些是python脚本,有些是perl脚本等。我更喜欢这里的通用解决方案。编辑2:情况比问题中出现的情况稍微复杂一些。例如,我正在使用scons来构建一些代码。使用“cmd / C scons”很容易。但是,启动scons进程要困难得多,因为它是一个python脚本。我传入了一个不同的工作目录,所以“python.exe scons.py scons”根本不起作用,“scons.bat scons”也不会,因为scons.bat需要找到scons.py,scons.py isn在我的工作目录中。
答案 0 :(得分:2)
终于通过坚持不懈和google foo找到了答案!这是stackoverflow答案的链接:
https://stackoverflow.com/a/15281070/476298
这是指向我这个方向的网站:
看起来他对此进行了大量的研究。绝对想给他所有的功劳。希望这个页面可以帮助那些还没有找到它的人!
我在为WinAPI方法找出一些D11Import的东西时遇到了一些麻烦,所以这里是我用过的代码,以防其他人被挂起:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AttachConsole(uint dwProcessId);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern bool FreeConsole();
// Delegate type to be used as the Handler Routine for SCCH
delegate Boolean ConsoleCtrlDelegate(CtrlTypes CtrlType);
[DllImport("kernel32.dll")]
static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add);
// Enumerated type for the control messages sent to the handler routine
enum CtrlTypes : uint
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT,
CTRL_CLOSE_EVENT,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT
}
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GenerateConsoleCtrlEvent(CtrlTypes dwCtrlEvent, uint dwProcessGroupId);
///
/// Immediately halts all running processes under this ProcessManager's control.
///
public static void HaltAllProcesses()
{
for (int i = 0; i < runningProcesses.Count; i++)
{
Process p = runningProcesses[i];
uint pid = (uint)p.Id;
//This does not require the console window to be visible.
if (AttachConsole(pid))
{
//Disable Ctrl-C handling for our program
SetConsoleCtrlHandler(null, true);
GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, 0);
//Must wait here. If we don't and re-enable Ctrl-C
//handling below too fast, we might terminate ourselves.
p.WaitForExit(2000);
FreeConsole();
//Re-enable Ctrl-C handling or any subsequently started
//programs will inherit the disabled state.
SetConsoleCtrlHandler(null, false);
}
if (!p.HasExited)
{ //for console-driven processes, this won't even do anything... (it'll kill the cmd line, but not the actual process)
try
{
p.Kill();
}
catch (InvalidOperationException e)
{
controller.PrintImportantError("Process " + p.Id + " failed to exit! Error: " + e.ToString());
}
}
}
}
P.S。如果从代码中不明显,我将存储一个同时运行的多个进程的列表,并且只是逐个循环遍历它们以终止它们。
答案 1 :(得分:1)
如果您可以运行CMD流程,并且知道您的流程PID,为什么不简单地使用TASKKILL /PID 1234
?
我没有到达的地方是你从哪里获得PID。
答案 2 :(得分:0)
此link非常有用
// Get the current process.
Process currentProcess = Process.GetCurrentProcess();
// Get all instances of Notepad running on the local
// computer.
Process [] localByName = Process.GetProcessesByName("notepad");
// Get all instances of Notepad running on the specifiec
// computer.
// 1. Using the computer alias (do not precede with "\\").
Process [] remoteByName = Process.GetProcessesByName("notepad", "myComputer");
// 2. Using an IP address to specify the machineName parameter.
Process [] ipByName = Process.GetProcessesByName("notepad", "169.0.0.0");
// Get all processes running on the local computer.
Process [] localAll = Process.GetProcesses();
// Get all processes running on the remote computer.
Process [] remoteAll = Process.GetProcesses("myComputer");
// Get a process on the local computer, using the process id.
Process localById = Process.GetProcessById(1234);
// Get a process on a remote computer, using the process id.
Process remoteById = Process.GetProcessById(2345,"myComputer");
答案 3 :(得分:0)
使用GetProcessesByName()并查找“python.exe”或“pythonw.exe”进程。