I have created a program that can also be ran as a service and it will allow me to debug it as well using the following in the Program.cs
startup file.
using System;
using System.Linq;
using System.Windows.Forms;
using System.ServiceProcess;
using System.Reflection;
using System.Threading;
using crs.Includes;
using crs.Service;
using System.IO;
namespace crs
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//Convert all arguments to lower
args = Array.ConvertAll(args, e => e.ToLower());
//Create the container object for the settings to be stored
Settings.Bag = new SettingsBag();
//Check if we want to run this as a service
bool runAsService = args.Contains("-service");
//Check if debugging
bool debug = Environment.UserInteractive;
//Catch all unhandled exceptions as well
if (!debug || debug)
{
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
if (runAsService)
{
//Create service array
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new CRSService()
};
//Run services in interactive mode if needed
if (debug)
RunInteractive(ServicesToRun);
else
ServiceBase.Run(ServicesToRun);
}
else
{
//Start the main gui
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainGUI());
}
}
#region Functions
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Exception ex = e.ExceptionObject as Exception;
string stackTrace = ex.Message + "/n";
while (ex.InnerException != null)
{
ex = ex.InnerException;
stackTrace += ex.Message + "/n";
}
stackTrace = stackTrace.Substring(0, stackTrace.Length - 2);
string msg = "UNHANDLED EXCEPTION!/n/n" + stackTrace;
//Write all log messages to a debug log
try
{
string currentDate = DateTime.Now.ToString("yyyy-MM-dd");
string debugFilePath = AppDomain.CurrentDomain.BaseDirectory + @"debugLogs\";
string debugFilename = Application.ProductName + "-debug-" + currentDate + ".log";
if (!Directory.Exists(debugFilePath))
{
//Create the debug log files directory
Directory.CreateDirectory(debugFilePath);
}
if (!File.Exists(debugFilePath + debugFilename))
{
//Create the new file
using (StreamWriter w = File.CreateText(debugFilePath + debugFilename))
{
w.WriteLine("Debug log file for " + Application.ProductName + ".");
w.WriteLine("Created on " + currentDate + ".");
w.WriteLine("");
}
}
//Write the log message to the file
using (StreamWriter w = File.AppendText(debugFilePath + debugFilename))
{
w.WriteLine(DateTime.Now.ToString() + " :: " + msg);
}
}
catch
{ }
}
private static void RunInteractive(ServiceBase[] servicesToRun)
{
Console.WriteLine("Services running in interactive mode.");
Console.WriteLine();
MethodInfo onStartMethod = typeof(ServiceBase).GetMethod("OnStart", BindingFlags.Instance | BindingFlags.NonPublic);
foreach (ServiceBase service in servicesToRun)
{
Console.Write("Starting {0}...", service.ServiceName);
onStartMethod.Invoke(service, new object[] { new string[] { } });
Console.Write("Started");
}
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("Press any key to stop the services and end the process...");
Console.ReadKey();
Console.WriteLine();
MethodInfo onStopMethod = typeof(ServiceBase).GetMethod("OnStop", BindingFlags.Instance | BindingFlags.NonPublic);
foreach (ServiceBase service in servicesToRun)
{
Console.Write("Stopping {0}...", service.ServiceName);
onStopMethod.Invoke(service, null);
Console.WriteLine("Stopped");
}
//Keep the console alive for a second to allow the user to see the message.
Console.WriteLine("All services stopped.");
Thread.Sleep(1000);
}
#endregion
}
}
Everything works as expected except for the line Console.ReadKey();
under the RunInteractive()
method. If I was to try and run this service manually in a console window I would have no issues what so ever, it runs great and waits for me to hit enter to start the service stopping process. However, when running it in the IDE it's spitting everything out to the DEBUG window and there is nothing for it to grab a ReadKey on.
How can I go about getting around this when debugging in the IDE? Is it possible to somehow force it to run in a command window when debugging in the IDE?