如何将 ctrl+c 发送到 C# 中的进程?

2023-11-21

我正在为命令行可执行文件编写一个包装类。该exe接受来自的输入stdin直到我击中Ctrl+C在命令提示符 shell 中,在这种情况下,它将输出打印到stdout基于输入。我想模拟一下Ctrl+C按 C# 代码,将终止命令发送到 .NETProcess目的。我试过打电话Process.Kill(),但这似乎并没有给我带来任何好处StandardOutput StreamReader。我可能有什么地方做得不对吗?这是我尝试使用的代码:

ProcessStartInfo info = new ProcessStartInfo(exe, args);
info.RedirectStandardError = true;
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
Process p = Process.Start(info);

p.StandardInput.AutoFlush = true;
p.StandardInput.WriteLine(scriptcode);

p.Kill();

string error = p.StandardError.ReadToEnd();
if (!String.IsNullOrEmpty(error)) 
{
    throw new Exception(error);
}
string output = p.StandardOutput.ReadToEnd();

输出始终为空,即使我从stdout当我手动运行exe时。

Edit:顺便说一句,这是 C# 2.0。


Despite the fact that using GenerateConsoleCtrlEvent() for sending Ctrl+C signal is the right answer, it needs significant clarification to get it to work in different .NET application types.

如果您的 .NET 应用程序不使用自己的控制台(Windows Forms/WPF/Windows Service/ASP.NET),则基本流程是:

  1. Attach the main .NET process to the console of the process that you want to signal with Ctrl+C.
  2. Prevent the main .NET process from stopping because of Ctrl+C event by disabling handling of the signal with SetConsoleCtrlHandler().
  3. 生成控制台事件current控制台与GenerateConsoleCtrlEvent() (processGroupId应该为零!带有发送代码的答案p.SessionId将不起作用并且不正确)。
  4. 等待发出信号的进程响应(例如等待它退出)
  5. Restore Ctrl+C handling by main process and disconnect from console.

以下代码片段说明了如何执行此操作:

Process p;
if (AttachConsole((uint)p.Id)) {
    SetConsoleCtrlHandler(null, true);
    try { 
        if (!GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0))
            return false;
        p.WaitForExit();
    } finally {
        SetConsoleCtrlHandler(null, false);
        FreeConsole();
    }
    return true;
}

where SetConsoleCtrlHandler(), FreeConsole(), AttachConsole() and GenerateConsoleCtrlEvent()是本机 WinAPI 方法:

internal const int CTRL_C_EVENT = 0;
[DllImport("kernel32.dll")]
internal static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent, uint dwProcessGroupId);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool AttachConsole(uint dwProcessId);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
internal static extern bool FreeConsole();
[DllImport("kernel32.dll")]
static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add);
// Delegate type to be used as the Handler Routine for SCCH
delegate Boolean ConsoleCtrlDelegate(uint CtrlType);

Note that waiting for the targeted process to respond, typically by waiting for the process to exit, is critical. Otherwise, the Ctrl+C signal will remain in the current process's input queue and when handling is restored by the second call to SetConsoleCtrlHandler(), that signal will terminate the current process, rather than the targeted one.

Things become more complex if you need to send Ctrl+C from .NET console application. The above approach will not work because AttachConsole() returns false in this case (the main console app already has a console). It is possible to call FreeConsole() before AttachConsole() call, but doing so will result in the original .NET app console being lost, which is not acceptable in most cases.

这是我针对这种情况的解决方案;它可以工作并且对 .NET 主进程控制台没有副作用:

  1. Create small supporting .NET console program that accepts process ID from command line arguments, loses its own console with FreeConsole() before the AttachConsole() call and sends Ctrl+C to the target process with code mentioned above.
  2. The main .NET console process just invokes this utility in a new process when it needs to send Ctrl+C to another console process.
  3. In the main .NET console process call SetConsoleCtrlHandler(null, true) before spawning the "killer"-process (from step 1) and SetConsoleCtrlHandler(null, false) after. Else your main process will also receive Ctrl+C and die
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将 ctrl+c 发送到 C# 中的进程? 的相关文章

  • 用于代数简化和求解的 C# 库 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 网络上有很多代数求解器和简化器 例如 algebra com 上不错的代数求解器和简化器 然而 我正在
  • 未提供参数时如何指定 C# System.Commandline 行为?

    在我的控制台应用程序中 当未提供控制台参数时 将执行我指定列表 在本例中为参数 3 的任何处理程序 调用该处理程序时 布尔参数设置为 false 但对我来说 根本不调用它更有意义 如何防止这种情况发生并显示帮助文本 using System
  • 如何在 .NET Framework 2.0 中模拟“Func<(Of <(TResult>)>) 委托”?

    我尝试使用这个类代码项目文章 http www codeproject com KB threads AsyncVar aspx在 VB NET 和 NET Framework 2 0 中 除了这一行之外 所有内容似乎都可以编译Privat
  • 如何将 protobuf-net 与不可变值类型一起使用?

    假设我有一个像这样的不可变值类型 Serializable DataContract public struct MyValueType ISerializable private readonly int x private readon
  • 提交后禁用按钮

    当用户提交付款表单并且发布表单的代码导致 Firefox 中出现重复发布时 我试图禁用按钮 去掉代码就不会出现这个问题 在firefox以外的任何浏览器中也不会出现这个问题 知道如何防止双重帖子吗 System Text StringBui
  • 错误:表达式不产生值

    我尝试将以下 C 代码转换为 VB NET 但在编译代码时出现 表达式不产生值 错误 C Code return Fluently Configure Mappings m gt m FluentMappings AddFromAssemb
  • 在 C 中匹配二进制模式

    我目前正在开发一个 C 程序 需要解析一些定制的数据结构 幸运的是我知道它们是如何构造的 但是我不确定如何在 C 中实现我的解析器 每个结构的长度都是 32 位 并且每个结构都可以通过其二进制签名来识别 举个例子 有两个我感兴趣的特定结构
  • 复制目录内容

    我想将目录 tmp1 的内容复制到另一个目录 tmp2 tmp1 可能包含文件和其他目录 我想使用C C 复制tmp1的内容 包括模式 如果 tmp1 包含目录树 我想递归复制它们 最简单的解决方案是什么 我找到了一个解决方案来打开目录并读
  • 如何区分用户点击链接和页面自动重定向?

    拥有 C WebBrowser control http msdn microsoft com en us library system windows forms webbrowser aspx在我的 WinForms 应用程序中 并意识
  • java.io.Serialized 在 C/C++ 中的等价物是什么?

    C C 的等价物是什么java io Serialized https docs oracle com javase 7 docs api java io Serializable html 有对序列化库的引用 用 C 序列化数据结构 ht
  • 使用接口有什么好处?

    使用接口有什么用 我听说它用来代替多重继承 并且还可以用它来完成数据隐藏 还有其他优点吗 哪些地方使用了接口 程序员如何识别需要该接口 有什么区别explicit interface implementation and implicit
  • 回发后刷新时提示确认表单重新提交。我做错了什么?

    我有一个以空白 默认状态启动的仪表板 我让用户能够将保存的状态加载到仪表板中 当他们单击 应用 按钮时 我运行以下代码 function CloseAndSave var radUpload find radUpload1ID var in
  • qdbusxml2cpp 未知类型

    在使用 qdbusxml2cpp 程序将以下 xml 转换为 Qt 类时 我收到此错误 qdbusxml2cpp c ObjectManager a ObjectManager ObjectManager cpp xml object ma
  • 我可以使用 moq Mock 来模拟类而不是接口吗?

    正在经历https github com Moq moq4 wiki Quickstart https github com Moq moq4 wiki Quickstart 我看到它 Mock 一个接口 我的遗留代码中有一个没有接口的类
  • 使用自定义堆的类似 malloc 的函数

    如果我希望使用自定义预分配堆构造类似 malloc 的功能 那么 C 中最好的方法是什么 我的具体问题是 我有一个可映射 类似内存 的设备 已将其放入我的地址空间中 但我需要获得一种更灵活的方式来使用该内存来存储将随着时间的推移分配和释放的
  • 外键与独立关系 - Entity Framework 5 有改进吗?

    我读过了several http www ladislavmrnka com 2011 05 foreign key vs independent associations in ef 4 文章和问题 https stackoverflow
  • 等待进程释放文件

    我如何等待文件空闲以便ss Save 可以用新的覆盖它吗 如果我紧密地运行两次 左右 我会得到一个generic GDI error
  • CMake 无法确定目标的链接器语言

    首先 我查看了this https stackoverflow com questions 11801186 cmake unable to determine linker language with c发帖并找不到解决我的问题的方法 我
  • 不同类型指针之间的减法[重复]

    这个问题在这里已经有答案了 我试图找到两个变量之间的内存距离 具体来说 我需要找到 char 数组和 int 之间的距离 char data 5 int a 0 printf p n p n data 5 a long int distan
  • 如何从 ODBC 连接获取可用表的列表?

    在 Excel 中 我可以转到 数据 gt 导入外部数据 gt 导入数据 然后选择要使用的数据源 然后在提供登录信息后 它会给我一个表格列表 我想知道如何使用 C 以编程方式获取该列表 您正在查询什么类型的数据源 SQL 服务器 使用权 看

随机推荐

  • 如何在 SwiftUI 中获取视图或屏幕的高度和宽度

    我使用拖动手势来更改颜色对象的色相 饱和度 这个想法是 您可以在屏幕上拖动并查看所有色调值 0 0 1 0 以及从上到下相同的饱和度 我需要屏幕 或视图 这是一个单视图应用程序 的大小 以便将 CGPoint 值标准化 转换为 0 0 1
  • Laravel 共享主机 .htaccess

    我正在尝试将 Laravel 项目部署到共享托管上 我已经成功完成了大部分艰苦工作 但我无法在没有 Forbidden 问题的情况下剥离 public 目录 该网站可以正常工作并为这些链接显示相同的页面 www mywebsite com
  • document.querySelectorAll的返回类型是什么

    假设我有以下列表 ol li Cookies ol li Coffee li li Milk li li class test1 Chocolate li ol 我在 html 的末尾执行此选择 var nodes document que
  • 如何将 JSON 字符串转换为数组

    我想做的是 从 php 中的文本区域获取 JSON 作为输入 使用此输入并将其转换为 JSON 并将其传递给 php curl 来发送请求 我从 api 的 get 获取 php 这个 json 字符串我想传递给 json 但它没有转换为数
  • 从长远来看值得使用 Redux-Saga 吗? [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 Locked 这个问题及其答案是locked因为这个问题是题外话 但却具有历史意义 目前不接受新的答案或互动 Redux Saga 是一个 Redux 副作用管理器 据说已被弃用 并且不再
  • 使用 angularfire2 和 firestore 创建自动完成搜索?

    我正在尝试为我的网络应用程序构建一个简单的搜索功能 有关于如何使用实时数据库创建它的文档 我需要做出哪些改变才能使这项工作正常进行火库 本教程取自这里https angularfirebase com lessons autocomplet
  • Python 读取输入时出现 EOF 错误

    n input dum input d for i in range 0 n 1 x raw input x x split d int x 0 int x 1 array d keys for key in d keys if d key
  • 没有完整命名空间的类型引用

    有两个打字稿文件 A ts export class Person public name string constructor and B ts import A module A var p A Person 到目前为止一切正常 但是
  • 处理一元运算符的中缀到后缀算法

    算法的 I p 将是这样的表达式 a b a b c 即标准 C 编译器支持的任何表达式 现在我已经将输入格式化为标记流 标记包含信息 无论是运算符还是操作数 该算法应该接受这个并给我一个可以计算的后缀表达式 如果我使用标准转换算法 我无法
  • 在 Laravel 中访问 $_GET 值的最佳实践是什么?

    有没有更好的访问方式 GET而不是 Laravel 中的变量本身 或者就是这样 我需要 API 的多个参数 例如 users q keyword order desc limit 5 是否有更干净 更安全且类似 Laravel 的方式来访问
  • 使用 Azure Functions 在本地存储状态

    Azure Functions 是否提供本地 状态 存储来消除调用其他服务 例如存储 docDB 等 的需要 功能基于 Azure 应用服务构建 提供存储持久文件的功能 例如您可以将文件存储在 HOME data SomeFolderOfY
  • 在 Equinox 中,是否可以将 OSGi 包标记为从其包含功能的 p2.inf 开始?

    我有一个 Eclipse 功能 其中包含多个捆绑包 我想告诉 p2 在安装该功能时将其中一个捆绑包标记为已启动 这可以使用捆绑包自己的 META INF p2 inf 来实现 如下所示 instructions configure mark
  • Json.NET:反序列化嵌套 Json

    如何反序列化此 Json 字符串上的 Items 类部分 Buddies count 1 items id 5099207ee4b0cfbb6a2bd4ec firstName Foo lastName Bar image url size
  • Buildozer 未能执行最后一个命令

    当我尝试在我的设备上构建 推送并自动运行 apk 时 使用buildozer android debug deploy run它显示这些错误 Check configuration tokens Ensure build layout Ch
  • notify可以多次唤醒同一个线程吗?

    想象一下 Java 中有一个典型的生产者 消费者模式 为了提高效率 你想使用notify 并不是notifyAll 当一个新元素被添加到队列中时 如果两个生产者线程调用notify 是否可以保证两个不同的等待消费者线程会被唤醒 或者可以是两
  • Windows 中相当于命令“date+%s”的是什么

    我正在编写一个批处理脚本 我需要 unix 时间 在linux下很容易 但我不知道如何在windows下做到这一点 这是一个适用于任何区域设置的本机批处理解决方案 它使用 WMIC 以与区域设置无关的方式获取当前本地时间 其他一切都是字符串
  • CSS中的蛇形对齐

    我一直在努力解决 CSS 中的以下问题 我有任意数量的项目 跨度或 div 我想将它们以蛇状图案包装在容器内 我的意思是 如果我有 10 个项目 每个项目的宽度为 20 像素 我希望它们在 60 像素宽的容器中显示如下 0 1 2 5 4
  • setNeedsDisplay并不总是调用drawRect

    我在自定义表格单元格中有一个自定义视图 每次更改自定义视图上的特定属性时 我都会调用 self setNeedsDisplay 这会重绘视图 void drawRect CGRect rect 该属性在表视图委托中设置tableView c
  • 如何在 dart 中创建多个构造函数?

    我想通过调用具有不同数量参数的构造函数来创建不同的对象 我怎样才能在 Dart 中实现这一目标 class A String b c d A this b this c A this b this c this d See 构造函数部分飞镖
  • 如何将 ctrl+c 发送到 C# 中的进程?

    我正在为命令行可执行文件编写一个包装类 该exe接受来自的输入stdin直到我击中Ctrl C在命令提示符 shell 中 在这种情况下 它将输出打印到stdout基于输入 我想模拟一下Ctrl C按 C 代码 将终止命令发送到 NETPr