c#版的WinExecAndWait32,执行一个程序,等待他运行完毕,并回显他的显示
需要定义部分和执行部分,定义部分基本上是从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上有,用不大到。