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?
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.
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.
Related
Azure VM, Cloud service or Web job?
I have a configurable console application which runs continuosly. Currently it is running on a VM and consumes lot of memory (it is basically doing data mining).
The current requirement is to have multiple instances of this application with different set of configuration which can be changed by specific users.
So where should I host this application such that the configuration can be modified using some front end which provides access managements(like Sharepoint),ability to stop it/restart (like WCF service) without logging on the VM?
I am open to any suggestions/ideas. Thanks
I don't think there's any sold answer to this question as there is the preference variable but for what it's worth, if it were up to me I would deploy it against individual azure VM's for each specific set of users. That way if the server resources went up because of config changes the user group made it is isolated to that group, and with azure, will scale automatically to meet the resource demand. Then just build a little .net web app to allow user to authenticate and change configuration settings.
You could expose an "admin" endpoint for your service (obviously you need authentication here!) that:
1. can return the current configuration
2. accept new configuration
3. restart the service (if needed). Stopping the service will be harder, since that leaves the question on how to start it again.
Then you need to write your own (or use a 3-party (like sharepoint or a CMS)) application that will handle your users and under the hood consume your "admin" endpoint.
Edit: The hosting part: If I understand you correctly your app is just an console application today, and you don't know how to host it? Well, there are many answers to that question. If you have a operations department go talk to them, if you are on your own play around and see what fits you and your environment best!
My tip: go for a http/https protocol/interface - just because there are many web host out there, and you can easy find tools for that protocol. if you are on the .NET platform check out Web.API or OWASP
Azure now has Machine learning to process data mining.
You should check if it's suit to you.
Otherwise, you can use Webjob:
Allow you to have multiple instances of your long time running job (Webjon scaling out).
AppSettings can be change from the Azure Portal or using the Azure Management API
I have a web service that will only be called from the same box. In IIS 7 I have used named pipe endpoints for security and speed. the project I am working on now has the same requirements but will be on server 2003 IIS 6. What are my options to restrict access to only the local machine? Thanks!
IIS6 only supports http and wshttp protocols. You could run your WCF in a Windows Service and control everything as you do now (however that may be). There are tons of ways to secure it as well.
Self Signed certificates between the two (popular over the internet)
Windows Authentication and control list (easy on same network/domain)
UserName Password (also easy).
But if you have it working now, I would attempt to rehost into a Windows Service, which should not take away your current functionality.
You should know by the way that if use named pipes over a network, it is actually just remoting via TCP.
i am new in wcf and started learning. i got one confusion like that i create a small wcf service and just do not host it in IIS,console apps or win service but from another apps i can add the service reference of svc file and found it is working. if wcf can work without hosting in any place like "IIS,console apps or win service " then why people would alway host wcf service in IIS,console apps or win service. can anyone tell me the reason.
people use IIS and windows services in general because they are simpler to setup and run more consistently. they can also be hosted more easily on servers where the services can be configured to start automatically, and as usually wcf is used as a server communication method it is usually this that you want to do.
hosting in console applications is generally easier to setup for simple examples for testing purposes, when you want to test your services locally.
Whilst hosting in applications as possible it's a less common scenario to use wcf to communicate between 2 applications on the same machine.
EDIT:
Your original question asked why people always talk about IIS, services etc. The point I was making was that usually wcf is used for web services, and is usually run on a server other than the local machine. Even though it can be used for inter process communication on the same machine this is not the most common use case. This is why you see a lot of examples using IIS and not too many hosting it in a Windows forms app.
Here is a question for WCF hosting environment:
You are developing an application that performs file backups in the
background. The background application will host a Windows
Communication Foundation (WCF) service and must be active as soon as
the machine is running. The background application will not have a
user interface. A front-end application will consume the WCF service
and will provide the user interface.
You need to choose a host environment for the WCF service. Which
hosting environment should you choose?
A. Microsoft Internet Information Services (IIS) 6.0
B. Windows Process Activation Services (WAS)
C. A Windows Forms application
D. A Windows Service
The answer is D, but a lot documents of WCF MSDN and books all favor IIS/WAS over Windows Service, as they are more robust and resilient etc. I don't really see why it has to be D here. What is the reasoning behind D then?
The answer is D, because one of the requirements is:
must be active as soon as the machine is running.
When you use Windows Service you can start it even before user has authorized in system.
IIS gives on-demand loading. When a request comes in, the ServiceHost is constructed, then the service class being hosted is instantiated, and the request is handled. Nothing needs to be running around the clock. This setup requires more time and effort every time a message comes in.
Kindly help me in architecting a solution which is required for my ongoing project.
I have developed some WCF Services hosted as windows services which I did and working fine so far. Now I am asked to develop a master WCF type of service which should be intelligent enough to manage all other WCF service for possible corruption/errors and can repair them and restart.
Thanks in advance.
As we have written a custom host and took us years to make it a real application server, I will share some of the challenges that we had. Creating a custom host that manages WCF services as an NT service is a very challenging task if you want to manage all of the details and treat the NT service as a real service host. The challenges start from managing multiple Appdomains ( one for each Service ), managing the statuses of the services, startup times, deployments from the IDE and the worst of all is activation. Have you considered how to implement that? If you do not have this feature, it means that all of your services will be active and in memory at all times. IIS and Appfabric do that very well and trust me , it is noty easy to implement. The other part that was challenging was a UI to manage this host and offcourse a UI that can manage multiple hosts ( NT services running on different boxes ). Do you need a discovery proxy implementation? And at last how about if you want to manage services running in your custom host , IIS and App fabric the same way?
Think about before doing such an implementation because the scope may crypt on you as you do it.
I do something similar here.
Create a Dictionary<key, ApplicationDomain> collection into your main program
Key: something unique for each application domain, like a Guid or a System.Type.
That ApplicationDomain class exposes a internal property to access your AppDomain proxy (that which inherits a MarshallByRef class)
Load your WCF host into main program, so you'll get access to that collection
Every time your service get some access, you just need to take that key, access your proxy and do anything you want within your service hoster.
Keypoint: Your service must have access to all your service hosts.