代码之家  ›  专栏  ›  技术社区  ›  Spidey

如何阻止应用程序打开

  •  5
  • Spidey  · 技术社区  · 16 年前

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

    应用程序的用户界面使用WinForms很容易实现。

    我想知道的是,如何检测某个exe是否已被触发,然后如何阻止它运行。我很肯定我会深入研究一些win32的东西,但我在这方面没有经验,所以这篇文章。

    现在有一个类似的应用程序,但我一辈子都记不起来它叫什么。它是用vb6编写的,也是开源的。

    任何帮助都非常感谢。

    谢谢。

    10 回复  |  直到 16 年前
        1
  •  9
  •   Stephen Nutt    16 年前

    与其在进程运行时试图终止它,不如先停止它的运行?

    更改shell尝试启动应用程序时发生的情况很简单-将新注册表项添加到 hkey_local_machine\software\microsoft\windows nt\currentversion\image文件执行选项

    为了测试这个,我添加了一个名为 记事本 其中字符串值 调试器 用价值 小算盘 . 现在每当我尝试运行记事本时,Calc就会打开。以下是导出的注册表项。

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

    做了这个更改之后,我还没有打开记事本,这对于一个没有代码的解决方案来说也不错。如果您需要100%地确定应用程序永远不会运行,那么您总是可以添加一个“终止”解决方案,正如其他人所详细描述的那样。

        2
  •  5
  •   LaszloG    16 年前

    除了史蒂芬·纳特在其他方面的出色回答:

    如果你想让程序永远消失,不要只弹出其他东西来代替它(在斯蒂芬的例子中是calc.exe)。指定密钥: “Debugger”=“NTSD-C Q”

    这将调用NT现有的命令行调试器 NTSD 对于带有命令行参数的程序 -C 说“执行下一步指定的调试程序命令”;调试程序命令是 Q (表示退出)。这将停止调试器,作为副作用,它也将杀死调试对象——您希望阻止运行的程序。

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

        3
  •  1
  •   P.K    16 年前

    一个Windows钩子可以解决你的问题。我从来没有尝试过……但要实现这一点,您必须对win32 API执行一些pinvoke操作。谷歌win32钩子,看。

        4
  •  1
  •   Spidey    16 年前

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

    它叫做诱惑阻滞剂 available here

    它将找到所有的可执行文件,并允许您选择要阻塞的内容,持续几个小时。

    它不完美,我希望它能自动启动,这样我就不用手动启动了,但除此之外,它还不错

        5
  •  0
  •   Achim    16 年前

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

        6
  •  0
  •   Amr Elgarhy    16 年前

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

        7
  •  0
  •   Toad    16 年前

    您不必等待可执行文件打开,这样您就可以再次关闭它,而只需破坏可执行文件。

    只需更改exe头中的几个字节,就可以阻止它以这种方式启动。

    这样做的效果是可逆的。

        8
  •  0
  •   Spidey    16 年前
        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的人,这值得付出努力吗?

        9
  •  0
  •   Femaref    16 年前
    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
            }
        }
    }
    

    我正在一个程序中使用它,它工作得很好,应该可以根据您的需要更改它。

        10
  •  0
  •   bohdan_trotsenko    16 年前

    你可以写一个全局钩子。

    被钩住的并不重要,因为它是全局的,因此在一个单独的DLL中实现。在该库中,您可以正确处理与新模块的连接。如果你检测到过程重复,杀死它。

    推荐文章