需要定义部分和执行部分,定义部分基本上是从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上有,用不大到。