OSDN Git Service

AppliStation,バージョンを1.1.0.*に変更。ソースファイルへのコメントの加筆
[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         /// <summary>\r
8         /// Win32 API \82Ì<code>CreateProcess</code>\82ð\92¼\82É\92@\82­\82½\82ß\82Ì\83N\83\89\83X\81B\r
9         /// </summary>\r
10         /// <remarks>\r
11         /// .NET\82ÌProcess.Start\82Í\81A<code>CreateProcess(NULL, cmdLine, ...)</code>\r
12         /// \82Ì\82æ\82¤\82É\91æ\88ê\88ø\90\94\82ª<code>NULL</code>\82É\91\8a\93\96\82·\82é\8cÄ\82Ñ\8fo\82µ\82ª\81A\r
13         /// *\8cµ\96§\82È\88Ó\96¡*\82Å\82Å\82«\82È\82¢\81B\8cµ\96§\82È\88Ó\96¡\82Å\81A\r
14         /// \82±\82ê\82Æ\93¯\82\8cÄ\82Ñ\8fo\82µ\82ð\8eÀ\8c»\82·\82é\95K\97v\82ª\82 \82é\82Æ\82«\82É\8eg\82í\82ê\82é\81B\r
15         /// </remarks>\r
16         public class CreateProcessCaller : IDisposable\r
17         {\r
18                 #region Win32API\r
19                 \r
20                 /*\r
21                 [StructLayout(LayoutKind.Sequential)]\r
22                 internal struct SECURITY_ATTRIBUTES\r
23                 {\r
24                     public int nLength;\r
25                     public IntPtr lpSecurityDescriptor;\r
26                     public int bInheritHandle;\r
27                 }\r
28                 */\r
29                 \r
30                 [StructLayout(LayoutKind.Sequential)]\r
31                 internal struct PROCESS_INFORMATION\r
32                 {\r
33                         public IntPtr hProcess;\r
34                         public IntPtr hThread;\r
35                         public int dwProcessId;\r
36                         public int dwThreadId;\r
37                 }\r
38                 \r
39                 [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]\r
40                 struct STARTUPINFO\r
41                 {\r
42                         public Int32 cb;\r
43                         string lpReserved;\r
44                         string lpDesktop;\r
45                         string lpTitle;\r
46                         Int32 dwX;\r
47                         Int32 dwY;\r
48                         Int32 dwXSize;\r
49                         Int32 dwYSize;\r
50                         Int32 dwXCountChars;\r
51                         Int32 dwYCountChars;\r
52                         Int32 dwFillAttribute;\r
53                         Int32 dwFlags;\r
54                         Int16 wShowWindow;\r
55                         Int16 cbReserved2;\r
56                         IntPtr lpReserved2;\r
57                         IntPtr hStdInput;\r
58                         IntPtr hStdOutput;\r
59                         IntPtr hStdError;\r
60                 }\r
61                 \r
62                 [DllImport("kernel32.dll", CharSet= CharSet.Auto, SetLastError=true)]\r
63                 static extern bool CreateProcess(string lpApplicationName,\r
64                         string lpCommandLine,\r
65                         /* ref SECURITY_ATTRIBUTES lpProcessAttributes, */\r
66                         IntPtr lpProcessAttributes,\r
67                         /* ref SECURITY_ATTRIBUTES lpThreadAttributes, */\r
68                         IntPtr lpThreadAttributes,\r
69                         bool bInheritHandles,\r
70                         uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory,\r
71                         [In] ref STARTUPINFO lpStartupInfo,\r
72                         out PROCESS_INFORMATION lpProcessInformation);\r
73                 \r
74                 [DllImport("kernel32", SetLastError=true, ExactSpelling=true)]\r
75                 static extern UInt32 WaitForSingleObject(IntPtr handle, UInt32 milliseconds);\r
76                 \r
77                 [DllImport("kernel32.dll", SetLastError=true)]\r
78                 [return: MarshalAs(UnmanagedType.Bool)]\r
79                 static extern bool CloseHandle(IntPtr hObject);\r
80                 \r
81                 [DllImport("kernel32.dll", SetLastError = true)]\r
82                 [return: MarshalAs(UnmanagedType.Bool)]\r
83                 static extern bool GetExitCodeProcess(IntPtr hProcess, out int lpExitCode);\r
84                 \r
85                 #endregion\r
86                 \r
87                 STARTUPINFO si;\r
88                 PROCESS_INFORMATION pi;\r
89                 \r
90                 /// <summary>\r
91                 /// \83v\83\8d\83Z\83X\82ð\90\90¬\82·\82é\r
92                 /// </summary>\r
93                 /// <param name="procInfo">\83v\83\8d\83Z\83X\8bN\93®\8fî\95ñ\81B\r
94                 /// \82È\82¨\81A<code>procInfo.UseShellExecute</code>\82Í\95K\82¸false\82Å\82È\82¯\82ê\82Î\82È\82ç\82È\82¢</param>\r
95                 public CreateProcessCaller(ProcessStartInfo procInfo)\r
96                 {\r
97                         if (procInfo.UseShellExecute) {\r
98                                 throw new ArgumentException("UseShellExecute must be false");\r
99                         }\r
100                         si.cb = Marshal.SizeOf(si);\r
101                         \r
102                         string lpFileName = (string.IsNullOrEmpty(procInfo.FileName))? null : procInfo.FileName;\r
103                         \r
104                         uint dwCreationFlags = 0x0020; // NORMAL_PRIORITY_CLASS\r
105                         if (procInfo.CreateNoWindow) dwCreationFlags |= 0x08000000; // CREATE_NO_WINDOW\r
106                         string lpCurrentDirectory = (System.IO.Directory.Exists(procInfo.WorkingDirectory))? procInfo.WorkingDirectory : null;\r
107                         \r
108                         bool retValue = CreateProcess(lpFileName, procInfo.Arguments,\r
109                                                       IntPtr.Zero, IntPtr.Zero,\r
110                                                       false, dwCreationFlags,\r
111                                                       IntPtr.Zero, lpCurrentDirectory, ref si, out pi);\r
112                         if (! retValue) {\r
113                                 throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());\r
114                         }\r
115                         CloseHandle(pi.hThread);\r
116                 }\r
117                 \r
118                 /// <summary>\r
119                 /// \8aÖ\98A\95t\82¯\82ç\82ê\82½\83v\83\8d\83Z\83X\82ª\8fI\97¹\82·\82é\82Ü\82Å\81A\8dÅ\91å\8ew\92è\82µ\82½\83~\83\8a\95b\8aÔ\91Ò\8b@\81\r
120                 /// </summary>\r
121                 /// <param name="timeout">\8dÅ\91å\91Ò\8b@\8e\9e\8aÔ(\83~\83\8a\95b\92P\88Ê)</param>\r
122                 /// <returns>\8fI\97¹\83R\81[\83h</returns>\r
123                 public uint WaitForExit(uint timeout)\r
124                 {\r
125                         return WaitForSingleObject(pi.hProcess, timeout);\r
126                 }\r
127                 \r
128                 /// <summary>\r
129                 /// \8aÖ\98A\95t\82¯\82ç\82ê\82½\83v\83\8d\83Z\83X\82ª\8fI\97¹\82·\82é\82Ü\82Å\96³\8aú\8cÀ\82É\91Ò\8b@\81B\r
130                 /// </summary>\r
131                 /// <returns>\8fI\97¹\83R\81[\83h</returns>\r
132                 public uint WaitForExit()\r
133                 {\r
134                         // return WaitForExit(INFINITE)\r
135                         return WaitForExit(0xFFFFFFFF);\r
136                 }\r
137                 \r
138                 /// <summary>\r
139                 /// \8fI\97¹\83R\81[\83h\r
140                 /// </summary>\r
141                 public int ExitCode {\r
142                         get {\r
143                                 int lpExitCode;\r
144                                 if (! GetExitCodeProcess(pi.hProcess, out lpExitCode) ) {\r
145                                         throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());\r
146                                 }\r
147                                 return lpExitCode;\r
148                         }\r
149                 }\r
150                 \r
151                 /// <summary>\r
152                 /// \83v\83\8d\83Z\83X\82Ì\83n\83\93\83h\83\8b\82ð\8aJ\95ú\82·\82é\r
153                 /// </summary>\r
154                 public void Dispose()\r
155                 {\r
156                         CloseHandle(pi.hProcess);\r
157                 }\r
158                 \r
159         }\r
160 }\r