private static ProcessInfo RunProcess(ref StartInfoExtended sInfoEx, string commandLine) { int securityAttributeSize = Marshal.SizeOf <SecurityAttributes>(); var pSec = new SecurityAttributes { nLength = securityAttributeSize }; var tSec = new SecurityAttributes { nLength = securityAttributeSize }; var success = ProcessApi.CreateProcess( lpApplicationName: null, lpCommandLine: commandLine, lpProcessAttributes: ref pSec, lpThreadAttributes: ref tSec, bInheritHandles: false, dwCreationFlags: Constants.EXTENDED_STARTUPINFO_PRESENT, lpEnvironment: IntPtr.Zero, lpCurrentDirectory: null, lpStartupInfo: ref sInfoEx, lpProcessInformation: out ProcessInfo pInfo ); if (!success) { throw InteropException.CreateWithInnerHResultException("Could not create process."); } return(pInfo); }
private static StartInfoExtended ConfigureProcessThread(IntPtr hPC, IntPtr attributes) { // this method implements the behavior described in https://docs.microsoft.com/en-us/windows/console/creating-a-pseudoconsole-session#preparing-for-creation-of-the-child-process var lpSize = IntPtr.Zero; var success = ProcessApi.InitializeProcThreadAttributeList( lpAttributeList: IntPtr.Zero, dwAttributeCount: 1, dwFlags: 0, lpSize: ref lpSize ); if (success || lpSize == IntPtr.Zero) // we're not expecting `success` here, we just want to get the calculated lpSize { throw InteropException.CreateWithInnerHResultException("Could not calculate the number of bytes for the attribute list."); } var startupInfo = new StartInfoExtended(); startupInfo.StartupInfo.cb = Marshal.SizeOf <StartInfoExtended>(); startupInfo.lpAttributeList = Marshal.AllocHGlobal(lpSize); success = ProcessApi.InitializeProcThreadAttributeList( lpAttributeList: startupInfo.lpAttributeList, dwAttributeCount: 1, dwFlags: 0, lpSize: ref lpSize ); if (!success) { throw InteropException.CreateWithInnerHResultException("Could not set up attribute list."); } success = ProcessApi.UpdateProcThreadAttribute( lpAttributeList: startupInfo.lpAttributeList, dwFlags: 0, attribute: attributes, lpValue: hPC, cbSize: (IntPtr)IntPtr.Size, lpPreviousValue: IntPtr.Zero, lpReturnSize: IntPtr.Zero ); if (!success) { throw InteropException.CreateWithInnerHResultException("Could not set pseudoconsole thread attribute."); } return(startupInfo); }
private static void SetConsoleModeToVirtualTerminal() { SafeFileHandle stdIn = ConsoleApi.GetStdHandle(StdHandle.InputHandle); if (!ConsoleApi.GetConsoleMode(stdIn, out uint outConsoleMode)) { throw InteropException.CreateWithInnerHResultException("Could not get console mode."); } outConsoleMode |= Constants.ENABLE_VIRTUAL_TERMINAL_PROCESSING | Constants.DISABLE_NEWLINE_AUTO_RETURN; if (!ConsoleApi.SetConsoleMode(stdIn, outConsoleMode)) { throw InteropException.CreateWithInnerHResultException("Could not enable virtual terminal processing."); } }
public static PseudoConsole Create(SafeFileHandle inputReadSide, SafeFileHandle outputWriteSide, short width, short height) { int createResult = ConPtyApi.CreatePseudoConsole( new Coordinates { X = width, Y = height }, inputReadSide, outputWriteSide, 0, out IntPtr hPC); if (createResult != 0) { throw InteropException.CreateWithInnerHResultException($"Could not create pseudo console. Error Code: {createResult}"); } return(new PseudoConsole(hPC)); }
private void MakeHandleNoninheritable(ref SafeFileHandle handler, IntPtr processHandle) { // Create noninheritable read handle and close the inheritable read handle. IntPtr handleClone; if (!ConsoleApi.DuplicateHandle( processHandle, handler.DangerousGetHandle(), processHandle, out handleClone, 0, false, Constants.DUPLICATE_SAME_ACCESS)) { throw InteropException.CreateWithInnerHResultException("Couldn't duplicate the handle."); } SafeFileHandle toRelease = handler; handler = new SafeFileHandle(handleClone, true); toRelease.Dispose(); }
public static bool Receive(MethodProxy resultProxy, bool socketSuccess) { try { var taskToReturn = MethodDispatcher.GetTaskDispatcher(resultProxy.TaskIdentity); if (taskToReturn == null) { return(false); } if (socketSuccess && resultProxy.TaskSuccess) { MethodDispatcher.SetTaskResult(resultProxy.TaskIdentity, resultProxy); } else { InteropException exception = null; //If success value (from javascript) is false, like unable to connect to websocket //or if the native task failed with an exception, cancel the current task, that will throw if (!socketSuccess) { exception = new InteropException($"BlazorMobile was unable to connect to native through websocket server to execute task {resultProxy.TaskIdentity}"); } else if (resultProxy.ExceptionDescriptor != null) { //We have some message to send in this case if (!resultProxy.ExceptionDescriptor.HasInnerException) { exception = new InteropException(resultProxy.ExceptionDescriptor.Message); } else { exception = new InteropException( resultProxy.ExceptionDescriptor.Message, resultProxy.ExceptionDescriptor.InnerException); } } else { //Sending uncustomized message exception = new InteropException($"Task {resultProxy.TaskIdentity} has thrown an exception on native side. See log for more info."); } MethodDispatcher.SetTaskAsFaulted(resultProxy.TaskIdentity, exception); } taskToReturn.RunSynchronously(); //Clear task from task list. Should then call the task to execute. It will throw if it has been cancelled MethodDispatcher.ClearTask(resultProxy.TaskIdentity); } catch (Exception ex) { ConsoleHelper.WriteException(ex); return(false); } return(true); }