可以从 WCF 与 windows 服务通信 [英] It is possible to communicate to windows service from WCF

查看:21
本文介绍了可以从 WCF 与 windows 服务通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 windows 服务 有点陌生.我在一台机器(机器 1)上运行 WCF 服务,在另一台机器(机器 2)上运行 Windows 服务.

I am bit new to windows services. I have WCF service running on one machine(machine 1) and windows service running on another machine(machine 2).

我需要使用 WCF 服务在机器 2 上运行 powershell 脚本.我不知道从哪里开始以及如何实现这一点.此外,我需要将消息从 WCF Web 服务传递到 Windows 服务

I need to I need to do run a powershell script on machine 2 using the WCF service. I have no idea where to start and how to accomplish this. Further more I need to pass a message from WCF web service to Windows Service

请给我建议或提供一些好的例子或教程.

Please advice me or provide some good example or tutorial.

编辑
我想在机器 2 上运行一个 powershell 脚本.这个 powershell 脚本只被 WCF 服务知道.
只想做的是,将那个 powershell 传递给 Machine 2.怎么做??

EDIT
I want to run a powershell script on machine 2. This powershell script only knows by the WCF service.
In simply want to do is, pass that powershell to the Machine 2. How to do that??

推荐答案

首先,我假设你正在接管一个现有的项目,因为你的问题有点矛盾:你是 Windows 服务的新手,但是你声明你的系统中有一个.我还将考虑您必须维护现有的软件模型,同时您必须控制两台机器.所以:

First of all, I will assume that you are taking over an existing project, as you have a little contradiction in your question: you are new to Windows services, yet you state that you have one in your system. I'll also consider that you have to maintain the existing software model and, at the same time, that you have control over both machines. So:

  • 机器 1 上的 WCF 服务提供 PS 脚本
  • 机器 2 上的 Windows 服务应在这些脚本可用并由 机器 1 上的 WCF 服务传递后立即执行这些脚本
  • The WCF service on machine 1 provides the PS scripts
  • The Windows service on machine 2 should execute these scripts as soon as they are available and passed by the WCF service on machine 1

为了解决这个问题,您可以考虑在机器 2托管另一个 WCF 服务:如何:在托管 Windows 服务中托管 WCF 服务

In order to deal with this, you might consider hosting another WCF service on machine 2: How to: Host a WCF Service in a Managed Windows Service

这将如何运作?每次有新的 PS 脚本可用时,您都可以从 机器 1 上的 WCF 服务调用 机器 2 上的第二个 WCF 服务.随后,机器 2 上的 WCF 服务可能会将脚本保存到某个存储库(文件、数据库、内存中)并调用 ServiceController.ExecuteCommand 方法.此时,Windows 服务将从其保存位置获取脚本并执行.虽然我觉得这是一个不必要的过于复杂的软件项目,但这里有一个针对您情况的实现,只是为了回答您的问题,是的,有可能.

How this will work? You'll be able to call this second WCF service on machine 2 from the WCF service on machine 1 every time a new PS script is available. Subsequently, the WCF service on machine 2 may save the script to some repository (file, database, in memory) and call the ServiceController.ExecuteCommand Method on the Windows service. At this point, the Windows service will get the script form it's saved location and execute it. Although I have the feeling that this is a unnecessarily over-complicated software project, here is an implementation for your situation, just to answer your question that yes, it is possible.

机器 2 上,安装包含 WCF 服务的 Windows 服务:

On machine 2, install the Windows service, which contains a WCF service:

using System;
using System.Linq;
using System.ComponentModel;
using System.ServiceModel;
using System.ServiceProcess;
using System.Configuration.Install;
using System.IO;
using System.Management.Automation;
using System.Management.Automation.Runspaces;

namespace Sample.Services
{
    [ServiceContract(Namespace = "http://Sample.Services")]
    public interface IScriptExecutor
    {
        [OperationContract]
        void ExecuteScript(string script);
    }

    /// <summary>
    /// The WCF service class which will pass the script to the Windows
    /// service
    /// </summary>
    public class ScriptExecutorService : IScriptExecutor
    {
        const string PATH = @"C:\test\queue.txt";
        public void ExecuteScript(string script)
        {
            File.WriteAllText(PATH, script);
            ServiceController myService = 
                new ServiceController("WCFScriptWindowsService");
            myService.ExecuteCommand((int)MyCustomCommands.ExecuteScript);

        }
    }

    public class ScriptWindowsService : ServiceBase
    {
        const string PATH = @"C:\test\queue.txt";
        const string PATH_OUT = @"C:\test\out.txt";

        public ServiceHost serviceHost = null;
        public ScriptWindowsService()
        {
            ServiceName = "WCFScriptWindowsService";
        }

        protected override void OnCustomCommand(int command)
        {
            switch (command)
            {
                case (int)MyCustomCommands.ExecuteScript:
                    // Execute the PS script
                    var ps = PowerShell.Create();
                    var runspace = RunspaceFactory.CreateRunspace();
                    ps.Runspace = runspace;
                    // read the command from a repository, 
                    // could also be a database
                    ps.AddCommand(File.ReadAllText(PATH));
                    runspace.Open();
                    var results = ps.Invoke().ToList();
                    runspace.Close();
                    foreach (var result in results)
                    {
                        // writing the results to a file
                        File.AppendAllText(PATH_OUT, 
                            String.Format("{0}\r\n", 
                                result.BaseObject.GetType()));
                    }
                    break;
                default:
                    break;
            }
        }

        public static void Main()
        {
            ServiceBase.Run(new ScriptWindowsService());
        }

        protected override void OnStart(string[] args)
        {
            if (serviceHost != null)
            {
                serviceHost.Close();
            }
            serviceHost = 
                new ServiceHost(typeof(ScriptExecutorService));
            serviceHost.Open();
        }

        protected override void OnStop()
        {
            if (serviceHost != null)
            {
                serviceHost.Close();
                serviceHost = null;
            }
        }
    }

    // Provide the ProjectInstaller class which allows 
    // the service to be installed by the Installutil.exe tool
    [RunInstaller(true)]
    public class ProjectInstaller : Installer
    {
        private ServiceProcessInstaller process;
        private ServiceInstaller service;

        public ProjectInstaller()
        {
            process = new ServiceProcessInstaller();
            process.Account = ServiceAccount.LocalSystem;
            service = new ServiceInstaller();
            service.ServiceName = "WCFScriptWindowsService";
            Installers.Add(process);
            Installers.Add(service);
        }
    }

    /// <summary>
    /// Holds the custom commands (only one, in our case)
    /// </summary>
    public enum MyCustomCommands { ExecuteScript = 128 };
}

机器1上,修改WCF服务,使其调用机器2上的WCF服务:

On machine 1, modify the WCF service so that it calls the WCF service on machine 2:

using System.ServiceModel;

namespace Sample.Services
{
    [ServiceContract(Namespace = "http://Sample.Services")]
    public interface IScriptProvider
    {
        [OperationContract]
        string GetScript();
    }
    public class ScriptProviderService : IScriptProvider
    {
        public string GetScript()
        {
            // do some processing ...
            // let's say we end up with the "Get-Service" script
            var script = "Get-Service";
            // make sure you add a reference to the ExecutorServiceReference
            // WCF service on machine 2
            var client = new WcfService1.ExecutorServiceReference
                .ScriptExecutorClient();
            client.ExecuteScript(script);
            return script;
        }
    }
}

我再次强调:您不必从 Windows 服务本身执行 PS 脚本.通过在 Windows 服务中托管新的 WCF 服务,您可以轻松调用它的方法并将逻辑从 OnCustomCommand 方法的覆盖移动到 ScriptExecutorServiceExecuteScript 方法.

I will stress again: you do not have to execute the PS script from the Windows service itself. By hosting the new WCF service in the Windows service, you can easily call it's methods and move the logic from the OnCustomCommand method's override to the ScriptExecutorService's ExecuteScript method.

如果我的模型假设有误,我会更新我的答案.

I'll update my answer if my model assumptions were wrong.

这篇关于可以从 WCF 与 windows 服务通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆