private Boolean StartWithCreateProcess(ProcessStartInfo startInfo, Int32 flags) { if (startInfo.StandardOutputEncoding != null && !startInfo.RedirectStandardOutput) { throw new InvalidOperationException("StandardOutputEncodingNotAllowed"); } if (startInfo.StandardErrorEncoding != null && !startInfo.RedirectStandardError) { throw new InvalidOperationException("StandardErrorEncodingNotAllowed"); } if (this._disposed) { throw new ObjectDisposedException(this.GetType().Name); } StringBuilder stringBuilder = (StringBuilder)Private.s_BuildCommandLine.Invoke(null, new[] { startInfo.FileName, startInfo.Arguments }); STARTUPINFO lpStartupInfo = new STARTUPINFO(); MyProcess.PROCESS_INFORMATION lpProcessInformation = new MyProcess.PROCESS_INFORMATION(); Microsoft.Win32.SafeHandles.SafeProcessHandle processHandle = null; SafeThreadHandle safeThreadHandle = new SafeThreadHandle(); int error = 0; SafeFileHandle parentHandle1 = (SafeFileHandle)null; SafeFileHandle parentHandle2 = (SafeFileHandle)null; SafeFileHandle parentHandle3 = (SafeFileHandle)null; GCHandle gcHandle = new GCHandle(); lock (typeof(Process).GetField("s_CreateProcessLock", BindingFlags.Static | BindingFlags.NonPublic)) { try { if (startInfo.RedirectStandardInput || startInfo.RedirectStandardOutput || startInfo.RedirectStandardError) { if (startInfo.RedirectStandardInput) { this.CreatePipe(out parentHandle1, out lpStartupInfo.hStdInput, true); } else { lpStartupInfo.hStdInput = new SafeFileHandle(SafeNativeMethods.GetStdHandle(-10), false); } if (startInfo.RedirectStandardOutput) { this.CreatePipe(out parentHandle2, out lpStartupInfo.hStdOutput, false); } else { lpStartupInfo.hStdOutput = new SafeFileHandle(SafeNativeMethods.GetStdHandle(-11), false); } if (startInfo.RedirectStandardError) { this.CreatePipe(out parentHandle3, out lpStartupInfo.hStdError, false); } else { lpStartupInfo.hStdError = new SafeFileHandle(SafeNativeMethods.GetStdHandle(-12), false); } lpStartupInfo.dwFlags = 256; } int num1 = flags; if (startInfo.CreateNoWindow) { num1 |= 134217728; } IntPtr num2 = (IntPtr)0; // Not supported //if (startInfo.environmentVariables != null) //{ // bool unicode = false; // if (ProcessManager.IsNt) // { // num1 |= 1024; // unicode = true; // } // gcHandle = GCHandle.Alloc((object)EnvironmentBlock.ToByteArray(startInfo.environmentVariables, unicode), GCHandleType.Pinned); // num2 = gcHandle.AddrOfPinnedObject(); //} string lpCurrentDirectory = startInfo.WorkingDirectory; if (lpCurrentDirectory == String.Empty) { lpCurrentDirectory = Environment.CurrentDirectory; } if (startInfo.UserName.Length != 0) { throw new NotSupportedException("startInfo.UserName.Length != 0"); } else { RuntimeHelpers.PrepareConstrainedRegions(); bool process; try { } finally { process = SafeNativeMethods.CreateProcess((string)null, stringBuilder, IntPtr.Zero, IntPtr.Zero, true, num1, num2, lpCurrentDirectory, lpStartupInfo, out lpProcessInformation); if (!process) { error = Marshal.GetLastWin32Error(); } if (lpProcessInformation.hProcess != (IntPtr)0 && lpProcessInformation.hProcess != new IntPtr(-1)) { processHandle = new Microsoft.Win32.SafeHandles.SafeProcessHandle(lpProcessInformation.hProcess, true); } if (lpProcessInformation.hThread != (IntPtr)0 && lpProcessInformation.hThread != new IntPtr(-1)) { safeThreadHandle.InitialSetHandle(lpProcessInformation.hThread); } } if (!process) { if (error == 193 || error == 216) { throw new Win32Exception(error, "InvalidApplication"); } throw new Win32Exception(error); } } } finally { if (gcHandle.IsAllocated) { gcHandle.Free(); } lpStartupInfo.Dispose(); } } if (startInfo.RedirectStandardInput) { var sw = new StreamWriter((Stream) new FileStream(parentHandle1, FileAccess.Write, 4096, false), Console.InputEncoding, 4096); sw.AutoFlush = true; Private.standardInput.SetValue(this, sw); } if (startInfo.RedirectStandardOutput) { Encoding encoding = startInfo.StandardOutputEncoding != null ? startInfo.StandardOutputEncoding : Console.OutputEncoding; var sr = new StreamReader((Stream) new FileStream(parentHandle2, FileAccess.Read, 4096, false), encoding, true, 4096); Private.standardOutput.SetValue(this, sr); } if (startInfo.RedirectStandardError) { Encoding encoding = startInfo.StandardErrorEncoding != null ? startInfo.StandardErrorEncoding : Console.OutputEncoding; var sr = new StreamReader((Stream) new FileStream(parentHandle3, FileAccess.Read, 4096, false), encoding, true, 4096); Private.standardError.SetValue(this, sr); } bool flag = false; if (processHandle != null && !processHandle.IsInvalid) { Private.SetProcessHandle.Invoke(this, new[] { processHandle }); Private.SetProcessId.Invoke(this, new Object[] { lpProcessInformation.dwProcessId }); ProcessInformation = lpProcessInformation; _mainThread = safeThreadHandle; flag = true; } return(flag); }
public static extern Boolean CreateProcess([MarshalAs(UnmanagedType.LPTStr)] String lpApplicationName, StringBuilder lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, Boolean bInheritHandles, Int32 dwCreationFlags, IntPtr lpEnvironment, [MarshalAs(UnmanagedType.LPTStr)] String lpCurrentDirectory, STARTUPINFO lpStartupInfo, out MyProcess.PROCESS_INFORMATION lpProcessInformation);
public void Execute() { if (!_spec.GameDirectory.IsDataExists) { UnpackGamePackagesSpecPreprocessor unpackSpec = new UnpackGamePackagesSpecPreprocessor { GameDirectory = _spec.GameDirectory, OutputDirectory = _spec.GameDirectory.DataPath, Convert = true, Rename = true }; unpackSpec.Preprocess(); UnpackGamePackagesCoroutine unpack = new UnpackGamePackagesCoroutine(unpackSpec); unpack.Execute(); } MyProcess process = new MyProcess(); process.StartInfo = new ProcessStartInfo(_spec.GameDirectory.ExecutablePath, _spec.GameArguments); process.StartInfo.WorkingDirectory = _spec.GameDirectory.DirectoryPath; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; process.StartInfo.UseShellExecute = false; process.Start(0x4); try { StringBuilder output = new StringBuilder(); StringBuilder error = new StringBuilder(); process.OutputDataReceived += (s, z) => output.AppendLine(z.Data); process.ErrorDataReceived += (s, z) => error.AppendLine(z.Data); process.BeginOutputReadLine(); process.BeginErrorReadLine(); var dllPath = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "Septerra.Injection.dll"); if (!File.Exists(dllPath)) { throw new FileNotFoundException(dllPath); } var unicodeDllPath = Encoding.Unicode.GetBytes(dllPath); using (SafeProcessHandle processHandle = new SafeProcessHandle(process.Id, ProcessAccessFlags.All, false)) using (SafeVirtualMemoryHandle memoryHandle = processHandle.Allocate(unicodeDllPath.Length, AllocationType.Commit, MemoryProtection.ReadWrite)) { memoryHandle.Write(unicodeDllPath); IntPtr loadLibraryAddress = GetLoadLibraryAddress(); using (SafeRemoteThread thread = processHandle.CreateThread(loadLibraryAddress, memoryHandle)) { thread.Join(); Thread.Sleep(1000); // TODO:: Wait for DLL_THREAD_DETACH } var dxWndDirectory = Path.GetFullPath("dxwnd"); var dxWndPath = dxWndDirectory + "\\dxwnd.exe"; if (File.Exists(dxWndPath)) { unsafe { Int32 processInformationSize = sizeof(MyProcess.PROCESS_INFORMATION); using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("Global\\DxWndSuspendedProcessInfo", processInformationSize, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None)) using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor(0, processInformationSize, MemoryMappedFileAccess.Write)) { MyProcess.PROCESS_INFORMATION processInformation = process.ProcessInformation; accessor.Write(0, ref processInformation); Process dxWnd = new Process { StartInfo = new ProcessStartInfo(dxWndPath, "/r:0") { WorkingDirectory = dxWndDirectory } }; dxWnd.Start(); process.WaitForExit(); dxWnd.Kill(); } } } else { process.ResumeMainThread(); HideConsole(); process.WaitForExit(); } } } catch { process.Kill(); throw; } }