2
votes

I have a slightly complicated setup that, of course, works fine in XP, but chokes on Windows 7. It may seem like madness, but it made sense at the time!

I have a WPF application that launches and then launches another application that communicates with an external device. After launching it establishes communications with the new process using WCF (hosted by the new process) via a named pipe (net.pipe). This seems to work fine on either OS.

I wanted to make some of the functionality of the WPF application externally available to a command line program, so I set up another WCF service, this time hosted by the WPF application and again exposed it via named pipes. Again, this seems to work.

Next, I wanted to make the functionality of the WPF application available via the web. Now, it's important that the WPF application be runnable from a regular user account, so I thought the best way to make this work on Windows 7 would be to create a windows service that would provide the web service part and have it communicate back to the WPF application via the same named pipe that works fine for the command line. I implemented this and it runs fine on XP, but it chokes on Windows 7. The problem seems to be with trying to establish the named pipe connection between the windows service and the WPF application.

If I run the WPF app as an administrator, it works fine. So it seems to be a problem with the account that the windows service is running in can't communicate with a regular user account that is hosting the WCF service via named pipes. Is there a way to make this work? It seems a WCF service running in a regular user account can communicate using named pipes to another app running in the same account, but it seems it can't do the same thing with a different account.

Oddly, the reverse seems to work. The windows service does, in fact, also expose a service with a named pipe binding (it's used as an activation function since the service is running all the time). I can connect from the WPF app to this service without any problems.

My knowledge of security is somewhat limited. Can anybody shine a light on what's going on?

2

2 Answers

3
votes

This question has been asked several times previously on SO. For example, see Connecting via named pipe from windows service to desktop app

The problem is that your user session applications don't possess the SeCreateGlobalPrivilege security privilege necessary to allow them to create objects in the global kernel namespace visible to other sessions, but only in the local namespace which is only visible within the session. Services, on the other hand, which run with this privilege by default, can do so.

It is not the named pipe object itself which is constrained to the local namespace in this way, but another named kernel object, a shared memory section, on which the WCF named pipe binding relies in order to publish to its clients the actual name of the pipe, which is a GUID which changes each time the service is started.

You can get round this constraint by reversing the roles - make the windows service application the WCF Service, to which your user session apps connect. The windows service has no problem publishing its service to your session. And connecting things up this way round makes more sense because the windows service is always running, whereas your session and its apps comes and goes as you log in and out. You'll want to define the service with a duplex contract, so that once the connection is established, the essential flow of communication over the WCF service can still happen in the same direction you originally intended.

2
votes

The applications (WPF/Console) are creating locally scoped named pipes (this happens by default when they are unable to create globally scoped pipes). My guess is that they can communicate with each other because they can see each others named pipes because they are running under the same account.

The windows service has higher privileges and can therefore create a globally scoped named pipe for the client applications to see.

You can check out a discussion on Christian Weyer's Blog.