C#啓動一個外部程序(3)-CreateProcess

今天還是繼續說說C#調用系統Api啓動外部程序的方法,今天要說的是CreateProcess這個Api函數,相比前兩篇文章()中所說的Api,CreateProcess參數要更復雜一些,但使用起來,要更靈活。
1.

using System.Runtime.InteropServices;

2. CreateProcess中用到了幾個結構體類型,先聲明他們:

        [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
        
public class SECURITY_ATTRIBUTES
        {
            
public int nLength;
            
public string lpSecurityDescriptor;
            
public bool bInheritHandle;
        }

        [StructLayout(LayoutKind.Sequential)]
        
public struct STARTUPINFO
        {
            
public int cb;
            
public string lpReserved;
            
public string lpDesktop;
            
public int lpTitle;
            
public int dwX;
            
public int dwY;
            
public int dwXSize;
            
public int dwYSize;
            
public int dwXCountChars;
            
public int dwYCountChars;
            
public int dwFillAttribute;
            
public int dwFlags;
            
public int wShowWindow;
            
public int cbReserved2;
            
public byte lpReserved2;
            
public IntPtr hStdInput;
            
public IntPtr hStdOutput;
            
public IntPtr hStdError;
        }

        [StructLayout(LayoutKind.Sequential)]
        
public struct PROCESS_INFORMATION
        {
            
public IntPtr hProcess;
            
public IntPtr hThread;
            
public int dwProcessId;
            
public int dwThreadId;
        }

3. 聲明CreateProcess

        [DllImport("Kernel32.dll", CharSet = CharSet.Ansi)]
        
public static extern bool CreateProcess(
            StringBuilder lpApplicationName, StringBuilder lpCommandLine,
            SECURITY_ATTRIBUTES lpProcessAttributes,
            SECURITY_ATTRIBUTES lpThreadAttributes,
            
bool bInheritHandles,
            
int dwCreationFlags,
            StringBuilder lpEnvironment,
            StringBuilder lpCurrentDirectory,
            
ref STARTUPINFO lpStartupInfo,
            
ref PROCESS_INFORMATION lpProcessInformation
            );

4. 下邊這三個也是Api,作用看註釋

        #region Win32 Api : WaitForSingleObject
        //檢測一個系統核心對象(線程,事件,信號)的信號狀態,當對象執行時間超過dwMilliseconds就返回,否則就一直等待對象返回信號
        [DllImport("Kernel32.dll")]
        public static extern uint WaitForSingleObject(System.IntPtr hHandle, uint dwMilliseconds);

        #endregion

        #region Win32 Api : CloseHandle
        //關閉一個內核對象,釋放對象佔有的系統資源。其中包括文件、文件映射、進程、線程、安全和同步對象等
        [DllImport("Kernel32.dll")]
        public static extern bool CloseHandle(System.IntPtr hObject);

        #endregion       

        #region Win32 Api : GetExitCodeProcess
        //獲取一個已中斷進程的退出代碼,非零表示成功,零表示失敗。
        //參數hProcess,想獲取退出代碼的一個進程的句柄,參數lpExitCode,用於裝載進程退出代碼的一個長整數變量。
        [DllImport("Kernel32.dll")]
        static extern bool GetExitCodeProcess(System.IntPtr hProcess, ref uint lpExitCode);

        #endregion

5. 如果示例中argm指定的程序執行時間很長,進程會被阻塞到WaitForSingleObject行處,直到命令執行完畢或進程被中止才繼續執行後邊的語句。

            string argm = "cmd.exe";

            STARTUPINFO sInfo 
= new STARTUPINFO();
            PROCESS_INFORMATION pInfo 
= new PROCESS_INFORMATION();

            
if (!CreateProcess(nullnew StringBuilder(argm), nullnullfalse0nullnullref sInfo, ref pInfo))
            {
                
throw new Exception("調用失敗");
            }
            
uint i = 0;
            WaitForSingleObject(pInfo.hProcess, 
int.MaxValue);            
            GetExitCodeProcess(pInfo.hProcess, 
ref i);
            CloseHandle(pInfo.hProcess);
            CloseHandle(pInfo.hThread);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章