Нэнси с Topshelf не работает, когда работает как служба? C#

Я создал собственный хостинг с Нэнси, а затем хочу, чтобы приложение запускалось как сервисы. Поэтому я использую верхнюю полку, чтобы построить его. Затем, когда я отлаживаю свою программу или запускаю.exe, программа работает хорошо. Но когда я устанавливаю.exe как службу и запускаю службу. Я не могу вызвать API, который я создаю с помощью nancy (в браузере только "ожидание localhost..", ошибка или ошибка не возвращаются). Это из-за рабочего каталога, многопоточности или чего-то еще? благодарю вас

Вот мой код: 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 (модуль 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 (функция запуска и остановки и одна функция, вызываемая для 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();
    }
}

РЕДАКТИРОВАТЬ

Уже пытаются поймать исключение, но никто не пойман. Я пытаюсь комментировать Dummy.m_autoreset.WaitOne() и Dummy.m_autoreset.Set(). Теперь API работает, но функция внутри InitCDM() не выполняется? В этой функции я вызываю некоторую библиотеку для машины, чем машина возвращает обратную связь напрямую или через обработчик событий. Я думаю, что обработчик событий, который я создаю с помощью AddEventCDM(), не доступен библиотекой, потому что поток больше не доступен? Любой совет?

1 ответ

Попробуйте запустить NancyHost в новом потоке в методе Start(). В моем случае метод Start() не вернулся, что сделало невозможным запуск в качестве службы Windows.

Другие вопросы по тегам