简体   繁体   中英

How Do I Stop An Application From Opening

I want to write a small app that sits in my tray and that allows me to select an executable and prevent it from opening.

The UI of the app is easy to do using WinForms.

What I want to know is how to detect if a certain exe has been lauched and then how to stop it from running. I'm pretty sure I'll have to dig down into some Win32 stuff but I have no experience in that area, hence this post.

There is an existing app similar to this, but I can't for the life of me remember what it's called. It was written in VB6 and it's open source too.

Any help is much appreciated.

Rather than trying to kill the process when it runs, how about stopping it from running in the first place?

Changing what happens when the shell tries to launch an application is simple - add a new registry key to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options

To test this I added a registry key called notepad.exe and within this the string value Debugger with the value calc.exe . Now whenever I try and run notepad calc opens. The following is the exported registry key.

REGEDIT4

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

Having made this change I've not yet managed to open notepad, not bad for a no code solution. If you need to be 100% certain that the application never runs you could always add a "kill" solution too as detailed by others.

Just a small addition to Stephen Nutt's otherwise excellent answer:

If you want the program to go away for good, don't just pop up something else in its stead (calc.exe in Stephen's example). Specify the key: "Debugger" = "ntsd -cq"

This will invoke NT's ever-present command-line debugger ntsd for the program with the command line argument -c saying "execute the debugger command specified next"; the debugger command is q (meaning quit). This will stop the debugger, which as a side effect will kill the debuggee -- the program you want to prevent from running -- too.

Clean, nice and easy. The only side effect I observed is that sometimes a transient command window pops up briefly with a debugger prompt only to disappear again in a moment.

OK, I just found the app I was originally looking for.

It's called Temptation Blocker and it's available here

It will find all the executables and allow you to select what to block for however many hours.

It's not perfect, I wish it would auto start so I don't have to manually start it but apart from that it's pretty good

another option: link under policies in the registry:

  • HKEY_CURRENT_USER folder in the top-left side of the window.
  • Double-click the Software folder below HKEY_CURRENT_USER .
  • Double-click the Microsoft folder.
  • Double-click the Windows folder.
  • Double-click the CurrentVersion folder.

A Windows hook should solve your problem. I haven't ever tried this...but you will have to do some pinvoke to Win32 APIs to achieve this. Google Win32 hook and see.

One of the answer suggested a way of stopping applications running with Windows Registery key over Windows GUI. Since this question use c# as tag, I would like to put c# code for it, you guys can try it for yourself.

This code stops notepad.exe from running. It does it by adding several registery keys with the C# code. The logic behind it given in this link Explanation .

            RegistryKey key = Registry.CurrentUser.OpenSubKey("Software", true);

            key.CreateSubKey("Microsoft");
            key = key.OpenSubKey("Microsoft", true);

            key.CreateSubKey("Windows");
            key = key.OpenSubKey("Windows", true);

            key.CreateSubKey("CurrentVersion");
            key = key.OpenSubKey("CurrentVersion", true);

            key.CreateSubKey("Policies");
            key = key.OpenSubKey("Policies", true);

            RegistryKey explorerKey = key.CreateSubKey("explorer");
            key = key.OpenSubKey("explorer", true);

            explorerKey.SetValue("DisallowRun", 0x00000001, RegistryValueKind.DWord);

            RegistryKey disallowRun = key.CreateSubKey("DisallowRun");
            key = key.OpenSubKey("DisallowRun", true);

            disallowRun.SetValue("1", "notepad.exe", RegistryValueKind.String);

I remember some Win32 functionality which helps solving such scenarios. If you are using .Net anyway that would probably a pain to implement. I would use some of the cross-process synchronization objects (don't know out of my head which ones are cross-process) and would set some signal. At startup just let your app check whether the signal is already set. If yes, just close the app again.

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

instead of waiting for the executable to open, so you can close it again, you can also just cripple the executable.

just change a few of the bytes in the exe header and prevent it that way from ever starting.

Just do it in a way that the effect is reversible.

    private bool KillProcess(string name)
    {
        foreach (Process clsProcess in Process.GetProcesses())
        {
            if (clsProcess.ProcessName.ToLower().StartsWith(name.ToLower()))
            {
                clsProcess.Kill();
                return true;
            }
        }
       return false;
    }

yeah this is the method I'm using so far. This will close the app after it's been opened so it gets me about 90% there. I use a timer that checks every 10 seconds. I'm just wondering if it's worth spending the time researching the windows hook (which i know nothing about) for the convenience of instant app blocking. Those of you who know the Win32 api, is it worth the effort?

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
        }
    }
}

I'm using this in a program, and it works perfectly, and it should be able to change this for your needs.

You can write a global hook.

What will be hooked is less important than the fact it will be global, and therefore, implemented in a separate DLL. In that library you properly handle attaching to a new module. If you detect process duplicate — kill it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM