使用c#调用API函数CreateProcess来运行外部程序

C#调用CreateProcess函数比较麻烦的地方就是该函数的那些参数用c#的语法如何定义,CreateProcess函数位于Kernel32.dll中,原形如下:

BOOL
CreateProcess(
   LPCTSTR lpApplicationName ,
   LPTSTR lpCommandLine ,
   LPSECURITY_ATTRIBUTES lpProcessAttributes ,
   LPSECURITY_ATTRIBUTES lpThreadAttributes ,
   BOOL bInheritHandles ,
   DWORD dwCreationFlags ,
   LPVOID lpEnvironment ,
   LPCTSTR lpCurrentDirectory ,
   LPSTARTUPINFO lpStartupInfo ,
   LPPROCESS_INFORMATION lpProcessInformation
);
用c#语法声明时,LPCTSTR,LBTSTR,LPVOID这三个类型我都把它定义为StringBuilder类型,DWORD定义为int类型,关键是这三个Struct该怎么定义;在c#中定义传给API的Struct参数时,即可以将它定义为Struct也可以定义成class,于是我把 LPSECURITY_ATTRIBUTES,LPSTARTUPINFO,LPPROCESS_INFORMATION 这三个Struct在c#中分别如下定义:
[StructLayout(LayoutKind.Sequential)]
        public class SECURITY_ATTRIBUTES
        {
            public int nLength;  
            public string lpSecurityDescriptor;  
            public bool bInheritHandle;
        }

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

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

这里我把LPSECURITY_ATTRIBUTES  定义为class,主要是为了接下来传null参数时方便些,下面是CreateProcess的声明部分:
  [DllImport("Kernel32.dll",CharSet=CharSet.Ansi)]
  public static extern bool CreateProcess(StringBuilder lpApplicationName,StringBuilder lpCommandLine,
                                                              SECURITY_ATTRIBUTES lpProcessAttributes,
                                                              SECURITY_ATTRIBUTES lpThreadAttributes,
                                                              bool bInheritHandles,
                                                              int dwCreationFlags,
                                                              StringBuilder lpEnvironment,
                                                              StringBuilder lpCurrentDirectory,
                                                              ref STARTUPINFO lpStartupInfo,
                                                              ref PROCESS_INFORMATION lpProcessInformation
                                                              );
最后两个参数之所以在前面加上ref,是因为这两个参数的值需要回传.
在程序中使用CreateProcess:
string sCommand=@"isqlw /S "+TBServer.Text.Trim()+" /d "+TBDataBase.Text.Trim()+" /U "+TBUserName.Text.Trim()+
                             " /P "+TBPassWord.Text.Trim()+" /i "+sCurrtFile+" /o "+sProgramCurrectPath+sLogFile;
   StringBuilder sbCommand=new StringBuilder(1000);
   sbCommand.Append(sCommand);

   STARTUPINFO sInfo=new STARTUPINFO();
   PROCESS_INFORMATION pInfo=new PROCESS_INFORMATION();  
      
   if (!CreateProcess(null,sbCommand,null,null,false,0,null,null,ref sInfo,ref pInfo))
   {
    throw new Exception("isqlw调用失败["+sFileName+"]");
   }
   WaitForSingleObject(pInfo.hProcess,600000000);
   CloseHandle(pInfo.hProcess);
   CloseHandle(pInfo.hThread);

这里用到了WaitForSingleObject函数,使用该函数的作用是让CreateProcess创建的新进程与本程序的主进程同步执行,如果不加WaitForSingleObject则这两个进程是异步执行的,该函数的第二个参数是设函数的超时时间(毫秒),如果设一个很大的值则表示直到第一个参数所指的进程执行结束,才能执行该函授后面的代码;WaitForSingleObject的声明如下:
  [DllImport("Kernel32.dll",CharSet=CharSet.Ansi)]
  public static extern int WaitForSingleObject(IntPtr hHandle,int dwMilliseconds);

CloseHandle申明如下:
  [DllImport("Kernel32.dll",CharSet=CharSet.Ansi)]
  public static extern bool CloseHandle(IntPtr hObject);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值