我正在Visual Studio 2010 Ultimate SP1中创建Windows服务应用程序。
我正在关注来自MSDN的'如何': http://msdn.microsoft.com/en-us/library/7a50syb3.aspx
我遇到了两个问题:
我无法通过服务器资源管理器启动服务 - 我的服务列在那里,但在上下文菜单中我只有两个选项:刷新和属性。尽管MSDN文档说应该有这个选项,但没有“开始”。 幸运的是,我可以通过使用服务控制管理器来避免这种麻烦。
下一步是:“在Visual Studio中,从”调试“菜单中选择”进程“。 “调试”菜单中不存在该选项。我只有“附加到流程”,但服务没有列在那里。
有人知道出了什么问题以及我应该如何调试我的应用程序?
提前谢谢。
答案 0 :(得分:2)
作为一个想法:我已经构建了很多Windows服务,并且出于众多原因之一,我没有在服务本身中创建核心代码。如果愿意,该服务本质上是“操作层”。在DLL中创建核心代码允许调试和测试该特定代码。您可以创建一个控制台或桌面应用程序,它将运行可在开发和测试阶段使用的核心代码。
就个人而言,我创建了一个服务运行器应用程序,它结合启动和停止功能捕获日志记录。我的OnStart和OnStop代码块与服务的代码块完全相同。
接下来,当您测试该服务时,您应该能够启动该服务(例如myService.exe)并附加到进程。但是,另一个注意事项是您应该使用调试版本暂停/等待服务线程(例如30秒),这样您就有时间附加到进程并且不会错过初始化代码。请记住,您必须安装您的服务,然后通过Windows服务管理器启动。
以下是您可能会指出我使用方向的一些代码。在服务program.cs文件中我使用下面的内容;然后在Service OnStart()方法中调用你的dll并运行。此外,您可以停止服务,用更新版本替换dll然后重新启动。使用C#,您也可以替换服务exe,但这些只是C#特性:在C ++中你不能。
static class Program
{
public const string SERVICE_NAME = "myService";
public const string SERVICE_DISPLAY_NAME = "My Service";
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
if (args != null && args.Length > 0)
{
foreach (string arg in args)
{
switch (arg.ToLower())
{
case "-install":
ManageService(true);
return;
case "-remove":
ManageService(false);
return;
}
}
}
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service()
};
ServiceBase.Run(ServicesToRun);
}
private static void ManageService(bool bInstall)
{
string parms;
if (bInstall == true)
{
parms = string.Format("Create {0} type= own start= demand binPath= \"{1}\" DisplayName= \"{2}\"", SERVICE_NAME,
System.Reflection.Assembly.GetExecutingAssembly().Location, SERVICE_DISPLAY_NAME);
}
else // remove
{
parms = string.Format("Delete {0}", SERVICE_NAME);
}
try
{
string output = string.Empty;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo("sc.exe", parms);
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.CreateNoWindow = true;
proc.StartInfo = startInfo;
proc.Start();
output = proc.StandardOutput.ReadToEnd();
proc.WaitForExit(10000);
if (proc.HasExited == true)
{
// NOTE: The project type has been changed from Windows Service to Console Application
// so that Console.WriteLine will output to the console
Console.WriteLine(output);
}
else
{
proc.Close();
Console.WriteLine("Timed out waiting to install service");
}
}
catch (System.ComponentModel.Win32Exception)
{
Console.WriteLine("Unable to locate sc.exe");
}
}
}
答案 1 :(得分:0)
//From the main function a method from service class can be called like below code
//DebugApp method can be called from main and so the service can be debug:
//Service class
public partial class CServices : ServiceBase
{
public CServices()
{
InitializeComponent();
}
**public void DebugApp()
{
OnStart(new string[]{});
}**
protected override void OnStart(string[] args)
{
System.Console.WriteLine("Testing");
System.Console.Read();
}
protected override void OnStop()
{
}
}
//Calling from main:
static void Main()
{
Services1.CServices uc = new CServices();
uc.DebugApp();
}