简体   繁体   中英

Stop user from opening an already program using PowerShell

I want to stop the user from running another instance of an already running program/service in Windows using PowerShell.
Eg: I have notepad opened, then for minute's time period I want to disable the option to open notepad, since it already is running.

As of now, I can detect if the program is open or not, and if not I may have it opened for user (code attached).

$processName = Get-Process notepad -ErrorAction SilentlyContinue

if ( $processName ) {
    Write-Host 'Process is already running!'
    #stop another instance of notepad to be opened, since it is already running
}
else {
    $userChoice = Read-Host 'Process is not running, should I start it? (Y/N)  '

    if ($userChoice -eq 'Y') {
        Start-Process notepad
    }
    else {
        Write-Host 'No Problem!'
    }
}


But, how can I disable the option for the user to open another instance of the same?

Any lead for the same would be helpful.

Since Windows doesn't have such a feature that prevents launching multiple copies of an executable, you have two options:

  1. poll process list every now and then. Terminate extra instances of the application
  2. create a wrapper to the application and use a mutex to prevent multiple copies

The first option has its caveats. If additional copies are launched, it takes on the average half the polling interval to detect those. What's more, which of the processes are to be terminated? The eldest? The youngest? Some other criteria?

The second one can be circumvented easily by just launching the application itself.

The only real solution is to implement a single-instance feature in the application itself. Games often do this. For business software, be wary that the users will hate you, if there is a single reason why running multiple instances would be of use. Yes, especially if that use case would be absurd .

As an example of a mutex-based launcher, consider the following function

function Test-Mutex {
    $mtx = new-object System.Threading.Mutex($false, "SingleInstanceAppLauncher")

    if(-not $mtx.WaitOne(0, $false)) {
        write-host "Mutex already acquired, will not launch second instance!"
        read-host "Any key"
        return
    }
    write-host "Running instance #1"
    read-host "Any key"
    # Do stuff
}

As like the solution 2 caveat, any user can work around the limit by just executing the do suff part. Remember, the wrapper prevents launching multiple instances of the wrapper , not about the do stuff .

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