I've used a simple windows service to make a method work in specific time and it works fine. Following that I've already tried:
protected override void OnStart(string[] args)
{
this.WriteToFile("Simple Service started {0}");
this.ScheduleService();
}
protected override void OnStop()
{
this.WriteToFile("Simple Service stopped {0}");
this.Schedular.Dispose();
}
private Timer Schedular;
public void ScheduleService()
{
try
{
Schedular = new Timer(new TimerCallback(SchedularCallback));
string mode = ConfigurationManager.AppSettings["Mode"].ToUpper();
this.WriteToFile("Simple Service Mode: " + mode + " {0}");
//Rest of the code here
}
catch(Exception ex)
{
WriteToFile("Simple Service Error on: {0} " + ex.Message + ex.StackTrace);
//Stop the Windows Service.
using (System.ServiceProcess.ServiceController serviceController = new System.ServiceProcess.ServiceController("SimpleService"))
{
serviceController.Stop();
}
}
}
This is done in a simple windows application. So what I am trying to do is to call a web service (A specific method to operate in a specific time) in a windows service. The application I am building is web-based and am little bit confused how would I integrate the windows service into it? Do I need any alternatives or any suggestions would be appreciated.
Note: What I would like to know is it required to create another project for windows service in the web application or any other way to implement?
To call a web service from a Windows Service application, you would first generate a DLL from that web service, then instantiate its namespace. Assuming you have the code for that web service and/or know its namespace, you can perform these commands to do this:
Perform these lines on a command line:
cd C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools
wsdl /l:CS /protocol:SOAP %svc%?WSDL
where %svc% is the URL for your web service, i.e. http://localhost:777/MyWebService.asmx
If the code is in VB instead of C#, change /l:CS to /l:VB.
This will output a proxy class file that can be converted to a DLL.
Move the MyWebService.cs file from C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools to the C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ directory.
Run these two commands on the command line:
cd C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
csc /t:library %name%.cs /reference:System.Web.Services.dll /optimize
where %name% is the name of the class (without the .cs, since the command will append this). In our case, we'd use MyWebService. (Change .cs to .vb for a VB class.)
Navigate to C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 via Windows Explorer. You should see a DLL created in that folder with the name of the class (MyWebService.dll). Copy this file to the bin folder of your Service project. You will need to set the bin folder to be included in your project, and right-click the folder to Add > Existing Item. Select the DLL. Once imported, select the DLL and change its properties to:
Build Action: Content
Copy to Output Directory: Copy if newer (or Copy always, as you prefer)
Right-click References > Add References. Navigate to the DLL in the bin folder for your web service.
Right-click References > Add Service References. Assuming your web service is running, take its full URL (i.e. http://localhost:777/MyWebService.asmx) and put that on the Address line. In the Namespace textbox, give it something more meaningful than ServiceReference1, but it should not be the same as MyWebService (the name/namespace of the ASMX file). Perhaps MWS.
Instantiate your web service in your Windows Service:
MWS.MyWebServiceSoapClient webService = new MWS.MyWebServiceSoapClient();
webService.Open();
string someDataYouWant = webService.SomeMethodToGetData();
webService.Close();
Or you can probably do:
MyWebService webService = new MyWebService();
string someDataYouWant = webService.SomeMethodToGetData();
webService.Dispose();
In answer to your query on my comment;
Another approach is to use an IIS Auto-Start website contaning your Windows Service logic. The IIS Auto-start is supierior to using a Windows Service as it contains all the IIS application hosting logic including auto-restart, and aggressive resource management. A poorly written Windows Service can take down a Server but it takes a lot for an ASP.net IIS hosted application to take down its host (its almost impossible).
Your Auto-Start website need not be visibile to the outside world - it just needs to have an internal timer that keeps it alive when it starts up. Note that the web application might be started and stopped by IIS for various reasons; but the outcome is that it will be running whenever your other web service application is running. The internal timer can wait for a specific time to execute the logic you need to call your second web service.
The key thing to remember is that a Windows Service is designed to be an application that is hosted by Windows and is continually running. An IIS application is designed to be run by Windows but runs only when called. The IIS Auto-Start website concept allows you to provide a "continually running" website but hosted by the robust IIS application hosting components, instead of it running directly as an OS process.
Generally people dont do this because either they dont know about it, or want to avoid needing the IIS infrastructure to run "Windows Service" type applications, but in your case you have already paid the cost of using IIS to host your second web service, so you may as well make full use of IIS (and avoid the second technology stack and deployment headaches of Windows Service deployment).
So I suggest using an IIS Auto Start in preference to a Windows Service in your situation because;
You only need to use on tech stack in your solution, which was what your OP was asking about
IIS carries out active resource management on all its applications, terminating, restarting as neccessary if they become non-functional. Windows Services do not have that capability.
Your IIS based service code is XCOPY deployable with no administrator access credentials on the target machine.
Your IIS service is hot upgradeable without needing OS level administrator rights - IIS handles the stopping and restarting on upgrade without you needing to do anything.
I have written a service in C#. I kept the DLLs of my service in c:\windows\system32\myservice.dll. I have done the necessary registry changes for hosting in svchost.exe, but my service is not being executed. It gets a 1053 error code.
The following is the registry entry for myservice. I created a key and have given the path of the myservice.dll file.
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\svcsvc2]
"Type"=dword:00000010
"Start"=dword:00000002
"ErrorControl"=dword:00000001
"ImagePath"=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,\
74,00,25,00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,73,\
00,76,00,63,00,68,00,6f,00,73,00,74,00,2e,00,65,00,78,00,65,00,20,00,2d,00,\
6b,00,20,00,4c,00,6f,00,63,00,61,00,6c,00,53,00,65,00,72,00,76,00,69,00,63,\
00,65,00,00,00
"DisplayName"="#%SystemRoot%\\system32\\svcsvc.dll,-200"
"ObjectName"="NT AUTHORITY\\LocalService"
"ServiceSidType"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\svcsvc2\Parameter]
"ServiceDll"=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,\
00,74,00,25,00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,\
73,00,76,00,63,00,73,00,76,00,63,00,2e,00,64,00,6c,00,6c,00,00,00
"ServiceMain"="Main"
1053 is ERROR_SERVICE_REQUEST_TIMEOUT
The service did not respond to the start or control request in a
timely fashion.
StartServiceCtrlDispatcher was not called?
You also have type set to SERVICE_WIN32_OWN_PROCESS, not SERVICE_WIN32_SHARE_PROCESS.
And please respect this note from MSDN:
Note that Svchost.exe is reserved for use by the operating system and
should not be used by non-Windows services. Instead, developers should
implement their own service hosting programs.
svchost doesn't host the .NET framework, so is not able to execute your .NET assembly.
.NET services run with their own applications (.exe).
Why not creating a Setup Project in VS that installs your service?
Unless you want to install a service programatically, I would advise you to read this article.
I have a web service application in C#. When I run the Debug in Visual Studio, it starts the service at http://localhost:###### and shows the Default.htm page with links to test the different calls that can be made to the web service.
Is there a way to call this locally running version to test it from another computer? I tried making a call that the links on the test page make, but replaced localhost with the IP address of the machine running it, but it said that it could not connect to the server.
The embedded Visual Studio web server (Cassini) is only accessible from the local machine. If you want to use the web service from a different computer, you will need to deploy the service to IIS and then you'll be able to get to it at http://xxx.xxx.xxx.xxx/MyWebService/MyWebService.asmx (replace xxx with your IP Address and MyWebService with the appropriate IIS web site path).
Then to create a test application, you can create either an ASP.NET website or WinForms/Console application and import a Web Service reference in Visual Studio. That will build the proxy classes for you automatically and make calling the service very easy.
Just wrap your service in a console application so it can be accessed.
Create a new console application project in your solution, naming it something that makes sense (If your service is named MyService maybe MysServiceConsoleHost or some facsimile).
Include a reference to the service project in this project.
In your new project (program.cs) have something like the following:
using System;
using System.ServiceModel;
class Program
{
static String TITLE_TEXT = "MyService -- Console Host ({0})" + (System.Diagnostics.Debugger.IsAttached?" [DEBUG]":"");
static void Main(string[] args)
{
Console.Title = String.Format(TITLE_TEXT, "Not Running");
try
{
ServiceHost host = new ServiceHost(typeof(MyService));
Console.Title = String.Format(TITLE_TEXT, "Starting");
host.open();
Console.Title = String.Format(TITLE_TEXT, "Running");
Console.WriteLine("Service is started, press any key to exit.");
Console.ReadKey();
Console.Title = String.Format(TITLE_TEXT, "Closing");
host.close();
host = null;
Console.Title = String.Format(TITLE_TEXT, "Closed");
}
catch (Exception ex)
{
Console.Title = String.Format(TITLE_TEXT, "Exception");
Console.WriteLine("An error occured while running the host:");
Console.WriteLine(ex.Message);
Console.WriteLine();
Console.WriteLine(ex.StackTrace);
Console.ReadLine();
}
}
}
Replace the instances of MyService as necessary, then run it. Make sure you have a .config file that specifies the endpoints of your service, port to run on, etc. Then anyone can access your service and, if necessary, you can debug through the service during live calls.
A really simple solution to this is to use localtunnel:
http://progrium.com/localtunnel/
It will set up a proxy that will point to your localmachine and can be accessed outside of your machine.
If you are using Visual Studio's built in web server (Cassini) then this can only be called locally. If you want to connect remotely you will have to install IIS and configure your project to use it.
Yes and no. If you are using the built in ASP.NET dev server (most likely, since you have :####), I don't believe that can be contacted externally.
But, you can "deploy" to the local IIS instance and it then can be hit from other computers. Web Service Studio is a good test tool for web services. There are also some really good open source tools out there. I like SoapUI myself.
I can test the webservice on localhost. I have a windows CE Motorola terminal, connected to my computer. I have VS2008 on the computer.
My computer address is xxx.xxx.x.xxx and webserver is localhost:62209, so at the terminal i use webservice address: http://xxx.xxx.x.xxx/62209/MyWebservice.asmx and it works.
Maybe because the terminal is connected directly to the computer wher the webserver runs?
Anyway, it works.