Windows服务不会停止(C#)

时间:2018-10-22 19:33:11

标签: c# python windows windows-services

我已经用C#制作了Windows服务,该服务调用了python脚本来运行。这没有问题。但是,当我停止服务时,它显示错误“无法停止”,我必须在命令行中使用PID手动将其杀死。并非总是这样,我似乎无法在VS2017中找到我的代码的早期版本。我的代码的哪一部分导致Windows服务无法关闭?

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.Threading.Tasks;
using System.IO;
using System.Timers;
using System.Threading;
using System.Security.Permissions;

namespace WindowsService1
{
    public partial class Service1 : ServiceBase
    {
    public ThreadStart startScript;
    public Thread PyScriptThread;
    public ServerClass serverObject;
    //-------------------------------------------------------------------------
    public Service1() { InitializeComponent(); }

    //-------------------------------------------------------------------------
    protected override void OnStart(string[] args)
    {
        serverObject = new ServerClass();

        PyScriptThread = new Thread(new ThreadStart(serverObject.PyScript));
        var t = Task.Run(() => serverObject.PyScriptAsync(PyScriptThread));
    }

    //-------------------------------------------------------------------------
    protected override void OnStop()
    {
        try
        {
            StreamWriter sw = new StreamWriter(@"C:\Users\bakere1\A19149\Projects\text_doc.txt", false);
            sw.Write("***STOP***");
            sw.Close();                                //stop the script within the process


            if (!serverObject.p.HasExited)             //kill the process within the thread
            {
                serverObject.p.CancelErrorRead();
                serverObject.p.CancelOutputRead();
                serverObject.p.CloseMainWindow();
                serverObject.p.Refresh();
                serverObject.p.Close();
                serverObject.p.Kill();
                serverObject.p.Dispose();
            }

            serverObject.PyScriptAsync(PyScriptThread).Dispose();

            killPyThread(PyScriptThread);             //kill the overarching thread

            base.OnStop();
        }

        catch (Exception ex)
        {
            if (ex is IOException || ex is ThreadInterruptedException || ex is ThreadAbortException || ex is InvalidOperationException)
            {
                StreamWriter errorSW = new StreamWriter(@"C:\Users\bakere1\A19149\Projects\text_doc.txt", true);
                errorSW.Write("Error occurred: Stacktrace/Message/Source", ex.StackTrace, ex.Message, ex.Source);
                errorSW.Close();
            }
        }
    }

    //-------------------------------------------------------------------------
    [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
    public void killPyThread(Thread thread)
    {
        thread.Interrupt();
        thread.Abort();
    }

}

public class ServerClass
{
    public event System.EventHandler serviceChanged;
    public Process p;
    //-------------------------------------------------------------------------
    public async Task PyScriptAsync(Thread thread)
    {
        await Task.Delay(10000).ConfigureAwait(false);
        thread.Start();
    }

    public void PyScript()
    {
        string fileName = @"C:\Users\bakere1\A19149\Projects\BLE_Advertiser.py";
        p = new Process
        {
            StartInfo = new ProcessStartInfo(@"C:\Python36_64\python.exe", fileName)
            {
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                UseShellExecute = false,
                CreateNoWindow = false
            }
        };
        p.Start();

        p.WaitForExit();

        p.CancelErrorRead();
        p.CancelOutputRead();
        p.CloseMainWindow();
        p.Refresh();
        p.Close();
        p.Kill();
        p.Dispose();

        return;
    }

    //-------------------------------------------------------------------------
    protected virtual void onServiceChanged()
    {
        serviceChanged?.Invoke(this, EventArgs.Empty);
    }
}

}

0 个答案:

没有答案