可以调用无限运行的 Python 脚本的 Windows 服务(在 C# 中)?

Posted

技术标签:

【中文标题】可以调用无限运行的 Python 脚本的 Windows 服务(在 C# 中)?【英文标题】:Windows Service (in C#) that can call a Python script that runs infinitely? 【发布时间】:2019-03-22 07:27:01 【问题描述】:

据我了解,当您运行 Windows 服务时,它会调用“onStart()”并在任务管理器中说该服务正在“启动”,直到“onStart()”方法完全运行为止,然后它说“正在运行”。我想创建一个线程来启动一个蓝牙广告脚本(用 Python3 编写),只要它没有连接到设备,它就会不断地做广告。当我尝试创建一个线程并运行脚本时,该服务通常只在任务管理器中显示“正在启动”,而实际上从未显示“正在运行”,因为我在“onStart()”中调用以启动脚本的线程永远不会完成我猜。有没有办法让服务启动,只有在执行完“onStart()”后才启动线程?

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 Service1()  InitializeComponent(); 

    //-------------------------------------------------------------------------
    private Boolean _started;
    public event System.EventHandler serviceChanged;
    Service1 serv = new Service1();
    static ThreadStart start = new ThreadStart(Adv_Py_Script);
    Thread Adv_Py_ScriptThread = new Thread(start);
    //Start_Adv s = new Start_Adv();
    //Thread thread1 = new Thread(new ThreadStart(s.Adv_Py_Script));



    //-------------------------------------------------------------------------
    protected override void OnStart(string[] args)
    
        isStarted = true;



        Thread.Sleep(5000);

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

    //-------------------------------------------------------------------------
    public Boolean isStarted
    
        get  return _started; 
        set
            
            _started = value;
            onServiceChanged();
            
    

    //-------------------------------------------------------------------------
    protected override void OnStop()
    
        isStarted = false;

        serv.killPyThread(Adv_Py_ScriptThread);
        base.OnStop();
        // wait for threads to stop
        Adv_Py_ScriptThread.Join(60);

        try
        
            string error = "";
           // Messaging.SMS.SendSMSTextAsync("5555555555", "Messaging Service stopped on " + System.Net.Dns.GetHostName(), ref error);
        
        catch
        
            // yes eat exception if text failed
        



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

    //-------------------------------------------------------------------------

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

【问题讨论】:

【参考方案1】:

虽然可能存在其他问题,但第一个问题是您的服务(可能)运行的本地服务帐户无权访问位置 C:\Users\bakere1\A19149\Projects\

如果您将“运行方式”帐户更改为具有权限的帐户,您会走得更远。我不是 python 极客,但如果你的 py 应用程序需要任何类型的用户 I/O,它将失败,因为没有分配给它的控制台会话。

另外,如果您有漫游配置文件,服务会在用户文件夹可用之前启动,因此它会挂起或失败。

【讨论】:

谢谢 - 你知道我将如何更改权限以允许它访问吗? 在 Windows 服务控制面板中,将“运行方式”帐户更改为具有您的应用所需权限的帐户。 我在该部分为自己授予了管理员访问权限,但仍然收到“1053”错误,表示尝试启动服务时超时 对不起,你需要等待比我更了解 Python 的人。我从未尝试将 Python 粘合到 Windows 服务中。

以上是关于可以调用无限运行的 Python 脚本的 Windows 服务(在 C# 中)?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在无限循环中休眠的 python 脚本停止运行?

运行无限循环并从“外部”获取命令(例如 shell 或其他脚本)

如何运行长期(无限)Python 进程?

怎么在python脚本中调用其它的python脚本运行?

Perl脚本调用的优缺点

azkaban怎么在job里面直接调用python脚本啊,我调用shell脚本正常运行,调用python脚本没有运行