User Profile
AharonBensadoun
Copper Contributor
Joined 4 years ago
User Widgets
Recent Discussions
How to add a timer to C# Service
Hi everyone I am new to coding in c # and trying to write a windows service in c #, my service seems to be working fine except for one thing: I try to make it run in a loop, say every 30 seconds, another program. But for the moment when I launch my service, it executes the program only once. My code: using System; using System.Runtime.InteropServices; using System.Diagnostics; // SET STATUS using System.ComponentModel;// SET STATUS using System.ServiceProcess; using System.Timers; //using System.ServiceProccess;// SET STATUS public enum ServiceType : int { // SET STATUS [ SERVICE_WIN32_OWN_PROCESS = 0x00000010, SERVICE_WIN32_SHARE_PROCESS = 0x00000020, }; // SET STATUS ] public enum ServiceState : int { // SET STATUS [ SERVICE_STOPPED = 0x00000001, SERVICE_START_PENDING = 0x00000002, SERVICE_STOP_PENDING = 0x00000003, SERVICE_RUNNING = 0x00000004, SERVICE_CONTINUE_PENDING = 0x00000005, SERVICE_PAUSE_PENDING = 0x00000006, SERVICE_PAUSED = 0x00000007, }; // SET STATUS ] [StructLayout(LayoutKind.Sequential)] // SET STATUS [ public struct ServiceStatus { public ServiceType dwServiceType; public ServiceState dwCurrentState; public int dwControlsAccepted; public int dwWin32ExitCode; public int dwServiceSpecificExitCode; public int dwCheckPoint; public int dwWaitHint; }; // SET STATUS ] public enum Win32Error : int { // WIN32 errors that we may need to use NO_ERROR = 0, ERROR_APP_INIT_FAILURE = 575, ERROR_FATAL_APP_EXIT = 713, ERROR_SERVICE_NOT_ACTIVE = 1062, ERROR_EXCEPTION_IN_SERVICE = 1064, ERROR_SERVICE_SPECIFIC_ERROR = 1066, ERROR_PROCESS_ABORTED = 1067, }; public class Service_PSTest : ServiceBase { // PSTest may begin with a digit; The class name must begin with a letter private System.Diagnostics.EventLog eventLog; // EVENT LOG private ServiceStatus serviceStatus; // SET STATUS public Service_PSTest() { ServiceName = "Test2"; CanStop = true; CanPauseAndContinue = false; AutoLog = true; eventLog = new System.Diagnostics.EventLog(); // EVENT LOG [ if (!System.Diagnostics.EventLog.SourceExists(ServiceName)) { System.Diagnostics.EventLog.CreateEventSource(ServiceName, "Application"); } eventLog.Source = ServiceName; eventLog.Log = "Application"; // EVENT LOG ] EventLog.WriteEntry(ServiceName, "Test2.exe Test2()"); // EVENT LOG } [DllImport("advapi32.dll", SetLastError = true)] // SET STATUS private static extern bool SetServiceStatus(IntPtr handle, ref ServiceStatus serviceStatus); protected override void OnStart(string[] args) { EventLog.WriteEntry(ServiceName, "Test2.exe OnStart() // Entry. Starting script 'c:\\temp\\Test.exe\\Test1.ps1' -SCMStart"); // EVENT LOG // Set the service state to Start Pending. // SET STATUS [ // Only useful if the startup time is long. Not really necessary here for a 2s startup time. serviceStatus.dwServiceType = ServiceType.SERVICE_WIN32_OWN_PROCESS; serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING; serviceStatus.dwWin32ExitCode = 0; serviceStatus.dwWaitHint = 2000; // It takes about 2 seconds to start PowerShell SetServiceStatus(ServiceHandle, ref serviceStatus); // SET STATUS ] // Start a child process with another copy of this script try { Process p = new Process(); // Redirect the output stream of the child process. p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.FileName = "PowerShell.exe"; p.StartInfo.Arguments = "-ExecutionPolicy Bypass -c & 'c:\\temp\\Test.exe\\Test1.ps1' -SCMStart"; // Works if path has spaces, but not if it contains ' quotes. p.Start(); // Read the output stream first and then wait. (To avoid deadlocks says Microsoft!) string output = p.StandardOutput.ReadToEnd(); // Wait for the completion of the script startup code, that launches the -Service instance p.WaitForExit(); if (p.ExitCode != 0) throw new Win32Exception((int)(Win32Error.ERROR_APP_INIT_FAILURE)); // Success. Set the service state to Running. // SET STATUS serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING; // SET STATUS } catch (Exception e) { EventLog.WriteEntry(ServiceName, "Test2.exe OnStart() // Failed to start 'c:\\temp\\Test.exe\\Test1.ps1' " + e.Message, EventLogEntryType.Error); // EVENT LOG // Change the service state back to Stopped. // SET STATUS [ serviceStatus.dwCurrentState = ServiceState.SERVICE_STOPPED; Win32Exception w32ex = e as Win32Exception; // Try getting the WIN32 error code if (w32ex == null) { // Not a Win32 exception, but maybe the inner one is... w32ex = e.InnerException as Win32Exception; } if (w32ex != null) { // Report the actual WIN32 error serviceStatus.dwWin32ExitCode = w32ex.NativeErrorCode; } else { // Make up a reasonable reason serviceStatus.dwWin32ExitCode = (int)(Win32Error.ERROR_APP_INIT_FAILURE); } // SET STATUS ] } finally { serviceStatus.dwWaitHint = 0; // SET STATUS SetServiceStatus(ServiceHandle, ref serviceStatus); // SET STATUS EventLog.WriteEntry(ServiceName, "Test2.exe OnStart() // Exit"); // EVENT LOG } } protected override void OnStop() { EventLog.WriteEntry(ServiceName, "Test2.exe OnStop() // Entry"); // EVENT LOG // Start a child process with another copy of ourselves try { Process p = new Process(); // Redirect the output stream of the child process. p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.FileName = "PowerShell.exe"; p.StartInfo.Arguments = "-ExecutionPolicy Bypass -c & 'c:\\temp\\Test.exe\\Test1.ps1' -SCMStop"; // Works if path has spaces, but not if it contains ' quotes. p.Start(); // Read the output stream first and then wait. (To avoid deadlocks says Microsoft!) string output = p.StandardOutput.ReadToEnd(); // Wait for the PowerShell script to be fully stopped. p.WaitForExit(); if (p.ExitCode != 0) throw new Win32Exception((int)(Win32Error.ERROR_APP_INIT_FAILURE)); // Success. Set the service state to Stopped. // SET STATUS serviceStatus.dwCurrentState = ServiceState.SERVICE_STOPPED; // SET STATUS } catch (Exception e) { EventLog.WriteEntry(ServiceName, "Test2.exe OnStop() // Failed to stop 'c:\\temp\\Test.exe\\Test1.ps1'. " + e.Message, EventLogEntryType.Error); // EVENT LOG // Change the service state back to Started. // SET STATUS [ serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING; Win32Exception w32ex = e as Win32Exception; // Try getting the WIN32 error code if (w32ex == null) { // Not a Win32 exception, but maybe the inner one is... w32ex = e.InnerException as Win32Exception; } if (w32ex != null) { // Report the actual WIN32 error serviceStatus.dwWin32ExitCode = w32ex.NativeErrorCode; } else { // Make up a reasonable reason serviceStatus.dwWin32ExitCode = (int)(Win32Error.ERROR_APP_INIT_FAILURE); } // SET STATUS ] } finally { serviceStatus.dwWaitHint = 0; // SET STATUS SetServiceStatus(ServiceHandle, ref serviceStatus); // SET STATUS EventLog.WriteEntry(ServiceName, "Test2.exe OnStop() // Exit"); // EVENT LOG } } public static void Main() { Timer timer = new Timer(); // name space(using System.Timers;) void OnElapsedTime(object source, ElapsedEventArgs e) { System.ServiceProcess.ServiceBase.Run(new Service_PSTest()); } timer.Elapsed += new ElapsedEventHandler(OnElapsedTime); timer.Interval = 5000; //number in milisecinds timer.Enabled = true; } } Help will be welcome16KViews0likes2Comments
Groups
Recent Blog Articles
No content to show