2 using System.Diagnostics;
\r
3 using System.Runtime.InteropServices;
\r
5 namespace NaGet.InteropServices
\r
8 /// Win32 API
\82Ì<code>CreateProcess</code>
\82ð
\92¼
\82É
\92@
\82
\82½
\82ß
\82Ì
\83N
\83\89\83X
\81B
\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
16 public class CreateProcessCaller : IDisposable
\r
21 [StructLayout(LayoutKind.Sequential)]
\r
22 internal struct SECURITY_ATTRIBUTES
\r
25 public IntPtr lpSecurityDescriptor;
\r
26 public int bInheritHandle;
\r
30 [StructLayout(LayoutKind.Sequential)]
\r
31 internal struct PROCESS_INFORMATION
\r
33 public IntPtr hProcess;
\r
34 public IntPtr hThread;
\r
35 public int dwProcessId;
\r
36 public int dwThreadId;
\r
39 [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
\r
50 Int32 dwXCountChars;
\r
51 Int32 dwYCountChars;
\r
52 Int32 dwFillAttribute;
\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
74 [DllImport("kernel32", SetLastError=true, ExactSpelling=true)]
\r
75 static extern UInt32 WaitForSingleObject(IntPtr handle, UInt32 milliseconds);
\r
77 [DllImport("kernel32.dll", SetLastError=true)]
\r
78 [return: MarshalAs(UnmanagedType.Bool)]
\r
79 static extern bool CloseHandle(IntPtr hObject);
\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
88 PROCESS_INFORMATION pi;
\r
91 ///
\83v
\83\8d\83Z
\83X
\82ð
\90¶
\90¬
\82·
\82é
\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
97 if (procInfo.UseShellExecute) {
\r
98 throw new ArgumentException("UseShellExecute must be false");
\r
100 si.cb = Marshal.SizeOf(si);
\r
102 string lpFileName = (string.IsNullOrEmpty(procInfo.FileName))? null : procInfo.FileName;
\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
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
113 throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
\r
115 CloseHandle(pi.hThread);
\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@
\81B
\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
125 return WaitForSingleObject(pi.hProcess, timeout);
\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
131 /// <returns>
\8fI
\97¹
\83R
\81[
\83h</returns>
\r
132 public uint WaitForExit()
\r
134 // return WaitForExit(INFINITE)
\r
135 return WaitForExit(0xFFFFFFFF);
\r
139 ///
\8fI
\97¹
\83R
\81[
\83h
\r
141 public int ExitCode {
\r
144 if (! GetExitCodeProcess(pi.hProcess, out lpExitCode) ) {
\r
145 throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
\r
152 ///
\83v
\83\8d\83Z
\83X
\82Ì
\83n
\83\93\83h
\83\8b\82ð
\8aJ
\95ú
\82·
\82é
\r
154 public void Dispose()
\r
156 CloseHandle(pi.hProcess);
\r