在 Windows 服务中调用网络服务

Calling Web Service in a Windows Service

我使用了一个简单的 windows 服务来使方法在特定时间运行并且运行良好。之后我已经尝试过:

protected override void OnStart(string[] args)
{
    this.WriteToFile("Simple Service started {0}");
    this.ScheduleService();
}

protected override void OnStop()
{
    this.WriteToFile("Simple Service stopped {0}");
    this.Schedular.Dispose();
}

private Timer Schedular;

public void ScheduleService()
{
    try
    {
        Schedular = new Timer(new TimerCallback(SchedularCallback));
        string mode = ConfigurationManager.AppSettings["Mode"].ToUpper();
        this.WriteToFile("Simple Service Mode: " + mode + " {0}");

        //Rest of the code here
    }
    catch(Exception ex)
    {
        WriteToFile("Simple Service Error on: {0} " + ex.Message + ex.StackTrace);

        //Stop the Windows Service.
        using (System.ServiceProcess.ServiceController serviceController = new System.ServiceProcess.ServiceController("SimpleService"))
        {
            serviceController.Stop();
        }
    }
}

这是在一个简单的 windows 应用程序中完成的。所以我想做的是在 windows 服务中调用一个 web 服务(在特定时间操作的特定方法)。我正在构建的应用程序是基于 Web 的,我有点困惑如何将 windows 服务集成到其中?我是否需要任何替代方案或任何建议,我们将不胜感激。

注意:我想知道是否需要在 web 应用程序中为 windows 服务创建另一个项目或任何其他方式来实现?

回答您对我的评论的疑问;

另一种方法是使用包含您的 Windows 服务逻辑的 IIS 自动启动网站。 IIS 自动启动优于使用 Windows 服务,因为它包含所有 IIS 应用程序托管逻辑,包括自动重启和积极的资源管理。写得不好的 Windows 服务可以关闭服务器,但是 ASP.net IIS 托管的应用程序要关闭其主机需要很多时间(这几乎是不可能的)。

您的自动启动网站不需要对外界可见 - 它只需要有一个内部计时器,在启动时保持其活动状态。请注意,由于各种原因,IIS 可能会启动和停止 Web 应用程序;但结果是,只要您的其他 Web 服务应用程序 运行ning,它就会 运行ning。内部计时器可以等待特定时间来执行调用第二个 Web 服务所需的逻辑。

要记住的关键是 Windows 服务被设计为由 Windows 托管并持续 运行 的应用程序。 IIS 应用程序被设计为 运行 by Windows 但仅在调用时 运行s。 IIS 自动启动网站概念允许您提供一个 "continually running" 网站,但由强大的 IIS 应用程序托管组件托管,而不是 运行 直接作为 OS 进程托管。

通常人们不会这样做,因为他们不知道,或者想避免需要 IIS 基础结构来 运行 "Windows Service" 类型的应用程序,但在您的情况下,您已经支付了费用使用 IIS 托管您的第二个 Web 服务,因此您不妨充分利用 IIS(并避免 Windows 服务部署的第二个技术栈和部署难题)。

所以我建议在您的情况下优先使用 IIS 自动启动而不是 Windows 服务,因为;

  1. 你只需要在你的解决方案中使用 on tech stack,这就是你的 OP 所要求的
  2. IIS 对其所有应用程序执行主动资源管理,如果它们变得无法运行,则根据需要终止和重新启动。 Windows 服务没有那个能力。
  3. 您基于 IIS 的服务代码是 XCOPY 可部署的,目标机器上没有管理员访问凭据。
  4. 您的 IIS 服务可热升级,无需 OS 级管理员权限 - IIS 可处理升级时的停止和重新启动,您无需执行任何操作。

要从 Windows 服务应用程序调用 Web 服务,您首先要从该 Web 服务生成 DLL,然后实例化其命名空间。假设您有该 Web 服务的代码 and/or 知道它的命名空间,您可以执行这些命令来做到这一点:

  1. 在命令行上执行这些行:

    cd C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools
    wsdl /l:CS /protocol:SOAP %svc%?WSDL

    其中 %svc% 是您的网络服务的 URL,即 http://localhost:777/MyWebService.asmx

    如果代码在 VB 而不是 C# 中,请将 /l:CS 更改为 /l:VB。 这将输出一个代理 class 文件,可以将其转换为 DLL。

  2. MyWebService.cs 文件从 C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools 移动到 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ 目录。

  3. 运行命令行上的这两个命令:
    cd C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
    csc /t:library %name%.cs /reference:System.Web.Services.dll /optimize

    其中 %name% 是 class 的名称(没有 .cs,因为命令将追加它)。在我们的例子中,我们将使用 MyWebService。 (将 .cs 更改为 .vb 以获得 VB class。)

  4. 通过 Windows 资源管理器导航到 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727。您应该会看到在该文件夹中创建了一个名为 class (MyWebService.dll) 的 DLL。将此文件复制到服务项目的 bin 文件夹中。您需要将 bin 文件夹设置为包含在您的项目中,然后右键单击该文件夹以 Add > Existing Item。 Select DLL。导入后,select DLL 并将其属性更改为:

    构建操作:内容
    复制到输出目录:如果较新则复制(或始终复制,如您所愿)

  5. 右键单击 引用 > 添加引用。导航到 Web 服务的 bin 文件夹中的 DLL。

  6. 右键单击 引用 > 添加服务引用。假设您的 Web 服务是 运行,获取其完整的 URL(即 http://localhost:777/MyWebService.asmx)并将其放在地址行中。在 Namespace 文本框中,给它一些比 ServiceReference1 更有意义的东西,但它不应该与 MyWebService(ASMX 文件的 name/namespace)相同。也许 MWS.

  7. 在您的 Windows 服务中实例化您的网络服务:

    MWS.MyWebServiceSoapClient webService = new MWS.MyWebServiceSoapClient();
    webService.Open();
    string someDataYouWant = webService.SomeMethodToGetData();
    webService.Close();

    或者你可以这样做:

    MyWebService webService = new MyWebService();
    string someDataYouWant = webService.SomeMethodToGetData();
    webService.Dispose();