在控制台模式下运行 Windows 服务? [英] Running a Windows Service in Console mode?
问题描述
我发现一些示例代码发布在https://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/4d45e9ea5471cba4/4519371a77ed4a74?hl=en&pli=1用于自行安装 Windows 服务.我在 fx 4.0 上使用 C#.试找出我在哪里出轨...
我的问题:
- 我创建了一个 Win Service 项目.在 program.cs/main() 我几乎复制代码示例.看起来大多数东西都在工作除非如果我处于调试模式(传入 -c当然).出于某种原因,控制台窗口永远不会打开.
- 我遇到的另一个挑战是调用 StartUp()/ShutDown()控制台部分将无法编译.我最终必须初始化我的服务对象,然后调用它.
- 调用 Console.ReadKey() 方法时出现以下错误:
<块引用>
在以下任一情况下都无法读取密钥应用程序没有控制台或当控制台输入被重定向时从一个文件.试试 Console.Read.
我的代码和东西:
我的项目结构图:
注意:当我在 TestHarness 中复制启动序列时在调试模式下.如果/当我开始工作时,我会放弃它从解决方案.图书馆项目是我大部分工作的地方代码活着.
程序.CS
使用系统;使用 System.Collections.Generic;使用 System.Linq;使用 System.ServiceProcess;使用 System.Text;使用 System.ComponentModel;使用 System.Configuration.Install;使用 System.Collections;使用 RivWorks.FeedHandler.Service;命名空间 RivWorks.FeedHandler{静态类程序{///<总结>///应用程序的主要入口点.///</总结>静态 int Main(string[] args){bool install = false,uninstall = false,console = false,rethrow = false;尝试{foreach(args 中的字符串 arg){开关(参数){案例-i":案例-安装":安装 = 真;休息;案例-u":案例-卸载":卸载 = 真;休息;案例-c":案例-控制台":控制台 = 真;休息;默认:Console.Error.WriteLine("不需要参数:" + arg);休息;}}如果(卸载){安装(真,参数);}如果(安装){安装(假,参数);}如果(控制台){Console.WriteLine("开始...");FeedListener fl = new FeedListener();fl.StartUp();Console.WriteLine("系统运行;按任意键停止");Console.ReadKey(true);fl.ShutDown();Console.WriteLine("系统停止");}否则如果(!(安装||卸载)){重新抛出 = 真;//以便窗口看到错误...ServiceBase[] services = { new Service.FeedListener() };ServiceBase.Run(服务);重新抛出 = 假;}返回0;}捕获(异常前){如果(重新抛出)抛出;Console.Error.WriteLine(ex.Message);返回-1;}}静态无效安装(布尔撤消,字符串 [] args){尝试{Console.WriteLine(undo ? "uninstalling" : "installing");使用 (AssemblyInstaller inst = new AssemblyInstaller(typeof(Program).Assembly, args)){IDictionary state = new Hashtable();inst.UseNewContext = true;尝试{如果(撤消){安装卸载(状态);}别的{安装(状态);inst.Commit(状态);}}抓住{尝试{安装回滚(状态);}抓住 { }扔;}}}捕获(异常前){Console.Error.WriteLine(ex.Message);}}}[运行安装程序(真)]公共密封类 MyServiceInstallerProcess : ServiceProcessInstaller{公共 MyServiceInstallerProcess(){this.Account = ServiceAccount.NetworkService;}}[运行安装程序(真)]公共密封类 MyServiceInstaller : ServiceInstaller{公共 MyServiceInstaller(){this.Description = "提供一个服务来监听,然后从各种来源导入、馈送文件.";this.DisplayName = "RIVWorks Feed Handler (.NET 4.0)";this.ServiceName = "FeedListener";this.StartType = System.ServiceProcess.ServiceStartMode.Automatic;}}}
FEEDLISTENER.CS
使用系统;使用 System.Collections.Generic;使用 System.ComponentModel;使用 System.Data;使用 System.Diagnostics;使用 System.Linq;使用 System.ServiceProcess;使用 System.Text;使用 System.IO;使用 sysIO = System.IO;使用 RivWorks.FeedHandler;使用 System.Collections;使用 RivWorks.FeedHandler.Library;使用 System.Threading;命名空间 RivWorks.FeedHandler.Service{公共部分类 FeedListener : ServiceBase{#region 声明静态私有列表_keys = new List();静态私有 System.Threading.Timer _clock = null;静态私有 FileSystemWatcher _watcher;静态私有 RivWorks.FeedHandler.Library.QueueHandler _qHandler = null;静态私有 bool _isDequeueing = false;#endregion#region 构造函数公共 FeedListener(){初始化组件();}#endregion#region 内部方法内部无效启动(){...}内部 void ShutDown() {...}#endregion#region 开始/停止受保护的覆盖无效 OnStart(string[] args){启动();}受保护的覆盖无效 OnStop(){关掉();}#endregion#region 事件处理程序静态无效 qHandler_QueuesGrew() {...}静态无效 qHandler_QueuesShrunk() {...}静态无效 qHandler_QueuesChanged() {...}static void fileCreatedOrChanged(object sender, sysIO.FileSystemEventArgs e) {...}#endregion#region 私有方法私有静态无效滴答(对象状态){...}private static void WriteToEventLog(Exception ex, EventLogEntryType eventLogEntryType) {...}private static void WriteToEventLog(string message, EventLogEntryType eventLogEntryType) {...}#endregion}}
我找到了答案!我的项目属性设置为 Windows App 而不是 Console App.哦!(项目属性 > 应用程序选项卡 > 输出类型:)
I found some sample code posted at https://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/4d45e9ea5471cba4/4519371a77ed4a74?hl=en&pli=1 for self installing a Windows Service. I am in C# on fx 4.0. Trying to figure out where I went off the rails...
My questions:
- I created a Win Service project. In program.cs / main() I pretty much copied the code example. It appears most everything is working except launching a console window if I am in DEBUG mode (passing in - c of course). For some reason the console window never opens.
- The other challenge I had was the call to StartUp() / ShutDown() in the console portion would not compile. I ended up have to initialize my service object and then call it.
- I am getting the following error when the Console.ReadKey() method is called:
Cannot read keys when either application does not have a console or when console input has been redirected from a file. Try Console.Read.
My code and stuff:
An image of my project structure:
NOTE: I was duplicating the startup sequence in the TestHarness when in DEBUG mode. If/when I get this working I will be dropping that from the solution. The Library project is where the majority of my code lives.
PROGRAM.CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.ComponentModel;
using System.Configuration.Install;
using System.Collections;
using RivWorks.FeedHandler.Service;
namespace RivWorks.FeedHandler
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static int Main(string[] args)
{
bool install = false, uninstall = false, console = false, rethrow = false;
try
{
foreach (string arg in args)
{
switch (arg)
{
case "-i":
case "-install":
install = true; break;
case "-u":
case "-uninstall":
uninstall = true; break;
case "-c":
case "-console":
console = true; break;
default:
Console.Error.WriteLine("Argument not expected: " + arg);
break;
}
}
if (uninstall)
{
Install(true, args);
}
if (install)
{
Install(false, args);
}
if (console)
{
Console.WriteLine("Starting...");
FeedListener fl = new FeedListener();
fl.StartUp();
Console.WriteLine("System running; press any key to stop");
Console.ReadKey(true);
fl.ShutDown();
Console.WriteLine("System stopped");
}
else if (!(install || uninstall))
{
rethrow = true; // so that windows sees error...
ServiceBase[] services = { new Service.FeedListener() };
ServiceBase.Run(services);
rethrow = false;
}
return 0;
}
catch (Exception ex)
{
if (rethrow) throw;
Console.Error.WriteLine(ex.Message);
return -1;
}
}
static void Install(bool undo, string[] args)
{
try
{
Console.WriteLine(undo ? "uninstalling" : "installing");
using (AssemblyInstaller inst = new AssemblyInstaller(typeof(Program).Assembly, args))
{
IDictionary state = new Hashtable();
inst.UseNewContext = true;
try
{
if (undo)
{
inst.Uninstall(state);
}
else
{
inst.Install(state);
inst.Commit(state);
}
}
catch
{
try
{
inst.Rollback(state);
}
catch { }
throw;
}
}
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.Message);
}
}
}
[RunInstaller(true)]
public sealed class MyServiceInstallerProcess : ServiceProcessInstaller
{
public MyServiceInstallerProcess()
{
this.Account = ServiceAccount.NetworkService;
}
}
[RunInstaller(true)]
public sealed class MyServiceInstaller : ServiceInstaller
{
public MyServiceInstaller()
{
this.Description = "Provides a service to listen for, then import, feed files from various sources.";
this.DisplayName = "RIVWorks Feed Handler (.NET 4.0)";
this.ServiceName = "FeedListener";
this.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
}
}
}
FEEDLISTENER.CS
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.IO;
using sysIO = System.IO;
using RivWorks.FeedHandler;
using System.Collections;
using RivWorks.FeedHandler.Library;
using System.Threading;
namespace RivWorks.FeedHandler.Service
{
public partial class FeedListener : ServiceBase
{
#region Declarations
static private List<string> _keys = new List<string>();
static private System.Threading.Timer _clock = null;
static private FileSystemWatcher _watcher;
static private RivWorks.FeedHandler.Library.QueueHandler _qHandler = null;
static private bool _isDequeueing = false;
#endregion
#region Constructor
public FeedListener()
{
InitializeComponent();
}
#endregion
#region Internal Methods
internal void StartUp() {...}
internal void ShutDown() {...}
#endregion
#region Start/Stop
protected override void OnStart(string[] args)
{
StartUp();
}
protected override void OnStop()
{
ShutDown();
}
#endregion
#region Event Handlers
static void qHandler_QueuesGrew() {...}
static void qHandler_QueuesShrunk() {...}
static void qHandler_QueuesChanged() {...}
static void fileCreatedOrChanged(object sender, sysIO.FileSystemEventArgs e) {...}
#endregion
#region Private Methods
private static void Tick(object state) {...}
private static void WriteToEventLog(Exception ex, EventLogEntryType eventLogEntryType) {...}
private static void WriteToEventLog(string message, EventLogEntryType eventLogEntryType) {...}
#endregion
}
}
And I found my answer! My project properties were set to Windows App instead of Console App. DOH! (Project Properties > Application Tab > Output type:)
这篇关于在控制台模式下运行 Windows 服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!