Не удается найти свойство 'svc' при использовании promisify - PullRequest
1 голос
/ 06 мая 2019

Я пытаюсь написать приложение, которое будет работать как служба Windows.Для этого я использовал пакет node-windows.Приложение будет печатать простое сообщение каждую секунду при запуске (по крайней мере, на данный момент) - используется tasktimer для игнорирования таймера.Проблема, которую я обнаружил, заключалась в том, что когда служба не установлена, она пытается запустить службу, а затем установить ее (она работает асинхронно).Итак, я попытался решить эту проблему, используя promisify (чтобы иметь возможность использовать async - await, но теперь он дает мне ошибку: TypeError: Cannot read property 'svc' of undefined ...

Это класс, который создаетобъект службы и объявляет методы:

import * as pEvent from 'p-event'
var Service = require('node-windows').Service;

export class winServ {
    svc = new Service({
        name: 'Cli app',
        description: 'Just a cli app...',
        script: './src/index.js'
    });

    async alreadyInstalled() {
        //check if service was already installed - return 0 or 1
        this.svc.install();

        await pEvent(this.svc, 'alreadyinstalled')
        .then( () => {
            console.log('Already installed!');
            return 1;
        });

        return 0;
    }

    async installWinServ() {
        this.svc.install();

        await pEvent(this.svc, 'install')
        .then( () => {
            console.log('Service now installed!');
        });
    }

    async uninstallWinServ() {
        this.svc.uninstall();

        // await pEvent(this.svc, 'alreadyuninstalled')
        // .then( () => {
        //  console.log('Already uninstalled!');
        //  return;
        // });

        await pEvent(this.svc, 'uninstall')
        .then( () => {
            console.log('Uninstall complete.');
            console.log('The service exists: ', this.svc.exists);
        })
    }

    async runWinServ() {
        console.log('Service has started!');
        await this.svc.start();
    }

    async stopWinServ() {
        await this.svc.stop();
    }
}

И это файл index.ts, в котором я вызываю класс и пытаюсь выполнить логику: 1. запустите метод установки (если он уже установлен, простораспечатайте сообщение и вернитесь; если нет, установите службу) 2. запустите приложение (оно будет работать бесконечно)

import { winServ } from './windowsService/winServ';

var main = async () => {
    try {
            let serv = new winServ();

            //let alreadyInstalled = await serv.alreadyInstalled();
            //if (alreadyInstalled == 0) {
                await serv.installWinServ();
            //}

            await serv.runWinServ();

            let timer = new TaskTimer();

            // define a timer that will run infinitely
            timer.add(() => {
               console.log("abcd");
               timer.interval = 1000;
            });

            // start the timer
            timer.start();
            }
    }
    catch (err) {
        console.log(err);
    }
}

main();

ОБНОВЛЕНИЕ: Хорошо, теперь я пропустил (не) проверку установки, и она выдаетмне ошибка:

TypeError: Cannot read property 'send' of null
    at process.killkid (C:\Programs\node_modules\node-windows\lib\wrapper.js:177:11)

Это заставляет службу останавливаться сразу после ее запуска. Есть мысли? :)

1 Ответ

2 голосов
/ 06 мая 2019

util.promisify(serv.installWinServ) не привязан к serv и не может получить доступ к правильному this контексту.

Обещание функций async является ошибкой. installWinServ и т. Д. Уже возвращают обещание. Они не используют обещания правильно, потому что this.svc.on не возвращает обещание и не может быть await ed. Слушатель событий должен быть обещан, например, с p-event:

await pEvent(this.svc, 'alreadyinstalled');

Или events.once (Узел 11 или выше):

await once(this.svc, 'alreadyinstalled');
...