简体   繁体   English

Nancy with Topshelf作为服务运行时不起作用? C#

[英]Nancy with Topshelf doesn't work when run as service? C#

I created some self-hosting with Nancy then I want the app run as services. 我用Nancy创建了一些自我托管服务,然后希望该应用程序作为服务运行。 So i use topshelf to build it. 所以我用topshelf来构建它。 Then when I debug my program or run .exe, program running well. 然后,当我调试程序或运行.exe时,程序运行良好。 But when I install .exe as service and start the service. 但是当我安装.exe作为服务并启动该服务时。 I can't call the API I create with nancy (in browser only "waiting localhost.." not return error or succes). 我无法调用用nancy创建的API(在浏览器中仅“等待localhost ..”不会返回错误或成功)。 Is it because working directory, threading or anything else? 是因为工作目录,线程还是其他? thank you 谢谢

Here is my code : Program.cs 这是我的代码:Program.cs

public class Program
{
    [STAThread]
    public static void Main()
    {
        var thread = new Thread(WorkerMethod);
        thread.SetApartmentState(ApartmentState.STA);
        thread.IsBackground = false;
        thread.Start();
    }

    public static void WorkerMethod(object state)
    {
        HostFactory.Run(x =>
        {
            x.Service<HostingAPI>(s =>
            {
                s.ConstructUsing(name => new HostingAPI());
                s.WhenStarted(tc => tc.Start());
                s.WhenStopped(tc => tc.Stop());
            });

            x.RunAsLocalSystem();
            x.SetDescription("Hardware hosting API");
            x.SetDisplayName("Hosting Services for Hardware");
            x.SetServiceName("Hardware Services");
        });
    }
}

CDM_Module (the nancy module) CDM_Module(nancy模块)

public class CDM_Module : NancyModule
{
    public CDM_Module()
    {
        try
        {
            Get["/CDM/Machine/Start"] = parameters =>
            {
                var ins = HostingAPI.Instance;
                bool result = ins.InitCDM_Thread();

                return Response.AsJson(result);
            };

            Get["/CDM/Machine/OpenGate"] = parameters =>
            {
                var ins = HostingAPI.Instance;
                bool result = ins.StartProcess_Thread();

                return Response.AsJson(result);
            };

            Get["/CDM/Machine/CloseGate"] = parameters =>
            {
                var ins = HostingAPI.Instance;
                bool result = ins.StopProcess_Thread();

                return Response.AsJson(result);
            };
        }
        catch
        {
        }
    }
}

HostingAPI.cs (start and stop function and one function called for API) HostingAPI.cs(启动和停止功能以及一个为API调用的功能)

public class HostingAPI
{
    //global variable
    private NancyHost mainHost;
    public static HostingAPI Instance;
    private string hostUrl;
    //public static MainCDM Ins = new MainCDM();

    public clsCSDDPMControl ObjDPMControl = new clsCSDDPMControl();
    public ClsPrinterControl ObjPrinterControl = new ClsPrinterControl();

    //webservice
    HttpClient httpClient = new HttpClient();

    public void Start()
    {
        //set hosturl dari document xml nantinya
        //sementara default
        //under construction
        Config.ReadConfiguration();

        //set awal entity
        buildEntity();

        AddEventCDM();
        AddEventPrinter();

        Instance = this;

        if (hostUrl == null) hostUrl = "http://localhost:5030";

        mainHost = new NancyHost(new Uri(hostUrl));
        mainHost.Start();

        //Console.WriteLine("Hardware Hosting API is running on " + hostUrl);

    }

    public void Stop()
    {
        mainHost.Stop();
        //Console.WriteLine("Service stopped!");
    }

    public bool InitCDM_Thread()
    {
        var thread = new Thread(InitCDM);
        thread.SetApartmentState(ApartmentState.STA);
        thread.IsBackground = false;
        thread.Start();
        Dummy.m_autoreset.WaitOne();
        return rtn;
    }

    private void AddEventCDM()
    {
        ObjDPMControl.EvtBoxFullReceived += new clsCSDDPMControl.EvtBoxFullReceivedEventHandler(ObjDPMControl_EvtBoxFullReceived);
        ObjDPMControl.EvtDocDataReceived += new clsCSDDPMControl.EvtDocDataReceivedEventHandler(ObjDPMControl_EvtDocDataReceived);
        ObjDPMControl.EvtDocumentCounterReceived += new clsCSDDPMControl.EvtDocumentCounterReceivedEventHandler(ObjDPMControl_EvtDocumentCounterReceived);
        ObjDPMControl.EvtDPMShellMsgReceived += new clsCSDDPMControl.EvtDPMShellMsgReceivedEventHandler(ObjDPMControl_EvtDPMShellMsgReceived);
        ObjDPMControl.EvtErrMsgReceived += new clsCSDDPMControl.EvtErrMsgReceivedEventHandler(ObjDPMControl_EvtErrMsgReceived);
        ObjDPMControl.EvtEventsReceived += new clsCSDDPMControl.EvtEventsReceivedEventHandler(ObjDPMControl_EvtEventsReceived);
        ObjDPMControl.EvtImageStoredReceived += new clsCSDDPMControl.EvtImageStoredReceivedEventHandler(ObjDPMControl_EvtImageStoredReceived);
        ObjDPMControl.EvtImageStoredErrorReceived += new clsCSDDPMControl.EvtImageStoredErrorReceivedEventHandler(ObjDPMControl_EvtImageStoredErrorReceived);
        ObjDPMControl.EvtStatusReceived += new clsCSDDPMControl.EvtStatusReceivedEventHandler(ObjDPMControl_EvtStatusReceived);
        ObjDPMControl.AxEvtBackTraceFileReady += new clsCSDDPMControl.AxEvtBackTraceFileReadyEventHandler(ObjDPMControl_AxEvtBackTraceFileReady);
        ObjDPMControl.AxEvtComPortError += new clsCSDDPMControl.AxEvtComPortErrorEventHandler(ObjDPMControl_AxEvtComPortError);
        ObjDPMControl.AxEvtExtraImageError += new clsCSDDPMControl.AxEvtExtraImageErrorEventHandler(ObjDPMControl_AxEvtExtraImageError);
        ObjDPMControl.AxEvtFrontDitherReady += new clsCSDDPMControl.AxEvtFrontDitherReadyEventHandler(ObjDPMControl_AxEvtFrontDitherReady);
        ObjDPMControl.AxEvtOutOfOrder += new clsCSDDPMControl.AxEvtOutOfOrderEventHandler(ObjDPMControl_AxEvtOutOfOrder);
        ObjDPMControl.AxEvtRearDitherReady += new clsCSDDPMControl.AxEvtRearDitherReadyEventHandler(ObjDPMControl_AxEvtRearDitherReady);

        DeviceReplyCode = Convert.ToInt32(ObjDPMControl.InitDevices(Config.DpmIniFile));

    }

    private void InitCDM()
    {
        DeviceReplyCode = Convert.ToInt32(ObjDPMControl.InitDevices(Config.DpmIniFile));

        if (DeviceReplyCode == ObjDPMControl.CSDeviceSuccessCode)
        {
            if (ObjDPMControl.StartDPMEngine() == true)
            {
                if (ObjDPMControl.DPMSetTimeouts() == true)
                {
                    rtn = true;
                }
                else
                {
                    rtn = false;
                }
            }
            else
            {
                rtn = false;
            }
        }
        else
        {
            rtn = false;
        }

        Dummy.m_autoreset.Set();
    }
}

EDIT 编辑

Already try to catch exception but no one caught. 已经尝试捕获异常,但是没有人捕获。 I try to comment Dummy.m_autoreset.WaitOne() and Dummy.m_autoreset.Set(). 我尝试评论Dummy.m_autoreset.WaitOne()和Dummy.m_autoreset.Set()。 Now the API works but the function inside InitCDM() not executed? 现在该API可以使用了,但是InitCDM()内部的函数没有执行? In that function i call some library for machine than the machine give back feedback directly or by eventhandler. 在该函数中,我为机器调用了一些库,而不是直接或通过事件处理程序返回反馈。 I think the eventhandler i create with AddEventCDM() not reach by library because the thread is not available anymore? 我认为我用AddEventCDM()创建的事件处理程序无法通过库访问,因为线程不再可用? Any advise? 有什么建议吗?

Try to start the NancyHost on a new thread in the Start() method. 尝试在Start()方法中的新线程上启动NancyHost。 In my case the Start() method did not return making it impossible to start as a Windows service. 在我的情况下,Start()方法未返回,因此无法作为Windows服务启动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM