/// <summary> /// Command execution /// </summary> public override CommandResult InternalExecute(ICommandTarget target, params IAdaptable[] args) { PipeTerminalParameter paramInit = null; PipeTerminalSettings settingsInit = null; IExtensionPoint ext = PipePlugin.Instance.PoderosaWorld.PluginManager.FindExtensionPoint("org.poderosa.terminalsessions.loginDialogUISupport"); if (ext != null && ext.ExtensionInterface == typeof(ILoginDialogUISupport)) { foreach (ILoginDialogUISupport sup in ext.GetExtensions()) { ITerminalParameter terminalParam; ITerminalSettings terminalSettings; sup.FillTopDestination(typeof(PipeTerminalParameter), out terminalParam, out terminalSettings); PipeTerminalParameter paramTemp = terminalParam as PipeTerminalParameter; PipeTerminalSettings settingsTemp = terminalSettings as PipeTerminalSettings; if (paramInit == null) { paramInit = paramTemp; } if (settingsInit == null) { settingsInit = settingsTemp; } } } if (paramInit == null) { paramInit = new PipeTerminalParameter(); } if (settingsInit == null) { settingsInit = new PipeTerminalSettings(); } IPoderosaMainWindow window = (IPoderosaMainWindow)target.GetAdapter(typeof(IPoderosaMainWindow)); CommandResult commandResult = CommandResult.Failed; using (OpenPipeDialog dialog = new OpenPipeDialog()) { dialog.OpenPipe = delegate(PipeTerminalParameter param, PipeTerminalSettings settings) { PipeTerminalConnection connection = PipeCreator.CreateNewPipeTerminalConnection(param, settings); commandResult = PipePlugin.Instance.CommandManager.Execute( PipePlugin.Instance.TerminalSessionsService.TerminalSessionStartCommand, window, connection, settings); return(commandResult == CommandResult.Succeeded); }; dialog.ApplyParams(paramInit, settingsInit); DialogResult dialogResult = dialog.ShowDialog(window != null ? window.AsForm() : null); if (dialogResult == DialogResult.Cancel) { commandResult = CommandResult.Cancelled; } } return(commandResult); }
/// <summary> /// Create a new PipeTerminalConnection /// </summary> /// <param name="param">Terminal parameter</param> /// <param name="settings">Terminal settings</param> /// <returns>created object</returns> /// <exception cref="PipeCreatorException">Creation was failed.</exception> public static PipeTerminalConnection CreateNewPipeTerminalConnection(PipeTerminalParameter param, PipeTerminalSettings settings) { Debug.Assert(param != null); Debug.Assert(settings != null); if (param.ExeFilePath != null) { try { OverrideSettings(param, settings); return(OpenExeFile(param)); } catch (Exception e) { string message = PipePlugin.Instance.Strings.GetString("PipeCreator.LaunchingApplicationFailed"); throw new PipeCreatorException(message, e); } } else if (param.InputPipePath != null) { try { return(OpenNamedPipe(param)); } catch (Exception e) { string message = PipePlugin.Instance.Strings.GetString("PipeCreator.OpeningPipeFailed"); throw new PipeCreatorException(message, e); } } else { throw new ArgumentException("Parameter error: exe file or pipe path must be present."); } }
/// <summary> /// Create a new PipeTerminalConnection /// </summary> /// <param name="param">Terminal parameter</param> /// <param name="settings">Terminal settings</param> /// <returns>created object</returns> /// <exception cref="PipeCreatorException">Creation was failed.</exception> public static PipeTerminalConnection CreateNewPipeTerminalConnection(PipeTerminalParameter param, PipeTerminalSettings settings) { Debug.Assert(param != null); Debug.Assert(settings != null); if (param.ExeFilePath != null) { try { OverrideSettings(param, settings); return OpenExeFile(param); } catch (Exception e) { string message = PipePlugin.Instance.Strings.GetString("PipeCreator.LaunchingApplicationFailed"); throw new PipeCreatorException(message, e); } } else if (param.InputPipePath != null) { try { return OpenNamedPipe(param); } catch (Exception e) { string message = PipePlugin.Instance.Strings.GetString("PipeCreator.OpeningPipeFailed"); throw new PipeCreatorException(message, e); } } else { throw new ArgumentException("Parameter error: exe file or pipe path must be present."); } }
public ITerminalConnection EstablishConnection(IPoderosaMainWindow window, ITerminalParameter param, ITerminalSettings settings) { PipeTerminalParameter tp = param as PipeTerminalParameter; PipeTerminalSettings ts = settings as PipeTerminalSettings; Debug.Assert(tp != null && ts != null); return(PipeCreator.CreateNewPipeTerminalConnection(tp, ts)); }
/// <summary> /// Constructor /// </summary> /// <param name="terminalParameter">Terminal parameter</param> /// <param name="socket">PipeSocket object</param> /// <param name="pipedProcess">Process data (or null)</param> public PipeTerminalConnection(PipeTerminalParameter terminalParameter, PipeSocket socket, PipedProcess pipedProcess) { _terminalOutput = new PipeTerminalOutput(); _terminalParameter = terminalParameter; _socket = socket; _pipedProcess = pipedProcess; if (_pipedProcess != null) { _pipedProcess.Exited += delegate(object sender, EventArgs e) { _socket.ProcessExited(); }; } }
/// <summary> /// Apply parameters to controls /// </summary> /// <param name="param">Terminal parameters</param> /// <param name="settings">Terminal settings</param> public void ApplyParams(PipeTerminalParameter param, PipeTerminalSettings settings) { Debug.Assert(param != null); Debug.Assert(settings != null); Control boxToFocus = null; bool isProcessMode = true; // process mode is default bool isBidirectinal = true; // bidirectinal is default boxToFocus = _textBoxExePath; if (param.ExeFilePath != null) { _textBoxExePath.Text = param.ExeFilePath; if (param.CommandLineOptions != null) _textBoxCommandLineOptions.Text = param.CommandLineOptions; _environmentVariables = param.EnvironmentVariables; } else if (param.InputPipePath != null) { isProcessMode = false; _textBoxInputPath.Text = param.InputPipePath; if (param.OutputPipePath != null) { isBidirectinal = false; _textBoxOutputPath.Text = param.OutputPipePath; } boxToFocus = _textBoxInputPath; } SetMode(isProcessMode); SetBidirectional(isBidirectinal); _comboBoxLogType.SelectedItem = LogType.None; // select EnumListItem<T> by T _textBoxLogFile.Enabled = false; _buttonBrowseLogFile.Enabled = false; _comboBoxEncoding.SelectedItem = settings.Encoding; // select EnumListItem<T> by T _comboBoxNewLine.SelectedItem = settings.TransmitNL; // select EnumListItem<T> by T _comboBoxLocalEcho.SelectedIndex = settings.LocalEcho ? 1 : 0; _comboBoxTerminalType.SelectedItem = settings.TerminalType; // select EnumListItem<T> by T IAutoExecMacroParameter autoExecParams = param.GetAdapter(typeof(IAutoExecMacroParameter)) as IAutoExecMacroParameter; if (autoExecParams != null && PipePlugin.Instance.MacroEngine != null) { _textBoxAutoExecMacroPath.Text = (autoExecParams.AutoExecMacroPath != null) ? autoExecParams.AutoExecMacroPath : String.Empty; } else { _labelAutoExecMacroPath.Enabled = false; _textBoxAutoExecMacroPath.Enabled = false; _buttonSelectAutoExecMacro.Enabled = false; } if (boxToFocus != null) boxToFocus.Focus(); }
public StructuredText Serialize(object obj) { PipeTerminalParameter tp = obj as PipeTerminalParameter; Debug.Assert(tp != null); StructuredText node = new StructuredText(ConcreteType.FullName); if (tp.ExeFilePath != null) { node.Set("exeFilePath", tp.ExeFilePath); } if (!String.IsNullOrEmpty(tp.CommandLineOptions)) { node.Set("commandLineOptions", tp.CommandLineOptions); } if (tp.EnvironmentVariables != null && tp.EnvironmentVariables.Length > 0) { foreach (PipeTerminalParameter.EnvironmentVariable e in tp.EnvironmentVariables) { StructuredText envNode = new StructuredText("environmentVariable"); envNode.Set("name", e.Name); envNode.Set("value", e.Value); node.AddChild(envNode); } } if (tp.InputPipePath != null) { node.Set("inputPipePath", tp.InputPipePath); } if (tp.OutputPipePath != null) { node.Set("outputPipePath", tp.OutputPipePath); } if (tp.TerminalType != null) { node.Set("terminal-type", tp.TerminalType); } if (tp.AutoExecMacroPath != null) { node.Set("autoexec-macro", tp.AutoExecMacroPath); } return(node); }
public bool UIEquals(ITerminalParameter t) { PipeTerminalParameter p = t as PipeTerminalParameter; return(p != null && ((_exeFilePath == null && p._exeFilePath == null) || (_exeFilePath != null && p._exeFilePath != null && String.Compare(_exeFilePath, p._exeFilePath, true) == 0)) && ((_commandLineOptions == null && p._commandLineOptions == null) || (_commandLineOptions != null && p._commandLineOptions != null && String.Compare(_commandLineOptions, p._commandLineOptions, false) == 0)) && ((_inputPipePath == null && p._inputPipePath == null) || (_inputPipePath != null && p._inputPipePath != null && String.Compare(_inputPipePath, p._inputPipePath, true) == 0)) && ((_outputPipePath == null && p._outputPipePath == null) || (_outputPipePath != null && p._outputPipePath != null && String.Compare(_outputPipePath, p._outputPipePath, true) == 0))); }
/// <summary> /// Command execution /// </summary> public override CommandResult InternalExecute(ICommandTarget target, params IAdaptable[] args) { PipeTerminalParameter paramInit = null; PipeTerminalSettings settingsInit = null; IExtensionPoint ext = PipePlugin.Instance.PoderosaWorld.PluginManager.FindExtensionPoint("org.poderosa.terminalsessions.loginDialogUISupport"); if (ext != null && ext.ExtensionInterface == typeof(ILoginDialogUISupport)) { foreach (ILoginDialogUISupport sup in ext.GetExtensions()) { ITerminalParameter terminalParam; ITerminalSettings terminalSettings; sup.FillTopDestination(typeof(PipeTerminalParameter), out terminalParam, out terminalSettings); PipeTerminalParameter paramTemp = terminalParam as PipeTerminalParameter; PipeTerminalSettings settingsTemp = terminalSettings as PipeTerminalSettings; if (paramInit == null) paramInit = paramTemp; if (settingsInit == null) settingsInit = settingsTemp; } } if (paramInit == null) paramInit = new PipeTerminalParameter(); if (settingsInit == null) settingsInit = new PipeTerminalSettings(); IPoderosaMainWindow window = (IPoderosaMainWindow)target.GetAdapter(typeof(IPoderosaMainWindow)); CommandResult commandResult = CommandResult.Failed; using (OpenPipeDialog dialog = new OpenPipeDialog()) { dialog.OpenPipe = delegate(PipeTerminalParameter param, PipeTerminalSettings settings) { PipeTerminalConnection connection = PipeCreator.CreateNewPipeTerminalConnection(param, settings); commandResult = PipePlugin.Instance.CommandManager.Execute( PipePlugin.Instance.TerminalSessionsService.TerminalSessionStartCommand, window, connection, settings); return (commandResult == CommandResult.Succeeded); }; dialog.ApplyParams(paramInit, settingsInit); DialogResult dialogResult = dialog.ShowDialog(window != null ? window.AsForm() : null); if (dialogResult == DialogResult.Cancel) commandResult = CommandResult.Cancelled; } return commandResult; }
/// <summary> /// Set parameters /// </summary> /// <param name="env">environment variables</param> public void ApplyParams(PipeTerminalParameter.EnvironmentVariable[] env) { _listViewVariables.Items.Clear(); if (env != null && env.Length > 0) { List<PipeTerminalParameter.EnvironmentVariable> varList = new List<PipeTerminalParameter.EnvironmentVariable>(); varList.AddRange(env); SortItemList(varList); for (int i = 0; i < varList.Count; i++) { ListViewItem item = new ListViewItem( new string[] { varList[i].Name, varList[i].Value }); _listViewVariables.Items.Add(item); } } }
public object Deserialize(StructuredText node) { PipeTerminalParameter tp = new PipeTerminalParameter(); tp.ExeFilePath = node.Get("exeFilePath", null); tp.CommandLineOptions = node.Get("commandLineOptions", null); List<PipeTerminalParameter.EnvironmentVariable> envList = new List<PipeTerminalParameter.EnvironmentVariable>(); foreach (StructuredText s in node.FindMultipleNote("environmentVariable")) { string name = s.Get("name", null); string value = s.Get("value", null); if (name != null && value != null) { envList.Add(new PipeTerminalParameter.EnvironmentVariable(name, value)); } } tp.EnvironmentVariables = (envList.Count > 0) ? envList.ToArray() : null; tp.InputPipePath = node.Get("inputPipePath", null); tp.OutputPipePath = node.Get("outputPipePath", null); tp.SetTerminalName(node.Get("terminal-type", "vt100")); tp.AutoExecMacroPath = node.Get("autoexec-macro", null); return tp; }
/// <summary> /// Modify icon to which is obtained from the executable file /// </summary> /// <param name="param"></param> /// <param name="settings"></param> private static void OverrideSettings(PipeTerminalParameter param, PipeTerminalSettings settings) { if (param.ExeFilePath != null) { Image icon = GetExeFileIcon(param.ExeFilePath); if (icon != null) { Image oldIcon = settings.Icon; settings.BeginUpdate(); settings.Icon = icon; settings.EndUpdate(); // FIXME: // oldIcon may being used to repainting, so we don't dispose it here. // I don't know where the icon is disposed... // //if (oldIcon != null) // oldIcon.Dispose(); } } }
public object Deserialize(StructuredText node) { PipeTerminalParameter tp = new PipeTerminalParameter(); tp.ExeFilePath = node.Get("exeFilePath", null); tp.CommandLineOptions = node.Get("commandLineOptions", null); List <PipeTerminalParameter.EnvironmentVariable> envList = new List <PipeTerminalParameter.EnvironmentVariable>(); foreach (StructuredText s in node.FindMultipleNote("environmentVariable")) { string name = s.Get("name", null); string value = s.Get("value", null); if (name != null && value != null) { envList.Add(new PipeTerminalParameter.EnvironmentVariable(name, value)); } } tp.EnvironmentVariables = (envList.Count > 0) ? envList.ToArray() : null; tp.InputPipePath = node.Get("inputPipePath", null); tp.OutputPipePath = node.Get("outputPipePath", null); tp.SetTerminalName(node.Get("terminal-type", "vt100")); tp.AutoExecMacroPath = node.Get("autoexec-macro", null); return(tp); }
/// <summary> /// Open file path and create a new PipeTerminalConnection /// </summary> /// <param name="param">Terminal parameter</param> /// <returns>created object</returns> /// <exception cref="Win32Exception">Error in Win32 API</exception> private static PipeTerminalConnection OpenNamedPipe(PipeTerminalParameter param) { SafeFileHandle inputHandle = null; SafeFileHandle outputHandle = null; FileStream readStream = null; FileStream writeStream = null; try { bool hasOutputPipePath = param.OutputPipePath != null; inputHandle = CreateFile( param.InputPipePath, GENERIC_READ | (hasOutputPipePath ? 0 : GENERIC_WRITE), 0, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, IntPtr.Zero); if (inputHandle.IsInvalid) throw new Win32Exception("CreateFile", Marshal.GetLastWin32Error(), "path=" + param.InputPipePath + " mode=GENERIC_READ" + (hasOutputPipePath ? "" : "|GENERIC_WRITE")); readStream = new FileStream(inputHandle, hasOutputPipePath ? FileAccess.Read : FileAccess.ReadWrite, 4096, true /*Async*/); if (hasOutputPipePath) { outputHandle = CreateFile( param.OutputPipePath, GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, IntPtr.Zero); if (outputHandle.IsInvalid) throw new Win32Exception("CreateFile", Marshal.GetLastWin32Error(), "path=" + param.OutputPipePath + " mode=GENERIC_WRITE"); writeStream = new FileStream(outputHandle, FileAccess.Write, 4096, true /*Async*/); } else { writeStream = readStream; } PipeSocket sock = new PipeSocket(readStream, writeStream); PipeTerminalConnection conn = new PipeTerminalConnection(param, sock, null); return conn; } catch (Exception) { if (readStream != null) readStream.Dispose(); if (writeStream != null) writeStream.Dispose(); if (inputHandle != null) inputHandle.Dispose(); if (outputHandle != null) outputHandle.Dispose(); throw; } }
private bool ValidateParams(out PipeTerminalParameter param, out PipeTerminalSettings settings) { PipeTerminalParameter paramTmp = new PipeTerminalParameter(); PipeTerminalSettings settingsTmp = new PipeTerminalSettings(); StringResource res = PipePlugin.Instance.Strings; try { string caption; if (_radioButtonProcess.Checked) { string exePath = _textBoxExePath.Text; if (exePath.Length == 0) { throw new Exception(res.GetString("Form.OpenPipeDialog.Error.NoExePath")); } paramTmp.ExeFilePath = exePath; paramTmp.CommandLineOptions = _textBoxCommandLineOptions.Text; paramTmp.EnvironmentVariables = _environmentVariables; caption = Path.GetFileName(exePath); } else if (_radioButtonPipe.Checked) { string path = _textBoxInputPath.Text; if (path.Length == 0) { throw new Exception(res.GetString("Form.OpenPipeDialog.Error.NoInputPath")); } paramTmp.InputPipePath = path; caption = Path.GetFileName(path); if (!_checkBoxBidirectinal.Checked) { path = _textBoxOutputPath.Text; if (path.Length == 0) { throw new Exception(res.GetString("Form.OpenPipeDialog.Error.NoOutputPath")); } paramTmp.OutputPipePath = path; caption += "/" + Path.GetFileName(path); } } else { throw new Exception(res.GetString("Form.OpenPipeDialog.Error.NoOpenMode")); } TerminalType terminalType = ((EnumListItem <TerminalType>)_comboBoxTerminalType.SelectedItem).Value; paramTmp.SetTerminalName(terminalType.ToString().ToLowerInvariant()); LogType logType = ((EnumListItem <LogType>)_comboBoxLogType.SelectedItem).Value; ISimpleLogSettings logSettings = null; if (logType != LogType.None) { string logFile = _textBoxLogFile.Text; LogFileCheckResult r = LogUtil.CheckLogFileName(logFile, this); if (r == LogFileCheckResult.Cancel || r == LogFileCheckResult.Error) { throw new Exception(""); } logSettings = PipePlugin.Instance.TerminalEmulatorService.CreateDefaultSimpleLogSettings(); logSettings.LogPath = logFile; logSettings.LogType = logType; logSettings.LogAppend = (r == LogFileCheckResult.Append); } string autoExecMacroPath = null; if (_textBoxAutoExecMacroPath.Text.Length != 0) { autoExecMacroPath = _textBoxAutoExecMacroPath.Text; } IAutoExecMacroParameter autoExecParams = paramTmp.GetAdapter(typeof(IAutoExecMacroParameter)) as IAutoExecMacroParameter; if (autoExecParams != null) { autoExecParams.AutoExecMacroPath = autoExecMacroPath; } settingsTmp.BeginUpdate(); settingsTmp.Caption = caption; settingsTmp.Icon = Poderosa.Pipe.Properties.Resources.Icon16x16; settingsTmp.Encoding = ((EnumListItem <EncodingType>)_comboBoxEncoding.SelectedItem).Value; settingsTmp.LocalEcho = _comboBoxLocalEcho.SelectedIndex == 1; settingsTmp.TransmitNL = ((EnumListItem <NewLine>)_comboBoxNewLine.SelectedItem).Value; settingsTmp.TerminalType = terminalType; if (logSettings != null) { settingsTmp.LogSettings.Reset(logSettings); } settingsTmp.EndUpdate(); param = paramTmp; settings = settingsTmp; return(true); } catch (Exception e) { if (e.Message.Length > 0) { GUtil.Warning(this, e.Message); } param = null; settings = null; return(false); } }
/// <summary> /// Apply parameters to controls /// </summary> /// <param name="param">Terminal parameters</param> /// <param name="settings">Terminal settings</param> public void ApplyParams(PipeTerminalParameter param, PipeTerminalSettings settings) { Debug.Assert(param != null); Debug.Assert(settings != null); Control boxToFocus = null; bool isProcessMode = true; // process mode is default bool isBidirectinal = true; // bidirectinal is default boxToFocus = _textBoxExePath; if (param.ExeFilePath != null) { _textBoxExePath.Text = param.ExeFilePath; if (param.CommandLineOptions != null) { _textBoxCommandLineOptions.Text = param.CommandLineOptions; } _environmentVariables = param.EnvironmentVariables; } else if (param.InputPipePath != null) { isProcessMode = false; _textBoxInputPath.Text = param.InputPipePath; if (param.OutputPipePath != null) { isBidirectinal = false; _textBoxOutputPath.Text = param.OutputPipePath; } boxToFocus = _textBoxInputPath; } SetMode(isProcessMode); SetBidirectional(isBidirectinal); _comboBoxLogType.SelectedItem = LogType.None; // select EnumListItem<T> by T _textBoxLogFile.Enabled = false; _buttonBrowseLogFile.Enabled = false; _comboBoxEncoding.SelectedItem = settings.Encoding; // select EnumListItem<T> by T _comboBoxNewLine.SelectedItem = settings.TransmitNL; // select EnumListItem<T> by T _comboBoxLocalEcho.SelectedIndex = settings.LocalEcho ? 1 : 0; _comboBoxTerminalType.SelectedItem = settings.TerminalType; // select EnumListItem<T> by T IAutoExecMacroParameter autoExecParams = param.GetAdapter(typeof(IAutoExecMacroParameter)) as IAutoExecMacroParameter; if (autoExecParams != null && PipePlugin.Instance.MacroEngine != null) { _textBoxAutoExecMacroPath.Text = (autoExecParams.AutoExecMacroPath != null) ? autoExecParams.AutoExecMacroPath : String.Empty; } else { _labelAutoExecMacroPath.Enabled = false; _textBoxAutoExecMacroPath.Enabled = false; _buttonSelectAutoExecMacro.Enabled = false; } if (boxToFocus != null) { boxToFocus.Focus(); } }
/// <summary> /// Open file path and create a new PipeTerminalConnection /// </summary> /// <param name="param">Terminal parameter</param> /// <returns>created object</returns> /// <exception cref="Win32Exception">Error in Win32 API</exception> private static PipeTerminalConnection OpenNamedPipe(PipeTerminalParameter param) { SafeFileHandle inputHandle = null; SafeFileHandle outputHandle = null; FileStream readStream = null; FileStream writeStream = null; try { bool hasOutputPipePath = param.OutputPipePath != null; inputHandle = CreateFile( param.InputPipePath, GENERIC_READ | (hasOutputPipePath ? 0 : GENERIC_WRITE), 0, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, IntPtr.Zero); if (inputHandle.IsInvalid) { throw new Win32Exception("CreateFile", Marshal.GetLastWin32Error(), "path=" + param.InputPipePath + " mode=GENERIC_READ" + (hasOutputPipePath ? "" : "|GENERIC_WRITE")); } readStream = new FileStream(inputHandle, hasOutputPipePath ? FileAccess.Read : FileAccess.ReadWrite, 4096, true /*Async*/); if (hasOutputPipePath) { outputHandle = CreateFile( param.OutputPipePath, GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, IntPtr.Zero); if (outputHandle.IsInvalid) { throw new Win32Exception("CreateFile", Marshal.GetLastWin32Error(), "path=" + param.OutputPipePath + " mode=GENERIC_WRITE"); } writeStream = new FileStream(outputHandle, FileAccess.Write, 4096, true /*Async*/); } else { writeStream = readStream; } PipeSocket sock = new PipeSocket(readStream, writeStream); PipeTerminalConnection conn = new PipeTerminalConnection(param, sock, null); return(conn); } catch (Exception) { if (readStream != null) { readStream.Dispose(); } if (writeStream != null) { writeStream.Dispose(); } if (inputHandle != null) { inputHandle.Dispose(); } if (outputHandle != null) { outputHandle.Dispose(); } throw; } }
/// <summary> /// Start exe file and create a new PipeTerminalConnection /// </summary> /// <param name="param">Terminal parameter</param> /// <returns>created object</returns> /// <exception cref="Win32Exception">Error in Win32 API</exception> private static PipeTerminalConnection OpenExeFile(PipeTerminalParameter param) { // System.Diagnostics.Process has functionality that creates STDIN/STDOUT/STDERR pipe. // But we need two pipes. One connects to STDIN and another one connects to STDOUT and STDERR. // So we use Win32 API to invoke a new process. SafeFileHandle parentReadHandle = null; SafeFileHandle parentWriteHandle = null; SafeFileHandle childReadHandle = null; SafeFileHandle childWriteHandle = null; SafeFileHandle childStdInHandle = null; SafeFileHandle childStdOutHandle = null; SafeFileHandle childStdErrHandle = null; FileStream parentReadStream = null; FileStream parentWriteStream = null; try { // Create pipes CreateAsyncPipe(out parentReadHandle, true, out childWriteHandle, false); CreateAsyncPipe(out childReadHandle, false, out parentWriteHandle, true); // Duplicate handles as inheritable handles. childStdOutHandle = DuplicatePipeHandle(childWriteHandle, true, "ChildWrite"); childStdInHandle = DuplicatePipeHandle(childReadHandle, true, "ChildRead"); childStdErrHandle = DuplicatePipeHandle(childWriteHandle, true, "ChildWrite"); // Close non-inheritable handles childWriteHandle.Dispose(); childWriteHandle = null; childReadHandle.Dispose(); childReadHandle = null; // Create parent side streams parentReadStream = new FileStream(parentReadHandle, FileAccess.Read, 4096, true /*Async*/); parentWriteStream = new FileStream(parentWriteHandle, FileAccess.Write, 4096, true /*Async*/); // Prepare command line string commandLine = GetCommandLine(param.ExeFilePath, param.CommandLineOptions); // Determine character encoding of the environment variables bool unicodeEnvironment = (Environment.OSVersion.Platform == PlatformID.Win32NT) ? true : false; // Prepare flags // Note: // We use CREATE_NEW_CONSOLE for separating console. // It disables CREATE_NO_WINDOW, so we use setting below // to hide the console window. // STARTUPINFO.dwFlags |= STARTF_USESHOWWINDOW // STARTUPINFO.wShowWindow = SW_HIDE int creationFlags = CREATE_NEW_CONSOLE /*| CREATE_NO_WINDOW*/; if (unicodeEnvironment) { creationFlags |= CREATE_UNICODE_ENVIRONMENT; } // Prepare environment variables Dictionary <String, String> envDict = new Dictionary <String, String>(); foreach (DictionaryEntry entry in Environment.GetEnvironmentVariables()) { string key = entry.Key as string; string value = entry.Value as string; if (key != null && value != null) { envDict.Add(key.ToLowerInvariant(), key + "=" + value); } } if (param.EnvironmentVariables != null) { foreach (PipeTerminalParameter.EnvironmentVariable ev in param.EnvironmentVariables) { string expandedValue = Environment.ExpandEnvironmentVariables(ev.Value); string key = ev.Name.ToLowerInvariant(); envDict.Remove(key); envDict.Add(key, ev.Name + "=" + expandedValue); } } byte[] environmentByteArray = GetEnvironmentBytes(envDict, unicodeEnvironment); // Prepare current directory string currentDirectory = Path.GetDirectoryName(param.ExeFilePath); // Prepare STARTUPINFO STARTUPINFO startupInfo = new STARTUPINFO(); startupInfo.dwFlags |= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; startupInfo.hStdInput = childStdInHandle; startupInfo.hStdOutput = childStdOutHandle; startupInfo.hStdError = childStdErrHandle; startupInfo.wShowWindow = SW_HIDE; // Prepare PROCESS_INFORMATION PROCESS_INFORMATION processInfo = new PROCESS_INFORMATION(); // Start process GCHandle environmentGCHandle = GCHandle.Alloc(environmentByteArray, GCHandleType.Pinned); bool apiret = CreateProcess( null, commandLine, IntPtr.Zero, IntPtr.Zero, true, creationFlags, environmentGCHandle.AddrOfPinnedObject(), currentDirectory, startupInfo, ref processInfo ); environmentGCHandle.Free(); if (!apiret) { throw new Win32Exception("CreateProcess", Marshal.GetLastWin32Error(), "commandLine=" + commandLine); } Process process = Process.GetProcessById(processInfo.dwProcessId); PipedProcess pipedProcess = new PipedProcess(process, childStdInHandle, childStdOutHandle, childStdErrHandle); PipeSocket socket = new PipeSocket(parentReadStream, parentWriteStream); PipeTerminalConnection connection = new PipeTerminalConnection(param, socket, pipedProcess); return(connection); } catch (Exception) { if (parentReadStream != null) { parentReadStream.Dispose(); } if (parentWriteStream != null) { parentWriteStream.Dispose(); } if (parentReadHandle != null) { parentReadHandle.Dispose(); } if (parentWriteHandle != null) { parentWriteHandle.Dispose(); } if (childReadHandle != null) { childReadHandle.Dispose(); } if (childWriteHandle != null) { childWriteHandle.Dispose(); } if (childStdInHandle != null) { childStdInHandle.Dispose(); } if (childStdOutHandle != null) { childStdOutHandle.Dispose(); } if (childStdErrHandle != null) { childStdErrHandle.Dispose(); } throw; } }
/// <summary> /// Start exe file and create a new PipeTerminalConnection /// </summary> /// <param name="param">Terminal parameter</param> /// <returns>created object</returns> /// <exception cref="Win32Exception">Error in Win32 API</exception> private static PipeTerminalConnection OpenExeFile(PipeTerminalParameter param) { // System.Diagnostics.Process has functionality that creates STDIN/STDOUT/STDERR pipe. // But we need two pipes. One connects to STDIN and another one connects to STDOUT and STDERR. // So we use Win32 API to invoke a new process. SafeFileHandle parentReadHandle = null; SafeFileHandle parentWriteHandle = null; SafeFileHandle childReadHandle = null; SafeFileHandle childWriteHandle = null; SafeFileHandle childStdInHandle = null; SafeFileHandle childStdOutHandle = null; SafeFileHandle childStdErrHandle = null; FileStream parentReadStream = null; FileStream parentWriteStream = null; try { // Create pipes CreateAsyncPipe(out parentReadHandle, true, out childWriteHandle, false); CreateAsyncPipe(out childReadHandle, false, out parentWriteHandle, true); // Duplicate handles as inheritable handles. childStdOutHandle = DuplicatePipeHandle(childWriteHandle, true, "ChildWrite"); childStdInHandle = DuplicatePipeHandle(childReadHandle, true, "ChildRead"); childStdErrHandle = DuplicatePipeHandle(childWriteHandle, true, "ChildWrite"); // Close non-inheritable handles childWriteHandle.Dispose(); childWriteHandle = null; childReadHandle.Dispose(); childReadHandle = null; // Create parent side streams parentReadStream = new FileStream(parentReadHandle, FileAccess.Read, 4096, true /*Async*/); parentWriteStream = new FileStream(parentWriteHandle, FileAccess.Write, 4096, true /*Async*/); // Prepare command line string commandLine = GetCommandLine(param.ExeFilePath, param.CommandLineOptions); // Determine character encoding of the environment variables bool unicodeEnvironment = (Environment.OSVersion.Platform == PlatformID.Win32NT) ? true : false; // Prepare flags // Note: // We use CREATE_NEW_CONSOLE for separating console. // It disables CREATE_NO_WINDOW, so we use setting below // to hide the console window. // STARTUPINFO.dwFlags |= STARTF_USESHOWWINDOW // STARTUPINFO.wShowWindow = SW_HIDE int creationFlags = CREATE_NEW_CONSOLE /*| CREATE_NO_WINDOW*/; if (unicodeEnvironment) creationFlags |= CREATE_UNICODE_ENVIRONMENT; // Prepare environment variables Dictionary<String, String> envDict = new Dictionary<String, String>(); foreach (DictionaryEntry entry in Environment.GetEnvironmentVariables()) { string key = entry.Key as string; string value = entry.Value as string; if (key != null && value != null) { envDict.Add(key.ToLowerInvariant(), key + "=" + value); } } if (param.EnvironmentVariables != null) { foreach (PipeTerminalParameter.EnvironmentVariable ev in param.EnvironmentVariables) { string expandedValue = Environment.ExpandEnvironmentVariables(ev.Value); string key = ev.Name.ToLowerInvariant(); envDict.Remove(key); envDict.Add(key, ev.Name + "=" + expandedValue); } } byte[] environmentByteArray = GetEnvironmentBytes(envDict, unicodeEnvironment); // Prepare current directory string currentDirectory = Path.GetDirectoryName(param.ExeFilePath); // Prepare STARTUPINFO STARTUPINFO startupInfo = new STARTUPINFO(); startupInfo.dwFlags |= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; startupInfo.hStdInput = childStdInHandle; startupInfo.hStdOutput = childStdOutHandle; startupInfo.hStdError = childStdErrHandle; startupInfo.wShowWindow = SW_HIDE; // Prepare PROCESS_INFORMATION PROCESS_INFORMATION processInfo = new PROCESS_INFORMATION(); // Start process GCHandle environmentGCHandle = GCHandle.Alloc(environmentByteArray, GCHandleType.Pinned); bool apiret = CreateProcess( null, commandLine, IntPtr.Zero, IntPtr.Zero, true, creationFlags, environmentGCHandle.AddrOfPinnedObject(), currentDirectory, startupInfo, ref processInfo ); environmentGCHandle.Free(); if (!apiret) throw new Win32Exception("CreateProcess", Marshal.GetLastWin32Error(), "commandLine=" + commandLine); Process process = Process.GetProcessById(processInfo.dwProcessId); PipedProcess pipedProcess = new PipedProcess(process, childStdInHandle, childStdOutHandle, childStdErrHandle); PipeSocket socket = new PipeSocket(parentReadStream, parentWriteStream); PipeTerminalConnection connection = new PipeTerminalConnection(param, socket, pipedProcess); return connection; } catch (Exception) { if (parentReadStream != null) parentReadStream.Dispose(); if (parentWriteStream != null) parentWriteStream.Dispose(); if (parentReadHandle != null) parentReadHandle.Dispose(); if (parentWriteHandle != null) parentWriteHandle.Dispose(); if (childReadHandle != null) childReadHandle.Dispose(); if (childWriteHandle != null) childWriteHandle.Dispose(); if (childStdInHandle != null) childStdInHandle.Dispose(); if (childStdOutHandle != null) childStdOutHandle.Dispose(); if (childStdErrHandle != null) childStdErrHandle.Dispose(); throw; } }
private bool ValidateParams(out PipeTerminalParameter param, out PipeTerminalSettings settings) { PipeTerminalParameter paramTmp = new PipeTerminalParameter(); PipeTerminalSettings settingsTmp = new PipeTerminalSettings(); StringResource res = PipePlugin.Instance.Strings; try { string caption; if (_radioButtonProcess.Checked) { string exePath = _textBoxExePath.Text; if (exePath.Length == 0) throw new Exception(res.GetString("Form.OpenPipeDialog.Error.NoExePath")); paramTmp.ExeFilePath = exePath; paramTmp.CommandLineOptions = _textBoxCommandLineOptions.Text; paramTmp.EnvironmentVariables = _environmentVariables; caption = Path.GetFileName(exePath); } else if (_radioButtonPipe.Checked) { string path = _textBoxInputPath.Text; if (path.Length == 0) throw new Exception(res.GetString("Form.OpenPipeDialog.Error.NoInputPath")); paramTmp.InputPipePath = path; caption = Path.GetFileName(path); if (!_checkBoxBidirectinal.Checked) { path = _textBoxOutputPath.Text; if (path.Length == 0) throw new Exception(res.GetString("Form.OpenPipeDialog.Error.NoOutputPath")); paramTmp.OutputPipePath = path; caption += "/" + Path.GetFileName(path); } } else { throw new Exception(res.GetString("Form.OpenPipeDialog.Error.NoOpenMode")); } TerminalType terminalType = ((EnumListItem<TerminalType>)_comboBoxTerminalType.SelectedItem).Value; paramTmp.SetTerminalName(terminalType.ToString().ToLowerInvariant()); LogType logType = ((EnumListItem<LogType>)_comboBoxLogType.SelectedItem).Value; ISimpleLogSettings logSettings = null; if (logType != LogType.None) { string logFile = _textBoxLogFile.Text; LogFileCheckResult r = LogUtil.CheckLogFileName(logFile, this); if (r == LogFileCheckResult.Cancel || r == LogFileCheckResult.Error) throw new Exception(""); logSettings = PipePlugin.Instance.TerminalEmulatorService.CreateDefaultSimpleLogSettings(); logSettings.LogPath = logFile; logSettings.LogType = logType; logSettings.LogAppend = (r == LogFileCheckResult.Append); } string autoExecMacroPath = null; if (_textBoxAutoExecMacroPath.Text.Length != 0) autoExecMacroPath = _textBoxAutoExecMacroPath.Text; IAutoExecMacroParameter autoExecParams = paramTmp.GetAdapter(typeof(IAutoExecMacroParameter)) as IAutoExecMacroParameter; if (autoExecParams != null) autoExecParams.AutoExecMacroPath = autoExecMacroPath; settingsTmp.BeginUpdate(); settingsTmp.Caption = caption; settingsTmp.Icon = Poderosa.Pipe.Properties.Resources.Icon16x16; settingsTmp.Encoding = ((EnumListItem<EncodingType>)_comboBoxEncoding.SelectedItem).Value; settingsTmp.LocalEcho = _comboBoxLocalEcho.SelectedIndex == 1; settingsTmp.TransmitNL = ((EnumListItem<NewLine>)_comboBoxNewLine.SelectedItem).Value; settingsTmp.TerminalType = terminalType; if (logSettings != null) settingsTmp.LogSettings.Reset(logSettings); settingsTmp.EndUpdate(); param = paramTmp; settings = settingsTmp; return true; } catch (Exception e) { if (e.Message.Length > 0) GUtil.Warning(this, e.Message); param = null; settings = null; return false; } }