【问题标题】:Prevent a user from closing an application that is opened through a C# program防止用户关闭通过 C# 程序打开的应用程序
【发布时间】:2010-07-24 20:43:30
【问题描述】:

我有一个旧的基于命令行的程序(如果重要的话,它的 fortran),当用户单击按钮时,它会从 C# 应用程序中打开。如果命令行程序在运行时关闭,则数据会损坏。有什么办法可以防止人们在它运行时关闭它?比如使 [x] 不可用或以某种方式将程序嵌入到我的程序中?

 System.Diagnostics.Process pname =
 System.Diagnostics.Process.Start(Path.Combine(Application.StartUpPath,
"diag_main.exe"));

    pname.Exited += new EventHandler(pname_Exited);

注意:我希望仍然能够看到应用程序正在运行,并且在完成后它会自行关闭,我只是不能让人们在它运行过程中杀死它。

【问题讨论】:

  • 你是如何启动它的?可以发一下代码吗?

标签: c# command-line fortran embedding


【解决方案1】:

需要大量编程但可以完成的解决方案:

编写一个单独的程序,截取程序的屏幕输出并以某种方式将其发送到您的程序。在隐藏窗口中运行此程序,它会转身运行应用程序并将输出发送到您的程序。

几乎可以肯定,至少拦截器的某些部分必须进行组装。

编辑:即使程序只写入标准输出,重定向标准输出也不会这样做——他希望显示输出。

可能需要截取三样东西:

Int 21h 文件系统写入。这些是可以通过重定向标准输出来拦截的东西。请注意,某些程序可能会写入实际代表标准输出文件的不同句柄号——在程序的句柄表中查找正在写入的句柄并将其与标准输出条目(IIRC 第二个条目)进行比较——如果它们匹配它实际上是屏幕输出。

第二级是 IIRC int 10h。有几个子调用必须被拦截。

最后,程序可以直接进行屏幕写入。拦截这些将是一个主要的痛苦,我什至不会考虑尝试它(你基本上必须重写 dos 框。)相反,经常将屏幕内存与保存的副本进行比较以寻找更改。

在所有这三种情况下,至少部分例程必须用汇编语言编写。

我做了第一个,玩了第二个,但后来我发现我可以不做。我从来没有尝试过第三个。

【讨论】:

  • 他为什么不能直接从进程中重定向STDOUT?
  • +1 我认为这是最好的方法。我实际上并不认为它需要很多工作,我确信 System.Diagnostics.Process 类具有用于重定向标准输入和输出的属性。然后他可以将他的应用程序嵌入到某种 WPF 或 WinForms 应用程序中,然后确保用户无法杀死宿主应用程序。
  • +1 在 .NET 中重定向 stdio 并不困难。它不适用于直接写入控制台的程序,但这种情况很少见。
  • 不幸的是,拦截 STDOUT 可能不会这样做。任何保持屏幕格式的程序都不能被 STDOUT 截获。只有严格的控制台应用程序(几乎所有这些都是某种实用程序)才能如此容易地被拦截。
  • 我怀疑普通的 FORTRAN 应用程序会在不使用标准输出的情况下写入控制台。
【解决方案2】:

很遗憾,没有。如果另一个程序有一个 UI,那么你就不能对用户隐藏它。如果没有,那么您可以使用ProcessStartInfo 类在不显示控制台窗口的情况下启动它。但是,即使您这样做,他们仍然可以使用任务管理器将其杀死。

【讨论】:

    【解决方案3】:

    我不知道这是否适用于您的应用程序,但您可以使用隐藏窗口启动该过程 - 这意味着应用程序被隐藏并且无法通过 UI 停止。

    在构造您的流程对象时,请使用带有ProcessStartInfo 对象的构造函数重载。将此属性的WindowStyle 属性设置为ProcessWindowStyle.Hidden,将CreateNoWindow 属性设置为true

    ProcessStartInfo startInfo = new ProcessStartInfo("fortranApp.exe");
    startInfo.WindowStyle = ProcessWindowStyle.Hidden;
    startInfo.CreateNoWindow = true;
    
    Process.Start(startInfo);
    

    当然,它仍然会出现在进程列表中并且可以这样被杀死,但至少这样可以防止任何意外关闭。

    【讨论】:

    • 我希望能够看到应用程序
    • @Pieces - 你总是可以最小化启动它。除此之外,如果应用程序本身不支持它,我现在无法启动进程并禁用窗口控制按钮。
    • 是否可以隐藏启动进程,将某些内容附加到标准输出以收集 Fortran 程序生成的消息并将其通过管道传输到 C# 程序的显示窗口?
    • 是的,在 Process.Start 返回的进程对象(属性称为 StandardOutput)上使用 streamReader。
    【解决方案4】:

    您可以尝试使用ProcessStartInfo 并将属性CreateNoWindow 设置为true 并设置WindowStyle to ProcessWindowStyle.Hidden。我自己没试过,但也许你很幸运。

    【讨论】:

      【解决方案5】:

      如果程序在cmd 窗口中加载,那么不,没有办法阻止用户关闭窗口。更好的方法是在后台启动程序,对临时用户隐藏它。恶意用户仍然可以找到该进程并将其杀死,但这可能不是问题。

      您可以通过以下方式做到这一点:

      var psi = new ProcessStartInfo();
      psi.CreateNoWindow = true;
      /// etc.
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多