c#版的WinExecAndWait32,執行一個程序,等待他運行完畢,並回顯他的顯示
阿新 • • 發佈:2018-07-04
realtime services sage 參數 work lec tostring 簡單 這一
需要定義部分和執行部分,定義部分基本上是從delphi改過來的,把他另存命名為dWindows.cs,代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; // using System.Runtime.InteropServices; namespace 應用服務器 { //轉載請註明海宏軟件,從0開始,測試了好幾天的。在delphi基礎上改過來的。
/// <summary> /// win32相關的api,從delphi的windows單元復制過來改的。 /// 一些定義可以從這裏搜:https://www.pinvoke.net ,很全 /// </summary> public partial class dWindows { #region //結構:SECURITY_ATTRIBUTES,安全屬性 [StructLayout(LayoutKind.Sequential)] public struct SECURITY_ATTRIBUTES { //https://www.pinvoke.net/default.aspx/Structures/SECURITY_ATTRIBUTES.html public uint nLength; //DWORD public string lpSecurityDescriptor; //Pointer類型。IntPtr、string、或者unsafe byte* lpSecurityDescriptor public bool bInheritHandle; //boolean } #endregion #region //結構:STARTUPINFO,啟動信息 [StructLayout(LayoutKind.Sequential)] public struct STARTUPINFO { public uint cb; public string lpReserved; //Pointer public string lpDesktop; //Pointer public string lpTitle; //Pointer public uint dwX; //DWORD public uint dwY; public uint dwXSize; public uint dwYSize; public uint dwXCountChars; public uint dwYCountChars; public uint dwFillAttribute; public uint dwFlags; public ushort wShowWindow; //Word public ushort cbReserved2; //Word public IntPtr lpReserved2; //PByte public IntPtr hStdInput; //THandle public IntPtr hStdOutput; //THandle public IntPtr hStdError; //THandle } #endregion #region //結構:STARTUPINFOEX,啟動信息擴展版 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct STARTUPINFOEX { //https://www.pinvoke.net/default.aspx/Structures/STARTUPINFOEX.html public STARTUPINFO StartupInfo; public IntPtr lpAttributeList; } #endregion #region //結構:PROCESS_INFORMATION,進程信息 [StructLayout(LayoutKind.Sequential)] public struct PROCESS_INFORMATION { //https://www.pinvoke.net/default.aspx/Structures/PROCESS_INFORMATION.html public IntPtr hProcess; //THandle public IntPtr hThread; public uint dwProcessId; //DWORD public uint dwThreadId; //DWORD } #endregion #region //WAIT_TIMEOUT等狀態,從delphi的windows.pas復制過來的狀態定義 public const ulong STATUS_WAIT_0 = 0x00000000; //{$EXTERNALSYM STATUS_WAIT_0} public const ulong STATUS_ABANDONED_WAIT_0 = 0x00000080; //{$EXTERNALSYM STATUS_ABANDONED_WAIT_0} public const ulong STATUS_USER_APC = 0x000000C0; //{$EXTERNALSYM STATUS_USER_APC} public const ulong STATUS_TIMEOUT = 0x00000102; //{$EXTERNALSYM STATUS_TIMEOUT} public const ulong STATUS_PENDING = 0x00000103; //{$EXTERNALSYM STATUS_PENDING} public const ulong STATUS_SEGMENT_NOTIFICATION = 0x40000005; //{$EXTERNALSYM STATUS_SEGMENT_NOTIFICATION} public const ulong STATUS_GUARD_PAGE_VIOLATION = (0x80000001); //{$EXTERNALSYM STATUS_GUARD_PAGE_VIOLATION} public const ulong STATUS_DATATYPE_MISALIGNMENT = (0x80000002); //{$EXTERNALSYM public const ulong STATUS_DATATYPE_MISALIGNMENT} public const ulong STATUS_BREAKPOINT = (0x80000003); //{$EXTERNALSYM public const ulong STATUS_BREAKPOINT} public const ulong STATUS_SINGLE_STEP = (0x80000004); //{$EXTERNALSYM public const ulong STATUS_SINGLE_STEP} public const ulong STATUS_ACCESS_VIOLATION = (0xC0000005); //{$EXTERNALSYM public const ulong STATUS_ACCESS_VIOLATION} public const ulong STATUS_IN_PAGE_ERROR = (0xC0000006); //{$EXTERNALSYM public const ulong STATUS_IN_PAGE_ERROR} public const ulong STATUS_INVALID_HANDLE = (0xC0000008); //{$EXTERNALSYM public const ulong STATUS_INVALID_HANDLE} public const ulong STATUS_NO_MEMORY = (0xC0000017); //{$EXTERNALSYM public const ulong STATUS_NO_MEMORY} public const ulong STATUS_ILLEGAL_INSTRUCTION = (0xC000001D); //{$EXTERNALSYM public const ulong STATUS_ILLEGAL_INSTRUCTION} public const ulong STATUS_NONCONTINUABLE_EXCEPTION = (0xC0000025); //{$EXTERNALSYM public const ulong STATUS_NONCONTINUABLE_EXCEPTION} public const ulong STATUS_INVALID_DISPOSITION = (0xC0000026); //{$EXTERNALSYM public const ulong STATUS_INVALID_DISPOSITION} public const ulong STATUS_ARRAY_BOUNDS_EXCEEDED = (0xC000008C); //{$EXTERNALSYM public const ulong STATUS_ARRAY_BOUNDS_EXCEEDED} public const ulong STATUS_FLOAT_DENORMAL_OPERAND = (0xC000008D); //{$EXTERNALSYM public const ulong STATUS_FLOAT_DENORMAL_OPERAND} public const ulong STATUS_FLOAT_DIVIDE_BY_ZERO = (0xC000008E); //{$EXTERNALSYM public const ulong STATUS_FLOAT_DIVIDE_BY_ZERO} public const ulong STATUS_FLOAT_INEXACT_RESULT = (0xC000008F); //{$EXTERNALSYM public const ulong STATUS_FLOAT_INEXACT_RESULT} public const ulong STATUS_FLOAT_INVALID_OPERATION = (0xC0000090); //{$EXTERNALSYM public const ulong STATUS_FLOAT_INVALID_OPERATION} public const ulong STATUS_FLOAT_OVERFLOW = (0xC0000091); //{$EXTERNALSYM public const ulong STATUS_FLOAT_OVERFLOW} public const ulong STATUS_FLOAT_STACK_CHECK = (0xC0000092); //{$EXTERNALSYM public const ulong STATUS_FLOAT_STACK_CHECK} public const ulong STATUS_FLOAT_UNDERFLOW = (0xC0000093); //{$EXTERNALSYM public const ulong STATUS_FLOAT_UNDERFLOW} public const ulong STATUS_INTEGER_DIVIDE_BY_ZERO = (0xC0000094); //{$EXTERNALSYM public const ulong STATUS_INTEGER_DIVIDE_BY_ZERO} public const ulong STATUS_INTEGER_OVERFLOW = (0xC0000095); //{$EXTERNALSYM public const ulong STATUS_INTEGER_OVERFLOW} public const ulong STATUS_PRIVILEGED_INSTRUCTION = (0xC0000096); //{$EXTERNALSYM public const ulong STATUS_PRIVILEGED_INSTRUCTION} public const ulong STATUS_STACK_OVERFLOW = (0xC00000FD); //{$EXTERNALSYM public const ulong STATUS_STACK_OVERFLOW} public const ulong STATUS_CONTROL_C_EXIT = (0xC000013A); //{$EXTERNALSYM public const ulong STATUS_CONTROL_C_EXIT} public const ulong WAIT_FAILED = 0xFFFFFFFF; //{$EXTERNALSYM WAIT_FAILED} public const ulong WAIT_OBJECT_0 = ((STATUS_WAIT_0) + 0); //{$EXTERNALSYM WAIT_OBJECT_0} public const ulong WAIT_ABANDONED = ((STATUS_ABANDONED_WAIT_0) + 0); //{$EXTERNALSYM WAIT_ABANDONED} public const ulong WAIT_ABANDONED_0 = ((STATUS_ABANDONED_WAIT_0) + 0); //{$EXTERNALSYM WAIT_ABANDONED_0} public const ulong WAIT_TIMEOUT = STATUS_TIMEOUT; //{$EXTERNALSYM WAIT_TIMEOUT} public const ulong WAIT_IO_COMPLETION = STATUS_USER_APC; //{$EXTERNALSYM WAIT_IO_COMPLETION} public const ulong STILL_ACTIVE = STATUS_PENDING; //{$EXTERNALSYM STILL_ACTIVE} public const ulong EXCEPTION_ACCESS_VIOLATION = STATUS_ACCESS_VIOLATION; //{$EXTERNALSYM public const ulong EXCEPTION_ACCESS_VIOLATION} public const ulong EXCEPTION_DATATYPE_MISALIGNMENT = STATUS_DATATYPE_MISALIGNMENT; //{$EXTERNALSYM public const ulong EXCEPTION_DATATYPE_MISALIGNMENT} public const ulong EXCEPTION_BREAKPOINT = STATUS_BREAKPOINT; //{$EXTERNALSYM public const ulong EXCEPTION_BREAKPOINT} public const ulong EXCEPTION_SINGLE_STEP = STATUS_SINGLE_STEP; //{$EXTERNALSYM public const ulong EXCEPTION_SINGLE_STEP} public const ulong EXCEPTION_ARRAY_BOUNDS_EXCEEDED = STATUS_ARRAY_BOUNDS_EXCEEDED; //{$EXTERNALSYM public const ulong EXCEPTION_ARRAY_BOUNDS_EXCEEDED} public const ulong EXCEPTION_FLT_DENORMAL_OPERAND = STATUS_FLOAT_DENORMAL_OPERAND; //{$EXTERNALSYM public const ulong EXCEPTION_FLT_DENORMAL_OPERAND} public const ulong EXCEPTION_FLT_DIVIDE_BY_ZERO = STATUS_FLOAT_DIVIDE_BY_ZERO; //{$EXTERNALSYM public const ulong EXCEPTION_FLT_DIVIDE_BY_ZERO} public const ulong EXCEPTION_FLT_INEXACT_RESULT = STATUS_FLOAT_INEXACT_RESULT; //{$EXTERNALSYM public const ulong EXCEPTION_FLT_INEXACT_RESULT} public const ulong EXCEPTION_FLT_INVALID_OPERATION = STATUS_FLOAT_INVALID_OPERATION; //{$EXTERNALSYM public const ulong EXCEPTION_FLT_INVALID_OPERATION} public const ulong EXCEPTION_FLT_OVERFLOW = STATUS_FLOAT_OVERFLOW; //{$EXTERNALSYM public const ulong EXCEPTION_FLT_OVERFLOW} public const ulong EXCEPTION_FLT_STACK_CHECK = STATUS_FLOAT_STACK_CHECK; //{$EXTERNALSYM public const ulong EXCEPTION_FLT_STACK_CHECK} public const ulong EXCEPTION_FLT_UNDERFLOW = STATUS_FLOAT_UNDERFLOW; //{$EXTERNALSYM public const ulong EXCEPTION_FLT_UNDERFLOW} public const ulong EXCEPTION_INT_DIVIDE_BY_ZERO = STATUS_INTEGER_DIVIDE_BY_ZERO; //{$EXTERNALSYM public const ulong EXCEPTION_INT_DIVIDE_BY_ZERO} public const ulong EXCEPTION_INT_OVERFLOW = STATUS_INTEGER_OVERFLOW; //{$EXTERNALSYM public const ulong EXCEPTION_INT_OVERFLOW} public const ulong EXCEPTION_PRIV_INSTRUCTION = STATUS_PRIVILEGED_INSTRUCTION; //{$EXTERNALSYM public const ulong EXCEPTION_PRIV_INSTRUCTION} public const ulong EXCEPTION_IN_PAGE_ERROR = STATUS_IN_PAGE_ERROR; //{$EXTERNALSYM public const ulong EXCEPTION_IN_PAGE_ERROR} public const ulong EXCEPTION_ILLEGAL_INSTRUCTION = STATUS_ILLEGAL_INSTRUCTION; //{$EXTERNALSYM public const ulong EXCEPTION_ILLEGAL_INSTRUCTION} public const ulong EXCEPTION_NONCONTINUABLE_EXCEPTION = STATUS_NONCONTINUABLE_EXCEPTION; //{$EXTERNALSYM public const ulong EXCEPTION_NONCONTINUABLE_EXCEPTION} public const ulong EXCEPTION_STACK_OVERFLOW = STATUS_STACK_OVERFLOW; //{$EXTERNALSYM public const ulong EXCEPTION_STACK_OVERFLOW} public const ulong EXCEPTION_INVALID_DISPOSITION = STATUS_INVALID_DISPOSITION; //{$EXTERNALSYM public const ulong EXCEPTION_INVALID_DISPOSITION} public const ulong EXCEPTION_GUARD_PAGE = STATUS_GUARD_PAGE_VIOLATION; //{$EXTERNALSYM public const ulong EXCEPTION_GUARD_PAGE} public const ulong EXCEPTION_INVALID_HANDLE = STATUS_INVALID_HANDLE; //{$EXTERNALSYM public const ulong EXCEPTION_INVALID_HANDLE} public const ulong CONTROL_C_EXIT = STATUS_CONTROL_C_EXIT; //{$EXTERNALSYM CONTROL_C_EXIT} #endregion #region //STARTF參數,從delphi的windows中復制來的 //{ Dual Mode API below this line.Dual Mode Structures also included. } public const UInt16 STARTF_USESHOWWINDOW = 1; //{$EXTERNALSYM STARTF_USESHOWWINDOW} public const uint STARTF_USESIZE = 2; //{$EXTERNALSYM STARTF_USESIZE} public const UInt16 STARTF_USEPOSITION = 4; //{$EXTERNALSYM STARTF_USEPOSITION} public const UInt16 STARTF_USECOUNTCHARS = 8; //{$EXTERNALSYM STARTF_USECOUNTCHARS} public const UInt16 STARTF_USEFILLATTRIBUTE = 0x10; //{$EXTERNALSYM STARTF_USEFILLATTRIBUTE} public const UInt16 STARTF_RUNFULLSCREEN = 0x20; //{ ignored for non-x86 platforms } //{$EXTERNALSYM STARTF_RUNFULLSCREEN} public const UInt16 STARTF_FORCEONFEEDBACK = 0x40; //{$EXTERNALSYM STARTF_FORCEONFEEDBACK} public const UInt16 STARTF_FORCEOFFFEEDBACK = 0x80; //{$EXTERNALSYM STARTF_FORCEOFFFEEDBACK} public const UInt16 STARTF_USESTDHANDLES = 0x100; //{$EXTERNALSYM STARTF_USESTDHANDLES} public const UInt16 STARTF_USEHOTKEY = 0x200; //{$EXTERNALSYM STARTF_USEHOTKEY} #endregion #region //CREATE創建參數,從delphi的windows中復制過來的 public const uint DEBUG_PROCESS = 0x00000001; //{$EXTERNALSYM public const uint DEBUG_PROCESS} public const uint DEBUG_ONLY_THIS_PROCESS = 0x00000002; //{$EXTERNALSYM public const uint DEBUG_ONLY_THIS_PROCESS} public const uint CREATE_SUSPENDED = 0x00000004; //{$EXTERNALSYM public const uint CREATE_SUSPENDED} public const uint DETACHED_PROCESS = 0x00000008; //{$EXTERNALSYM DETACHED_PROCESS} public const uint CREATE_NEW_CONSOLE = 0x00000010; //{$EXTERNALSYM public const uint CREATE_NEW_CONSOLE} public const uint NORMAL_PRIORITY_CLASS = 0x00000020; //{$EXTERNALSYM public const uint NORMAL_PRIORITY_CLASS} public const uint IDLE_PRIORITY_CLASS = 0x00000040; //{$EXTERNALSYM IDLE_PRIORITY_CLASS} public const uint HIGH_PRIORITY_CLASS = 0x00000080; //{$EXTERNALSYM HIGH_PRIORITY_CLASS} public const uint REALTIME_PRIORITY_CLASS = 0x00000100; //{$EXTERNALSYM REALTIME_PRIORITY_CLASS} public const uint CREATE_NEW_PROCESS_GROUP = 0x00000200; //{$EXTERNALSYM public const uint CREATE_NEW_PROCESS_GROUP} public const uint CREATE_UNICODE_ENVIRONMENT = 0x00000400; //{$EXTERNALSYM public const uint CREATE_UNICODE_ENVIRONMENT} public const uint CREATE_SEPARATE_WOW_VDM = 0x00000800; //{$EXTERNALSYM public const uint CREATE_SEPARATE_WOW_VDM} public const uint CREATE_SHARED_WOW_VDM = 0x00001000; //{$EXTERNALSYM public const uint CREATE_SHARED_WOW_VDM} public const uint CREATE_FORCEDOS = 0x00002000; //{$EXTERNALSYM public const uint CREATE_FORCEDOS} public const uint CREATE_DEFAULT_ERROR_MODE = 0x04000000; //{$EXTERNALSYM public const uint CREATE_DEFAULT_ERROR_MODE} public const uint CREATE_NO_WINDOW = 0x08000000; //{$EXTERNALSYM public const uint CREATE_NO_WINDOW} #endregion //無效的句柄值:0xFFFF FFFF public const uint INVALID_HANDLE_VALUE = unchecked((uint)-1); #region //Win32 Api : CreateProcess,啟動一個外部程序 /// <summary> /// 啟動一個外部程序,帶著參數 /// </summary> /// <param name="lpApplicationName">用法1:null;用法2:程序名.exe(不含參數,必須帶exe)</param> /// <param name="lpCommandLine">用法1:完整的命令行帶著程序名和參數等全部;用法2:參數(不含程序名)</param> /// <param name="lpProcessAttributes">pointer to process security attributes</param> /// <param name="lpThreadAttributes">pointer to thread security attributes</param> /// <param name="bInheritHandles">handle inheritance flag</param> /// <param name="dwCreationFlags">創建參數,比如:dWindows.CREATE_NO_WINDOW</param> /// <param name="lpEnvironment">pointer to new environment block</param> /// <param name="lpCurrentDirectory">pointer to current directory name, PChar</param> /// <param name="lpStartupInfo">pointer to STARTUPINFO</param> /// <param name="lpProcessInformation">pointer to PROCESS_INF</param> /// <returns>成功與否</returns> [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern bool CreateProcess( string lpApplicationName, //PChar string lpCommandLine, //PChar ref SECURITY_ATTRIBUTES lpProcessAttributes, //PSecurityAttributes ref SECURITY_ATTRIBUTES lpThreadAttributes, //PSecurityAttributes bool bInheritHandles, uint dwCreationFlags, //DWORD IntPtr lpEnvironment, //Pointer string lpCurrentDirectory, //PChar [In] ref STARTUPINFO lpStartupInfo, //TStartupInfo out PROCESS_INFORMATION lpProcessInformation); //TProcessInformation //[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 // ); #endregion #region //Win32 Api : WaitForSingleObject,檢測一個核心對象,等待他返回信號 /// <summary> /// 檢測一個系統核心對象(線程,事件,信號)的信號狀態,當對象執行時間超過dwMilliseconds就返回,否則就一直等待對象返回信號 /// </summary> /// <param name="hHandle">句柄</param> /// <param name="dwMilliseconds">等待時長</param> /// <returns>返回WAIT_TIMEOUT、STATUS_這類狀態值</returns> [DllImport("Kernel32.dll")] public static extern uint WaitForSingleObject(System.IntPtr hHandle, uint dwMilliseconds); #endregion #region //Win32 Api : CloseHandle,關閉一個內核對象 /// <summary> /// 關閉一個內核對象,釋放對象占有的系統資源。其中包括文件、文件映射、進程、線程、安全和同步對象等 /// </summary> /// <param name="hObject">對象句柄</param> /// <returns>成功與否</returns> [DllImport("Kernel32.dll")] public static extern bool CloseHandle(System.IntPtr hObject); #endregion #region //Win32API:CreatePipe,創建線程間通信的匿名管道,返回讀寫管道的handle /// <summary> /// 創建線程間通信的匿名管道,返回讀寫管道的handle /// 參考網址:https://blog.csdn.net/dacxu/article/details/30071081 /// </summary> /// <param name="hReadPipe">返回對管道讀的handle</param> /// <param name="hWritePipe">返回對管道寫的handle</param> /// <param name="lpPipeAttributes">指向SECURITY_ATTRIBUTES結構的指針。SECURITY_ATTRIBUTES決定了子進程是否可以繼承管道的讀寫handle。如果lpPipeAttributes是NULL,不能繼承。</param> /// <param name="nSize">管道的緩沖空間。只是一個建議值,系統會根據建議值計算出一個合適的值。如果nSize是0,使用缺省值。</param> /// <returns>如果函數執行成功,返回值非0.如果失敗,返回0。可以通過GetLastError獲得更多的信息</returns> [DllImport("kernel32.dll")] public static extern bool CreatePipe(out IntPtr hReadPipe, out IntPtr hWritePipe, ref SECURITY_ATTRIBUTES lpPipeAttributes, uint nSize); #endregion #region //Win32 Api : GetExitCodeProcess,獲取一個已中斷線程的退出代碼,非0表示成功,0表示失敗 /// <summary> /// 獲取一個已中斷進程的退出代碼,非零表示成功,零表示失敗。 /// 參數hProcess,想獲取退出代碼的一個進程的句柄,參數lpExitCode,用於裝載進程退出代碼的一個長整數變量。 /// </summary> /// <param name="hProcess"></param> /// <param name="lpExitCode"></param> /// <returns></returns> [DllImport("Kernel32.dll")] public static extern bool GetExitCodeProcess(System.IntPtr hProcess, ref uint lpExitCode); #endregion #region //win32API:ReadFile,讀取文件 //1 [DllImport("kernel32.dll", SetLastError = true)] public static extern bool ReadFile(IntPtr hFile, [Out] byte[] lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped); //2 [DllImport("kernel32.dll", SetLastError = true)] public static extern unsafe int ReadFile(IntPtr handle, IntPtr bytes, uint numBytesToRead, IntPtr numBytesRead, System.Threading.NativeOverlapped* overlapped); //3 [DllImport("kernel32.dll", SetLastError = true)] public static extern bool ReadFile(IntPtr hFile, [Out] byte[] lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, [In] ref System.Threading.NativeOverlapped lpOverlapped); //4 [DllImport("kernel32.dll", SetLastError = true)] public unsafe static extern bool ReadFile( int hFile, // handle to file byte[] lpBuffer, // data buffer int nNumberOfBytesToRead, // number of bytes to read ref int lpNumberOfBytesRead, // number of bytes read int* ptr // // ref OVERLAPPED lpOverlapped // overlapped buffer ); //5 [DllImport(@"kernel32", CharSet = CharSet.Auto, SetLastError = true)] public static extern unsafe bool ReadFile( IntPtr hFile, //SafeFileHandle, handle to file byte* pBuffer, // data buffer, should be fixed int NumberOfBytesToRead, // number of bytes to read IntPtr pNumberOfBytesRead, // number of bytes read, provide NULL here System.Threading.NativeOverlapped* lpOverlapped // should be fixed, if not null ); #endregion } }
然後是函數exeAndWait32,把他另存為iWin32.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; // using System.Windows; using System.Windows.Forms; using System.IO; using System.Runtime.InteropServices; using iPublic; using Gs_Class; namespace 應用服務器 { public partial class iWin32 { //轉載請註明海宏軟件,從0開始,測試了好幾天的。在delphi基礎上改過來的。 /// <summary> /// 執行程序,並等待其返回值System.exitCode,照著delphi成熟的寫法改過來的。 /// 參考:http://delphi.ktop.com.tw/board.php?cid=168&fid=914&tid=36163 /// </summary> /// <param name="sExe">完整的命令行,帶著程序名、參數</param> /// <param name="onShowInfo">命令行執行時的回調顯示</param> /// <returns></returns> public static uint WinExecAndWait32(string sExe, gsDefineTypes.showInfoDelegate onShowInfo) { uint rt = 0, n = 0; //dword dWindows.STARTUPINFO si = new dWindows.STARTUPINFO(); //STARTUPINFO; dWindows.PROCESS_INFORMATION pi = new dWindows.PROCESS_INFORMATION(); //PROCESS_INFORMATION; StringBuilder p; //pAnsiChar; string s = "", sPath = "", sApp = "", sParam = ""; // dWindows.SECURITY_ATTRIBUTES sa = new dWindows.SECURITY_ATTRIBUTES(); //sa: TSecurityAttributes; dWindows.SECURITY_ATTRIBUTES pSec; //pSec: pointer; IntPtr hReadPipe = IntPtr.Zero, hWritePipe = IntPtr.Zero; //THandle; uint lngBytesread; //dword; bool L, lInfo = false; //BOOL; char[] buf = new char[256]; //array[0..255] of char; // uint result = 0; //zeroMemory(@si, sizeOf(si)); si.cb = (uint)Marshal.SizeOf(si); //si.cb:= sizeOf(si); //zeroMemory(@pi, sizeOf(pi)); ////pSec:= nil; sa.nLength = (uint)Marshal.SizeOf(sa); //sa.nLength := Sizeof(sa); if (onShowInfo != null) //if assigned(onShowInfo) then begin { //FillChar(sa, Sizeof(sa),#0); sa.bInheritHandle = true; //sa.lpSecurityDescriptor = string.Empty; //nil //L:= CreatePipe(hReadPipe, hWritePipe, @sa, 0); lInfo = dWindows.CreatePipe(out hReadPipe, out hWritePipe, ref sa, 0); //pSec:= @sa; //si.dwFlags:= STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; si.dwFlags = dWindows.STARTF_USESHOWWINDOW + dWindows.STARTF_USESTDHANDLES; //si.wShowWindow:=Visibility; //si.hStdOutput:= hWritePipe; si.hStdOutput = hWritePipe; //si.hStdError:= hWritePipe; si.hStdError = hWritePipe; } //這一行比較特殊 pSec = sa; //路徑 extractFilePathNoParam(sExe, ref sPath, ref sApp, ref sParam); //sPath:= extractFilePathNoParam(sExe); //Environment.GetEnvironmentVariable("windir")+ if (sPath == "") sPath = Path.GetDirectoryName(Application.ExecutablePath); //if sPath=‘‘ then sPath:= extractFilePath(application.exeName); if (sPath != "" && !sPath.EndsWith("\\")) sPath += "\\"; //if (!sApp.Contains("\\")) sApp = sPath + sApp; if (sParam != "") sParam = " " + sParam; //sExe:=‘"‘+sExe+‘"‘; lInfo = (onShowInfo != null); if (!dWindows.CreateProcess(null, //這裏可以寫sApp,得帶.exe,比如:ffmpeg.exe可以,ffmpeg就報錯。不用帶路徑 sExe, //這裏可以寫sParam.{ pointer to command line string} ref pSec, //{ pointer to process security attributes} ref pSec, //{ pointer to thread security attributes } lInfo, //{ 20180622之前是FALSE。handle inheritance flag } (uint)dWindows.CREATE_NO_WINDOW, IntPtr.Zero, //{ pointer to new environment block } sPath, //{ pointer to current directory name, PChar} ref si, //{ pointer to STARTUPINFO } out pi //{ pointer to PROCESS_INF } )) { throw new Exception("創建線程出錯!CreateProcess failed! \n起始路徑:" + sPath + ",錯誤代碼:" + Marshal.GetLastWin32Error().ToString()); //return iWindows.INVALID_HANDLE_VALUE; } //開始執行、等待 if (onShowInfo != null) dWindows.CloseHandle(hWritePipe); //CloseHandle(hWritePipe); //關閉輸入 do { //repeat if (onShowInfo != null) { //if assigned(onShowInfo) then begin fillChar(buf, buf.Length, (char)0); //fillChar(buf, Sizeof(buf), #0); //L:= ReadFile(hReadPipe, buf, 256, lngBytesread, nil); //從輸出中讀 lInfo = ReadFile(hReadPipe, buf, 256, out lngBytesread, IntPtr.Zero); //if lInfo then onShowInfo(trim(buf)); if (lInfo) { s = new string(buf).Trim(); if (lInfo) onShowInfo(s, true); } } //繼續,等待 rt = dWindows.WaitForSingleObject(pi.hProcess, 0); //rt:= WaitForSingleObject(pi.hProcess, 0); Application.DoEvents(); //Application.ProcessMessages(); System.Threading.Thread.Sleep(200); //Sleep(500) } //until(rt <> wait_TimeOut) or(lGlobalTerminateWorking); while (rt == dWindows.WAIT_TIMEOUT && !gsDefineTypes.GlobalTerminateWorking); //if (GetExitCodeProcess(pi.hProcess, rt)) then result:= rt; if (dWindows.GetExitCodeProcess(pi.hProcess, ref rt)) result = rt; // dWindows.CloseHandle(pi.hProcess); //CloseHandle(pi.hProcess); dWindows.CloseHandle(pi.hThread); //CloseHandle(pi.hThread); //if assigned(onShowInfo) then CloseHandle(hReadPipe); if (onShowInfo != null) dWindows.CloseHandle(hReadPipe); //完成 return result; } public static void extractFilePathNoParam(string sDosCommand, ref string sPath, ref string sApp, ref string sCmdParam) { //移除文件名中的參數。系統自帶函數:GetParamStr string result = Path.GetDirectoryName(sDosCommand); //result:= extractFilePath(AFile); string s = sDosCommand, s2 = ""; //s:= AFile; int i = iGetParamPosition(sDosCommand); //i:= iGetParamPosition(s); if (i > 0) { result = Path.GetDirectoryName(s.Substring(0, i));//result:= extractFilePath(trim(copy(s, 1, i))); sApp = sDosCommand.Substring(0, i).Trim(); sCmdParam = sDosCommand.Substring(i, sDosCommand.Length - i).Trim(); } sPath = result; } private static int iGetParamPosition(string AFile) { //參數的開始點:GetParamStr //var i, j, nDrv:integer;lHead: boolean; //c, c2: char; s,s2: string; int result = 0; string s = AFile.Trim(); //s:= trim(AFile); //盤符,例如: d:\a.exe -p1=f:\a.bmp 或者:a.exe .\a.exe ..\a.exe s = s.Substring(1 - 1, 2) + s.Substring(3 - 1, s.Length - 3).Replace(":", ""); //s:= copy(s, 1, 2) + StringReplace(copy(s, 3, length(s)), ‘:‘, ‘‘, [rfReplaceAll]); string s2 = s; int i = -1; char c, c2 = ‘ ‘; //去掉文件名中的參數 while (s != "") { c = s[s.Length - 1]; //c:= s[length(s)]; //最後一個字符 //s:= copy(s, 1, length(s) - 1); //去掉最後一個字符 s = s.Substring(1 - 1, s.Length - 1); //if (c = ‘ ‘) and(c2 in [‘-‘, ‘/‘, ‘#‘]) then i:= length(s); //空格後邊跟著-/符號,表示參數 if ((c == ‘ ‘) && (c2 == ‘-‘ || c2 == ‘/‘ || c2 == ‘#‘)) i = s.Length; c2 = c; } if (i > 0) result += i; //if (i > 0) then result:= result + i; return result; } public static void fillChar(char[] buf, int length, char v) { for (int i = 0; i < length; i++) buf[i] = v; } //用來讀dos句柄返回值的,因為默認的是byte[],這裏改成char[]方便讀 [DllImport("kernel32.dll", SetLastError = true)] public static extern bool ReadFile(IntPtr hFile, [Out] char[] lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped); } }
然後調用就簡單了:
iWin32.WinExecAndWait32(sCmd, showInfoWin32);
這裏的showInfo無非就是txt.appendText(信息)這樣。
if (txt_info.Lines.Count() > 500) txt_info.Clear(); txt_info.AppendText(s + "\r\n");
Gs_Class有關的是海宏運行類庫,在csdn上有,用不大到。
c#版的WinExecAndWait32,執行一個程序,等待他運行完畢,並回顯他的顯示