Migrating existing Windows service to Service Fabric - c#

Recently, I have encountered an issue where I want to make my existing Windows service to run in a SF cluster.
However, this service does some registry operations, and it is dependent on it.
At SF, this is meaningless (as the service can be shutdown and re-run on another node). What are my options to make a smooth transition?
Use DB instead of a registry? Any other ideas (as in some cases the service stores data in the registry in case an error will occur in DB)?

You could just create a Stateful service for this. The Service would store the (registry) values in a reliable dictionary. This way the state would always be available to the service.

Related

azure cache on localhost

I'm developing an application to run in azure.
I'm making use of the azure cache, however when I run this locally I don't want to connect up to Azure to use the cache because it's a bit slow and tedious.
Can you run the cache locally?
[EDIT]
This is .Net C#
Unfortunately, you do need to connect to azure to test the windows azure cache service. Read this for more info: http://msdn.microsoft.com/en-us/library/windowsazure/gg278342.aspx
You can use Windows Server AppFabric Cache when local debug. It utilizes very similar configuration and program mode, which means almost all you need to change is the cache server IP and access token.
But I'd better to create a separated Cache layer to isolate the cache operations. For example introduces ICache interface with Add, Get, Remove, etc. methods. Then you can implement the Azure Cache, Memcached, In-Proc Cache, etc. in vary cases.
There's a good cache layer you might be interested in, check the ServiceStack project at GitHUB https://github.com/ServiceStack/ServiceStack/tree/master/src/ServiceStack.Interfaces/CacheAccess
It's not possible. To use the windows azure caching service locally, you'll always have to route your request to azure, which adds a serious delay on top of the request.
To property test your cache, you need to deploy your service in azure.
As others said, you can use Windows Server AppFabric caching locally, but be warned, there are some differences between the Windows Server AppFabric caching and the Windows Azure caching service, like for example the notifcation based invalidation on local cache items is not supported in azure. Make sure not to use any of these features while developing locally, or you might get surprised when deploying your service to the cloud.
Only the timeout based invalidation on local cache is supported for the windows azure caching service. Windows azure caching service is designed to be used for your cloud services, so it makes sense it's kinda crappy when using with on on-premise application.
Azure AppFabric caching uses a subset of the functionality of Windows Server AppFabric caching. If you're willing to setup a server in house with the cache installed you could probably get something comparable to using the Azure cache. I haven't tried this myself, so while I know that the code you'd need to write is more or less the same between the two, I'm not sure how different the configs need to be.
Chances are though that it's going to be a lot less time and effort to just use the Azure cache.
This article specifically talks about what you are trying to do. Create a caching "infrastructure" that switches between local and distributed cache based on configuration(s):
http://msdn.microsoft.com/en-us/magazine/hh708748.aspx
Now you can use azure in-role cache and try locally using emulator

IIS vs Windows Service?

I have a C# application that needs to always be running. I originally planned on making this a windows service but I now have a requirement to make the application host a web admin console.
I haven't played with IIS in quite a few years so my question is this:
What would you recommend I use?
I've thought about making a windows service and embedding a web server such as Cassini but so far I'm not very happy with the open source web servers I've looked at.
Can IIS handle this? Do people use it for this type of scenario, and if so how?
This sounds like a job for two separate projects.
One is the original Windows Service. Windows Services are well suited for what you're doing.
The second is the Web Project that will be used to administer the Windows Service. This is the part that runs in IIS.
It depends on what you mean by always running. An ASP.NET web application deployed in IIS could very well be unloaded by the web server if there aren't any requests for certain amount of time killing all background threads. So if you want an ever running background thread it would be better suited to use a Windows Service. As far as the web admin is concerned, well, here you don't have much choice: ASP.NET in IIS. In order to do something useful those two applications should be able to find a common language to talk. So you could use a database to store the results into which could be used by both applications.
IIS will run your app on first request, not on server boot. So you will still need to run a service to ensure your app is always running.
You can use IIS as a webserver for your web admin part, and link your ASP.net app with your service by means of a configuration database (easy) or webservices (a little more tricky).
Windows and Web services are two very different creatures. A web service will expose external methods that you can implement against an application, while a windows service is an entity within itself. If you're planning on using this service on a timed interval to perform an operation, a Windows service would be the right way to go. If you use a web service, you will need to invoke the method you wish to run from a secondary application.
If you need to queue commands against your windows service, you could always create a database that was accessible by both your website and your windows service. This way you could send commands and query data between the two. Placing a web service in to serve as an intermidary between the two may be overkill.

Call A Windows Service from a remote computer

I am going to be coding up a windows service to add users to a computer (users with no rights, ie just for authentication). (As a side note, I plan to use this method.)
I want to be able to call this windows service from another computer.
How is this done? Is this a tall order? Would I be better off just creating a Web Service and hosting it in IIS?
I have some WCF services hosted in IIS on the calling computer (they will do the calling to the proposed windows service). I have found that Hosting in IIS is somewhat problematic, so I would rather not have a second IIS instance to manage unless I need to.
(I will be using Visual Studio 2008 SP1, C# and Windows Server 2003 (for both caller and service host).
Thanks for the help
If you are thinking of hosting a web service in IIS just to communicate with an NT-service on that same machine, that is definitely more trouble than it is worth in this case.
As other answers have indicated you can make a WCF service with the operations you need and host that within the same NT-service that you want to interact with. You can easily secure this with certificates, or user accounts to make sure it is only controlled by the right people/machines.
If you need to control the NT-service itself, there are existing programs such as sc.exe to start, stop, configure, or query the status of your NT-service remotely.
However, you may want to consider seeking a solution without the overhead of creating an custom NT-service and a custom WCF service to interact with it. If you do, the Net User commands (sorry no link - new user limitation) or the AddUsers (see kb 199878/en-us) utility may be sufficient. If your remote "controller" can invoke these commands directly against the target machine you may not have to create any custom software address this need. Additionally you would have less software to maintain and administer on the target machine. You would just be using the built-in OS capabilities and admin utilities.
Finally, you will need to think about the security aspect, NT-services and IIS are usually run under very restricted accounts, many auditors would flip-out over any service running with sufficient permission to create or modify users locally, and especially on other machines. You'll want to make sure that the service could never be used to create users that do have more than the "authenticate" permission you indicated.
Edit: The net user command may not work against another machine's local users, but check out. pspasswd that along with PsExec to create users, should do what you need remotely.
Simply host a WCF service in the Windows Service. You'll then be able to call it remotely.
You can host a WCF service inside a Windows service. Take a look at the TCP binding (NetTcpBinding class). Both client and server will have to use WCF, but that doesn't sound like it will be an issue with your implementation.
Also, the section entitled "Hosting in Windows Services" in this MSDN article provides a walk-through of the process
If the windows service publishes a remoting interface then it can be accessed via that remoting interface.
Otherwise it's the same as accessing any other process running on a remote machine except that there may be some tools (e.g., sc) with built in support for executing against a remote machine (barring firewall complications).
Any IPC mechanisms applies; sockets, web services, remoting, etc...
You could expose a WCF service directly from your windows service. When you start up your windows service, in addition to spinning up any other background processes, you could create an instance of ServiceHost<T> for your service implementation. This would allow you to not only provide WCF access, but also avoid the extra instance of IIS like you requested, and provide TCP, Named Pipes, and WsHttp endpoints. This should give you some nice flexibility in the performance tuning arena, since it sounds like this service will be consumed internally on your network, rather than externally.
You could create a WCF service which will talk to your Windows service on the remote box. Host the WCF component in IIS (or however you'd like so that you can communicate with it) and then call the WCF component from your remote machine.

Querying a Windows Service over a Network

I have written a windows service in C# that gathers performance, disk and memory information and writes it to the EventLog. It is enabled as a network service. What I would like to do is be able to gather this information from a remote location. This service will run at various client machines and I would like to retrieve this information periodically (once a day) and store them in a database table. I am confused as to how one can query a windows service over a network. In other words, what exactly makes the service a "Network Service"?
I do not want the service to directly connect to my database and write this information. But I would like to initiate it from a remote machine, retreive the information and then write that information to my database table.
I was unable to find any tutorial that illustrates a networked windows service. Most of them covered writing to event logs and I am pretty much stuck there.
Is this doable, are there any suggestions about how this sort of stuff is done?
If the other suggestions to move over to WCF Web services are not an option, you can do allot with Custom commands in a windows service without having to resort to remoting.
Effectively you can send an integer between 128 & 256 and then have your service execute whatever code you need it to when it receives that command, like sending all the information to your database or web service.
You will be able to initiate it from your side as and when you need to while the service happily trundles along on the client machines.
Take a look at this code project article for an example: Creating a Basic Windows Service in C#
Take a look at the OnCustomCammand method.
Here's another example article from Microsoft: Communicate With Windows Services
Use WCF to enable some form of a RESTful Web Service.
See wcf-getting-started on MSDN, and specially A Guide to Designing and Building RESTful Web Services with WCF.
AFAIK 'Network Service' just means that it is running under the "Network Service" account which has a different set of permission than the 'Local Service' or 'System' accounts.
To expose a service to another machine on the network however (apart from the standard STOP, START, RESTART functionality that you get through the services snap-in - services.msc) you will need to create your service using something like Remoting, Webservices or most ideally as gimel mentioned WCF.

Passing a Windows Service Parameters for it to act on

I want to turn a program I have into a service so I can use it without logging it. Basically what it does is it backs up specified folders to a specified location using SSH. However the problem I'm running into is I don't know how to tell it these items. I only know how to start, stop, and run a custom command with only an integer with a parameter.
How can I do this?
Windows Service, not a Web Service
edit: The folders it backs up will not remain consistent and will be updated at every runtime
You can instantiate your service and pass command line arguments using the ServiceController class.
using (ServiceController serviceController = new ServiceController(serviceName))
{
string[] args = new string[1];
args[0] = "arg1";
serviceController.Start(args);
}
"arg1" will then be available as regular command line arguments in main() when Windows starts up the service.
I see that you (or someone) voted Sebastian Sedlak's answer down, because he mentioned hosting a WCF Service in the Windows Service. Your reply was
It's in nice bold lettering in the question. Not a Web Service, therefor WCF is out of the question
I think you misunderstood what he meant. He wasn't talking about a Web Service. He was talking about hosting a WCF Service within your Windows Service.
It's far from the same thing. You can host a WCF Service within any Windows (Forms/Console/Service) application. The point of doing so, is that the application is then reachable for communciation via its internal WCF Service, in the same fashion as you can communicate with a Web Service (you can also host WCF Services in IIS, btw, which would then make them "Web Services", in the sense you seem to be referring to).
In a Windows Service, this means you can send any command to it and also get any information you want from it - while it's running.
In fact, I am working on a project right now, which is a Windows Service that I need to be able to contact and pass commands to - and get information from - at runtime. For example, I want to be able to tell it where to store certain things, what to log, to have it reset/restart - and poll it for status messages. I do this by hosting a WCF Service inside the Windows Service. That WCF Service exposes a set of methods, that in my case includes receiving commands and returning status information. So when the Windows Service is running, I can contact it (even remotely), via its built-in WCF Service and tell it what to do.
This an extremely easy thing to implement, and in the case of Windows Services, can provide you with a much richer interface to the Service than through the basic standard commands.
However, you specified that you wanted your Windows Service to receive its folder settoings each time it starts up, which makes such a passive setup less than ideal (as it would be unable to do anything until you passed it the right folders).
One way to deal with this (using a hosted WCF Service), would be to have the Windows Service running all the time (i.e. automatic startup). Its default state would be idle. Then you could issue it a "start processing"-command, feeding it the correct folders to work on (through a call to the corresponding WCF Service method). Similarly, the WCF Service would expose methods giving you the status of the application (current folder, progress, busy/idle etc). Once the processing is done, it would go back into the idle state, waiting for the next set of folders to be supplied to it.
Doing it this way would make it very easy to control remotely - you could even make an online administration panel for it, accessible from anywhere.
The issue, is that, while passing in parameters is not difficult, when the machine restarts and windows tries to restart the service, those parameters are not there. they only exist when someone starts the service from the command line.
for example. I have a windows service which hosts a WCF service. I want the users to be able to specify a non-default port number for the WCF service to listen on. They do this by starting the windows service like so... MyService -port:xxxxx
Which works fine, until the server is rebooted, then windows restarts MyService (but without parameters) and the wcf service defaults to original port #
Any service is capable of receiving command line arguments at start-up.
Would it be possible to use a configuration file to specify these items?
Store the service's startup parameters in the registry: and then, when the registry starts, it should read its startup parameters from the registry.
Windows services have executables like any other. I believe you can write it to accept command-line parameters and specify those parameters in the Windows Service configuration. You can also have it read a config file. If you're using .NET, there are config file classes in the framework.
Why not just Host a WCF Service in the Windows Service to obatain such "admin" functions?
(Remoting is also possible)
RE: config file.
Of course a config file can be used.
And the file can be changed while the service is running.
This would be a nice solution if the config file changes in fact.
All my services use an XML config file, wrapped in a class for easy reuse.
The wrapper has an option to monitor the XML file using fileMonitor for changes, optionally refreshing the content of the config file automatically, and finally raises an event to the service class.
The service then has the option of "resetting" itself as needed to incorporate the new values in the XML configuration file.
Placing configuration into the registry has a few issues:
Security (ie: installer being granted access), depending on what tree is used
The service will not be aware of changes
Portability - although minor as the install should setup registry settings
Where an XML file is easy to copy, edit, share, view and understand.
Throw in some good COMMENT blocks and a detailed XSD file, and it becomes a source of good documentation too.
Look into XPath for easy navigation and extraction of values within the XML file.
$0.02
... david ...
Concerning the app.config file - I'm rather sure that your service will read and use those files as I write all my windows-services this way ;)
So just put everything you need in the app.config under "application" (not user) and put allway edit the "yourname.exe.config" in the folder where you "InstallUtil" the service from.

Categories