OSDN Git Service

cfb1d5c4142900ba029f4093c07feda35752b6d5
[applistation/AppliStation.git] / na-get-lib / NaGet.InteropServices / CreateProcessCaller.cs
1 using System;\r
2 using System.Diagnostics;\r
3 using System.Runtime.InteropServices;\r
4 \r
5 namespace NaGet.InteropServices\r
6 {\r
7         public class CreateProcessCaller : IDisposable\r
8         {\r
9                 #region Win32API\r
10                 \r
11                 /*\r
12                 [StructLayout(LayoutKind.Sequential)]\r
13                 internal struct SECURITY_ATTRIBUTES\r
14                 {\r
15                     public int nLength;\r
16                     public IntPtr lpSecurityDescriptor;\r
17                     public int bInheritHandle;\r
18                 }\r
19                 */\r
20                 \r
21                 [StructLayout(LayoutKind.Sequential)]\r
22                 internal struct PROCESS_INFORMATION\r
23                 {\r
24                         public IntPtr hProcess;\r
25                         public IntPtr hThread;\r
26                         public int dwProcessId;\r
27                         public int dwThreadId;\r
28                 }\r
29                 \r
30                 [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]\r
31                 struct STARTUPINFO\r
32                 {\r
33                         public Int32 cb;\r
34                         string lpReserved;\r
35                         string lpDesktop;\r
36                         string lpTitle;\r
37                         Int32 dwX;\r
38                         Int32 dwY;\r
39                         Int32 dwXSize;\r
40                         Int32 dwYSize;\r
41                         Int32 dwXCountChars;\r
42                         Int32 dwYCountChars;\r
43                         Int32 dwFillAttribute;\r
44                         Int32 dwFlags;\r
45                         Int16 wShowWindow;\r
46                         Int16 cbReserved2;\r
47                         IntPtr lpReserved2;\r
48                         IntPtr hStdInput;\r
49                         IntPtr hStdOutput;\r
50                         IntPtr hStdError;\r
51                 }\r
52                 \r
53                 [DllImport("kernel32.dll", CharSet= CharSet.Auto, SetLastError=true)]\r
54                 static extern bool CreateProcess(string lpApplicationName,\r
55                         string lpCommandLine,\r
56                         /* ref SECURITY_ATTRIBUTES lpProcessAttributes, */\r
57                         IntPtr lpProcessAttributes,\r
58                         /* ref SECURITY_ATTRIBUTES lpThreadAttributes, */\r
59                         IntPtr lpThreadAttributes,\r
60                         bool bInheritHandles,\r
61                         uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory,\r
62                         [In] ref STARTUPINFO lpStartupInfo,\r
63                         out PROCESS_INFORMATION lpProcessInformation);\r
64                 \r
65                 [DllImport("kernel32", SetLastError=true, ExactSpelling=true)]\r
66                 static extern UInt32 WaitForSingleObject(IntPtr handle, UInt32 milliseconds);\r
67                 \r
68                 [DllImport("kernel32.dll", SetLastError=true)]\r
69                 [return: MarshalAs(UnmanagedType.Bool)]\r
70                 static extern bool CloseHandle(IntPtr hObject);\r
71                 \r
72                 [DllImport("kernel32.dll", SetLastError = true)]\r
73                 [return: MarshalAs(UnmanagedType.Bool)]\r
74                 static extern bool GetExitCodeProcess(IntPtr hProcess, out int lpExitCode);\r
75                 \r
76                 #endregion\r
77                 \r
78                 STARTUPINFO si;\r
79                 PROCESS_INFORMATION pi;\r
80                 \r
81                 public CreateProcessCaller(ProcessStartInfo procInfo)\r
82                 {\r
83                         if (procInfo.UseShellExecute) {\r
84                                 throw new ArgumentException("UseShellExecute must be false");\r
85                         }\r
86                         si.cb = Marshal.SizeOf(si);\r
87                         \r
88                         string lpFileName = (string.IsNullOrEmpty(procInfo.FileName))? null : procInfo.FileName;\r
89                         \r
90                         uint dwCreationFlags = 0x0020; // NORMAL_PRIORITY_CLASS\r
91                         if (procInfo.CreateNoWindow) dwCreationFlags |= 0x08000000; // CREATE_NO_WINDOW\r
92                         string lpCurrentDirectory = (System.IO.Directory.Exists(procInfo.WorkingDirectory))? procInfo.WorkingDirectory : null;\r
93                         \r
94                         bool retValue = CreateProcess(lpFileName, procInfo.Arguments,\r
95                                                       IntPtr.Zero, IntPtr.Zero,\r
96                                                       false, dwCreationFlags,\r
97                                                       IntPtr.Zero, lpCurrentDirectory, ref si, out pi);\r
98                         if (! retValue) {\r
99                                 throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());\r
100                         }\r
101                         CloseHandle(pi.hThread);\r
102                 }\r
103                 \r
104                 public uint WaitForExit(uint timeout)\r
105                 {\r
106                         return WaitForSingleObject(pi.hProcess, timeout);\r
107                 }\r
108                 \r
109                 public uint WaitForExit()\r
110                 {\r
111                         // return WaitForExit(INFINITE)\r
112                         return WaitForExit(0xFFFFFFFF);\r
113                 }\r
114                 \r
115                 public int ExitCode {\r
116                         get {\r
117                                 int lpExitCode;\r
118                                 if (! GetExitCodeProcess(pi.hProcess, out lpExitCode) ) {\r
119                                         throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());\r
120                                 }\r
121                                 return lpExitCode;\r
122                         }\r
123                 }\r
124                 \r
125                 public void Dispose()\r
126                 {\r
127                         CloseHandle(pi.hProcess);\r
128                 }\r
129                 \r
130         }\r
131 }\r