Process.Start (推薦)using System.Diagnostics;
int processId;
private void BtnStart_Click(object sender, EventArgs e)
{
var proc = Process.Start(@"\\NandFlash\SerialTST.exe", "");
processId = proc.Id; // 取得 PID 供後續關閉
}
Process 物件,可直接 WaitForExit()、讀取 StandardOutput 等。CreateProcess (僅限極特殊需求)using System.Runtime.InteropServices;
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool CreateProcess(
string lpApplicationName,
string lpCommandLine,
IntPtr lpProcessAttributes,
IntPtr lpThreadAttributes,
bool bInheritHandles,
uint dwCreationFlags,
IntPtr lpEnvironment,
string lpCurrentDirectory,
[In] ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct STARTUPINFO
{
public int cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public int dwX, dwY, dwXSize, dwYSize;
public int dwXCountChars, dwYCountChars;
public int dwFillAttribute;
public int dwFlags;
public short wShowWindow;
public short cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput, hStdOutput, hStdError;
}
[StructLayout(LayoutKind.Sequential)]
struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
private void BtnStartApi_Click(object sender, EventArgs e)
{
var si = new STARTUPINFO { cb = Marshal.SizeOf(typeof(STARTUPINFO)) };
CreateProcess(@"\\NandFlash\SerialTST.exe", "", IntPtr.Zero, IntPtr.Zero,
false, 0, IntPtr.Zero, null, ref si, out var pi);
processId = pi.dwProcessId;
}
Marshal.GetLastWin32Error())。Process.GetProcessByIdprivate void BtnStop_Click(object sender, EventArgs e)
{
try
{
var proc = Process.GetProcessById(processId);
proc.Kill(); // 強制終止
// 或 proc.CloseMainWindow() 禮貌關閉 GUI 程式
}
catch (ArgumentException)
{
// 進程已不存在
}
}
| 需求 | 做法 |
|---|---|
| 等待結束並取得 ExitCode | proc.WaitForExit(); int code = proc.ExitCode; |
| 捕捉標準輸出/錯誤 | proc.StartInfo.RedirectStandardOutput = true; 並讀取 proc.StandardOutput.ReadToEnd() |
| 以不同使用者身分執行 | ProcessStartInfo.Verb = "runas" (UAC) 或設定 UserName/Password/Domain |
| 隱藏視窗 | proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; |
| 非同步啟動 | await Task.Run(() => Process.Start(...)) |
Process.Start,僅在需要 CreateProcess 獨有參數 (如 CREATE_BREAKAWAY_FROM_JOB) 時才 P/Invoke。Id,避免同名進程混淆。CloseMainWindow(),失敗再 Kill()。using 或 try/finally 確保 Process 物件釋放 (非 Unmanaged 資源,但屬良好習慣)。.NET Process 類別已封裝絕大多數啟動/管理外部進程的需求,除非遇到極罕見的底層需求,否則無需自行 P/Invoke Win32 API。