【发布时间】:2011-05-25 23:20:09
【问题描述】:
我想创建一个 Windows 服务来验证数据并从另一个 Windows 应用程序访问它,但我是服务新手,不知道如何开始。
因此,当服务运行时,Windows 应用程序应该以某种方式连接到服务,发送一些数据并获得响应,无论是真还是假。
【问题讨论】:
标签: c# windows-services ipc
我想创建一个 Windows 服务来验证数据并从另一个 Windows 应用程序访问它,但我是服务新手,不知道如何开始。
因此,当服务运行时,Windows 应用程序应该以某种方式连接到服务,发送一些数据并获得响应,无论是真还是假。
【问题讨论】:
标签: c# windows-services ipc
您的服务在处理过程中可以将事件添加到 EventLog。
您可以创建另一个与服务并行运行的控制台应用程序,并使用事件处理机制侦听该 EventLog:
var log= new EventLog("[name of the eventlog]");
log.EnableRaisingEvents = true;
log.EntryWritten += Log_EntryWritten;
那你马上处理:
private static void Log_EntryWritten(object sender, System.Diagnostics.EntryWrittenEventArgs e)
{
Console.WriteLine("Event detected !");
}
您可以阅读 EntryWrittenEventArgs 对象以获取所有事件详细信息,并在控制台应用程序中显示您想要的内容。如果您停止控制台应用程序,服务会继续运行,并且仍会记录到事件日志中。
【讨论】:
我可以通过以下方式成功处理(几乎)与您相同的问题:
在您的 Class : ServiceBase 中,代表您的 Service 类,您可能有:
public Class () //constructor, to create your log repository
{
InitializeComponent();
if (!System.Diagnostics.EventLog.SourceExists("YOURSource"))
{
System.Diagnostics.EventLog.CreateEventSource(
"YOURSource", "YOURLog");
}
eventLog1.Source = "YOURSource";
eventLog1.Log = "YOURLog";
}
现在,实施:
protected override void OnStart(string[] args)
{...}
与
protected override void OnStop()
{...}
处理自定义命令调用:
protected override void OnCustomCommand(int command)
{
switch (command)
{
case 128:
eventLog1.WriteEntry("Command " + command + " successfully called.");
break;
default:
break;
}
}
现在,在您将调用 Windows 服务的应用程序中使用它:
枚举来引用您的方法:(请记住,服务自定义方法始终接收 int32(128 到 255)作为参数,使用枚举可以更容易记住和控制您的方法
private enum YourMethods
{
methodX = 128
};
调用特定方法:
ServiceController sc = new ServiceController("YOURServiceName", Environment.MachineName);
ServiceControllerPermission scp = new ServiceControllerPermission(ServiceControllerPermissionAccess.Control, Environment.MachineName, "YOURServiceName");//this will grant permission to access the Service
scp.Assert();
sc.Refresh();
sc.ExecuteCommand((int)YourMethods.methodX);
这样做,您可以控制您的服务。
Here您可以查看如何创建和安装 Windows 服务。 More 关于 ExecuteCommand 方法。
祝你好运!
【讨论】:
在旧版本的 Windows 中,您可以将 Windows 服务配置为与桌面交互。这允许您将用户界面元素直接添加到可以呈现给用户的服务中。从 Windows Vista 开始,服务不能再直接与用户交互,即没有用户界面。
为此,您要做的是编写您的 Windows 服务和一个前端 Windows 应用程序。为了提供两者之间的沟通桥梁,我强烈建议使用Windows Communication Foundation (WCF)。
要创建 C# Windows 服务,您可以按照here 的分步说明进行操作。
【讨论】:
如果您使用的是 .Net Framework 4,那么内存映射文件提供了一种实现跨进程通信的相当简单的方法。
它相当简单,并且在文档中得到了很好的描述,并且避免了使用 WCF 或其他基于连接/远程处理的交互或将共享数据写入中心位置的开销(在运行时以及开发工作方面)轮询(数据库、文件等)。
有关概述,请参阅here。
【讨论】:
将其视为远程数据库所有者。假设您有 1 个数据库,但有 10 个应用程序需要来自数据库的不同数据,而且您不想将所有数据开放给每个应用程序。此外,您的应用程序将独立于您的数据库,您的数据层将只在您的服务中实现,您的应用程序将不包含该逻辑。您可以编写服务并将您的服务开放给其他应用程序。
【讨论】:
为此,我们使用命名管道。但是我们的客户端是用 C++ 实现的。如果您的服务和应用程序是在 .Net 中实现的,则可以使用 .Net 远程处理。
【讨论】:
MarshalByRefObject 方案等效的方案,但在 WCF 框架中仍有解决此问题的方法。 MSDN 网站特别指出 .NET Remoting 是一项为向后兼容而维护的遗留技术,不推荐用于新开发。 msdn.microsoft.com/en-us/library/kwdt6w2k.aspx
您可以通过将服务托管 WCF 服务并从您的应用程序连接到它来非常轻松地完成此操作。
【讨论】:
NetTcpBinding 内,您也可以使用本地主机地址来限制对本地机器的访问。虽然一旦跨越机器边界就会产生安全隐患,但事实仍然是 WCF 使分布式操作成为可能,而内存映射解决方案则排除了它。