-
Notifications
You must be signed in to change notification settings - Fork 986
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WindowsFormsApplicationBase.IsSingleInstance applications are global on a machine, not per user #3715
Comments
Can the named pipe be put into logon session namespace? This doc says
And this doc seems to suggest that Might be worth investigating if named pipes can be put into the users logon session namespace on all supported Windows versions by naming them accordingly, instead of reimplementing everything. |
No, the local namespace doesn't apply to named pipes - you just get a pipe called "Local\whatever" in the global namespace. I think the |
Some additional considerations in https://devblogs.microsoft.com/oldnewthing/20070629-00/?p=26213 |
Why not adding the session id in the pipe name to make it unique per session ? |
A named pipe with a predictable name creates a scenario where another user can register the same pipe name and therefore prevent your application from starting. This is a potential security consideration on multi-user servers. |
But it must be a predictable name (based on the entry module id it seems : |
Could you retrieve the session ID and reject pipe connections from different sessions? Outright rejecting undesired connections might be better than a random pipe name. Not sure if the pipe handle is available for this though, and whether this session ID is actually the same as the logon session. |
It does need to be a consistent name, but it needs to be consistent in a local namespace - the global namespace is the problem. If your program runs with a pipe named I think you can do it with a mutex, a shared memory segment and a pipe, but that's a lot of moving parts. |
Pinging @cston and @KathleenDollard on this. |
My .Net 6 build is hitting this issue. |
@KathleenDollard: I am strongly in favor to get this fixed. Let's talk! |
This is nothing the WinForms team can decide on their own. @JeremyKuhne, @merriemcgaw FYI. |
If we decided to get this addressed, we should address this, too: |
…r use in TryCreatePipeServer to avoid system wide blocking. Used in conjunction with PipeOptions.CurrentUserOnly
Moving this to .NET 10. |
@KlausLoeffelmann the PR: #11258 has mentioned all issues together about WindowsFormsApplicationBase.IsSingleInstance. Do you mean we create a new issue with writing these issues together? |
.NET Core Version:
v5.0.0-preview.7
Have you experienced this same bug with .NET Framework?:
No
Problem description:
The implementation of
WindowsFormsApplicationBase.IsSingleInstance
from #3200 uses a named pipe as its synchronization and communication tool, but named pipes are in a global namespace (at least on Windows) and thus any assembly can only be running once on any given machine.Expected behavior:
Able to start this executable in multiple user accounts (under terminal services or fast user switching) at once.
Actual behaviour:
Starting the executable in a second user account produces an uncaught
CantStartSingleInstanceException
exception.Strictly speaking this is a potential denial of service issue; by using a named pipe with a predictable name, users can prevent others on the same machine from ever starting the application. Adding the session identifier to the pipe name is enough to make the named pipe session-local, but not enough to prevent others from creating a pipe with the same name.
I don't know what other options there are; mutexes and event handles have a session namespace, but don't allow for data transfer. Local TCP runs into trouble with firewalls (as the old Remoting implementation did). Cursory reading shows that named memory mappings are Windows only, and require marshalling/synchronisation to a much greater degree, though perhaps a memory mapping containing only the randomly-generated named pipe name is the way to go (like WCF).
Minimal repro:
Borrowed from https://stackoverflow.com/a/19326/125549:
The text was updated successfully, but these errors were encountered: