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上有,用不大到。

 

posted @ 2018-07-04 08:42  海宏软件  阅读(1082)  评论(0编辑  收藏  举报