【问题标题】:How Do I Stop An Application From Opening如何阻止应用程序打开
【发布时间】:2023-04-11 09:43:01
【问题描述】:

我想编写一个放在托盘中的小应用程序,它允许我选择一个可执行文件并阻止它打开。

应用程序的 UI 使用 WinForms 很容易实现。

我想知道的是如何检测某个 exe 是否已启动,然后如何阻止它运行。我很确定我将不得不深入研究一些 Win32 的东西,但我在这方面没有经验,因此这篇文章。

有一个与此类似的现有应用程序,但我一生都无法记住它的名称。它是用 VB6 编写的,也是开源的。

非常感谢任何帮助。

【问题讨论】:

  • 为什么要阻止应用程序打开?只限制用户权限,使应用程序无法打开不是更好吗?
  • 是的,我查看了设置组策略,但我发现仍然可以从 CMD 启动应用程序,所以我也需要禁用我不想这样做的那个。
  • 不,你可以在文件本身上设置ACL,使其无法执行。

标签: c# .net c++ winapi


【解决方案1】:

与其在进程运行时试图杀死它,不如从一开始就阻止它运行?

更改 shell 尝试启动应用程序时发生的情况很简单 - 将新注册表项添加到 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options

为了对此进行测试,我添加了一个名为 notepad.exe 的注册表项,并在其中添加了字符串值 Debugger,其值为 calc.exe。现在,每当我尝试运行记事本 calc 时,都会打开。以下是导出的注册表项。

REGEDIT4

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe]
"Debugger"="calc.exe"

进行此更改后,我还没有设法打开记事本,这对于无代码解决方案来说还不错。如果您需要 100% 确定应用程序永远不会运行,您可以随时添加其他人详述的“终止”解决方案。

【讨论】:

  • 这是斯蒂芬的好方法。我可以将它添加到应用程序中,所以现在不是每 10 秒轮询一次,而是只更改一次注册表。甜蜜。
  • 这个斯蒂芬纳特是什么?这是 C# 代码吗? @StephenNutt
【解决方案2】:

只是对 Stephen Nutt 的出色回答的一个小补充:

如果您希望程序永远消失,请不要只弹出其他内容来代替它(Stephen 示例中的 calc.exe)。指定密钥: "调试器" = "ntsd -c q"

这将为程序调用NT一直存在的命令行调试器ntsd,命令行参数-c表示“执行下一个指定的调试器命令”;调试器命令是q(意思是退出)。这将停止调试器,其副作用是会杀死被调试者——您想要阻止运行的程序。

干净、美观、简单。我观察到的唯一副作用是,有时会短暂弹出一个短暂的命令窗口,并带有调试器提示,但一会儿又消失了。

【讨论】:

  • 谢谢你,我想知道放什么来代替 calc.exe。
【解决方案3】:

好的,我刚刚找到了我最初寻找的应用程序。

它叫做 Temptation Blocker,它是 available here

它将找到所有可执行文件,并允许您选择要阻止多少小时的内容。

它并不完美,我希望它会自动启动,所以我不必手动启动它,但除此之外它还不错

【讨论】:

    【解决方案4】:

    Windows 挂钩应该可以解决您的问题。我从来没有尝试过这个......但你必须对 Win32 API 做一些 pinvoke 来实现这一点。 Google Win32 看看吧。

    【讨论】:

      【解决方案5】:

      另一个选项:link 在注册表中的策略下:

      • HKEY_CURRENT_USER 位于窗口左上角的文件夹。
      • 双击HKEY_CURRENT_USER下方的Software文件夹。
      • 双击Microsoft 文件夹。
      • 双击Windows 文件夹。
      • 双击CurrentVersion 文件夹。

      【讨论】:

        【解决方案6】:

        我记得一些有助于解决此类情况的 Win32 功能。如果您无论如何都在使用.Net,那么实施起来可能会很痛苦。我会使用一些跨进程同步对象(不知道哪些是跨进程的)并且会设置一些信号。在启动时,只需让您的应用程序检查信号是否已设置。如果是,请再次关闭应用程序。

        【讨论】:

          【解决方案7】:

          其中一个想法,但不是最好的方法是监视正在运行的进程并在找到所需的运行进程时终止,这可以使用普通的托管 C# 代码来完成。

          【讨论】:

          • 是的,这是我目前使用的方法。这将在打开应用程序后关闭应用程序,因此它可以让我到达那里大约 90%。 private bool KillProcess(string name) { foreach (Process clsProcess in Process.GetProcesses()) { if (clsProcess.ProcessName.ToLower().StartsWith(name.ToLower())) { clsProcess.Kill();返回真; } } 返回假;我只是想知道是否值得花时间研究 windows 挂钩(我对此一无所知)以方便即时应用程序阻止。
          【解决方案8】:

          您可以再次关闭可执行文件,而不是等待可执行文件打开,也可以只是削弱可执行文件。

          只需更改 exe 标头中的一些字节并防止它以这种方式启动。

          只要以一种效果可逆的方式进行即可。

          【讨论】:

            【解决方案9】:
                private bool KillProcess(string name)
                {
                    foreach (Process clsProcess in Process.GetProcesses())
                    {
                        if (clsProcess.ProcessName.ToLower().StartsWith(name.ToLower()))
                        {
                            clsProcess.Kill();
                            return true;
                        }
                    }
                   return false;
                }
            

            是的,这是我目前使用的方法。这将在应用程序打开后关闭应用程序,因此它可以让我到达那里大约 90%。我使用每 10 秒检查一次的计时器。我只是想知道是否值得花时间研究 windows 挂钩(我对此一无所知)以方便即时应用程序阻止。 懂Win32 api的朋友,值得努力吗?

            【讨论】:

              【解决方案10】:
              internal static class Program
              {
                  private static Mutex m;
              
                  [STAThread]
                  private static void Main()
                  {
                      bool flag;
                      m = new Mutex(true, "ProgramName", out flag);
                      if (!flag)
                      {
                          MessageBox.Show("Another instance is already running.");
                      }
                      else
                      {
                          //start program
                      }
                  }
              }
              

              我在一个程序中使用它,它运行良好,它应该能够根据您的需要进行更改。

              【讨论】:

              • 我的代码有效地做同样的事情。即找到一个进程并处理它。
              • 是的,但是那些评估所有进程的人,用我的,你可以简单地拥有一个互斥锁列表并检查它。此外,我的解决方案是针对其他问题 - 阻止您的 OWN 应用程序打开 TWICE。我只是误解了问题本身,因为阅读得太快了:)
              【解决方案11】:

              你可以写一个全局钩子。

              挂钩的内容不如全局的事实重要,因此在单独的 DLL 中实现。在该库中,您可以正确处理附加到新模块。如果你检测到进程重复——杀死它。

              【讨论】:

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