node.jsのprocess.on( 'SIGINT')に相当するWindowsの機能は何ですか?


84

+またはサーバーのシャットダウンに応答して、Windows-8でホストされているnode.jsアプリケーションを正常にシャットダウンするために、ここでのガイダンス(SIGINTイベントのリッスン)に従っています。CtrlC

しかし、WindowsにはありませんSIGINT。私も試しましたがprocess.on('exit')、それは生産的なことをするのに遅れているようです。

Windowsでは、次のコードが表示されます。エラー:そのようなモジュールはありません

process.on( 'SIGINT', function() {
  console.log( "\ngracefully shutting down from  SIGINT (Crtl-C)" )
  // wish this worked on Windows
  process.exit( )
})

Windowsでは、このコードは実行されますが、適切な処理を行うに遅すぎます

process.on( 'exit', function() {
  console.log( "never see this log message" )
})

SIGINTWindowsに同等のイベントはありますか?


この問題は今日私にランダムに発生しました、そしてそれはreadlineモジュール自体と関係があると思います。テストはできませんでしたが、このモジュールを追加してから問題が発生し始めました。
sv4 4319

回答:


148

readlineモジュールを使用して、SIGINTイベントをリッスンする必要があります。

http://nodejs.org/api/readline.html#readline_event_sigint

if (process.platform === "win32") {
  var rl = require("readline").createInterface({
    input: process.stdin,
    output: process.stdout
  });

  rl.on("SIGINT", function () {
    process.emit("SIGINT");
  });
}

process.on("SIGINT", function () {
  //graceful shutdown
  process.exit();
});

最も優れたアップデート、ありがとう!前の回答(キー押下を聞く)が機能しなくなったため、これを回答として設定します。
pappadog 2013

44
ばかげてる。これがノードコアによって処理されないのはなぜですか?
balupton 2013年

3
stdinをリッスンすると、SIGINTシグナルを明示的に送信するまでプロセスが終了しないためです。
Gabriel Llamas

2
したがって、親から子にランダムなメッセージを送信する必要があります(例: "SIGINT")。
ガブリエルラマ2014年

8
これはかなり前に解決されたようです:github.com/nodejs/node-v0.x-archive/issues/5054
SimonSimCity

23

いつかはわかりませんが、ノード8.xとWindows 10では、元の質問コードが機能するようになりました。

process.on( "SIGINT", function() {
  console.log( "\ngracefully shutting down from SIGINT (Crtl-C)" );
  process.exit();
} );

process.on( "exit", function() {
  console.log( "never see this log message" );
} );

setInterval( () => console.log( "tick" ), 2500 );

ここに画像の説明を入力してください

Windowsのコマンドプロンプトでも機能します。


私もこれに気づきました。Windows 7は、ここでの私にとって大きな問題です
Gregory Nowakowski 2017

この方法は、Windows 7のノード8.11.1で機能します、gitbashシェルから実行していました。最初に簡単な方法を試してみると、うまくいきました。
user944849 2018

7

他のタスクで「readline」をインポートする必要がない限り、プログラムがWindowsで実行されていることを確認したら、「readline」をインポートすることをお勧めします。さらに、知らない人のために-これはWindows32ビットシステムとWindows64ビットシステムの両方で機能します(キーワード「win32」を返します)。このソリューションをありがとうガブリエル。

if (process.platform === "win32") {
  require("readline")
    .createInterface({
      input: process.stdin,
      output: process.stdout
    })
    .on("SIGINT", function () {
      process.emit("SIGINT");
    });
}

process.on("SIGINT", function () {
  // graceful shutdown
  process.exit();
});

5

今日 は、Windowsを含むすべてのプラットフォームで動作します。

次のコードは、Windows 10でログを記録し、正しく終了します。

process.on('SIGINT', () => {
    console.log("Terminating...");
    process.exit(0);
});

2
これは、cygwinでは機能しません。最新のWindows10(自動更新)、ノードバージョン8.11.4を使用します。「機能しない」とは、1)プロセスは終了するが、2)メッセージはコンソールに記録されず、3)作成されたHTTP接続はシャットダウンされないことを意味します。ただし、PowerShellで試してみたところ、期待どおりに機能することを付け加えておきます。しかし、PowerShellのcurlコマンドが不適切なため、cygwinに切り替えました。くそー!
John Deighan 2018

2
明らかな理由もなく(更新がまったくない)、今日は機能しなくなりましたが、理由はまだわかりません。受け入れられた答えはそれを修正しました。
Sv4 4319

4

現在、Windowsコンソール制御イベントをキャプチャするためのノードでのサポートはまだないため、POSIXシグナルに相当するものはありません。

https://github.com/joyent/node/issues/1553

ただし、ttyモジュールのドキュメントには、正常なシャットダウンを開始するためにキーの押下をキャプチャするメカニズムの例が示されていますが、これはctrl+に対してのみ機能しcます。

var tty = require('tty');

process.stdin.resume();
tty.setRawMode(true);

process.stdin.on('keypress', function(char, key) {
  if (key && key.ctrl && key.name == 'c') {
    console.log('graceful exit of process %d', process.pid);
    process.exit();
  }
});

おかげで、この情報を探していましたが、CTRL + Cの代わりにサーバーに実装できる限り、これは私にとって許容できる代替手段です。+1(ただし、これがプロセスにイベントリスナーを追加することでパフォーマンスに影響するかどうか
Cory Gross

これを試してみましたが、サーバーが実行されているときにゲームループstdinが使用できないようで、上記を使用するとCTRL + Cが機能しません。
Cory Gross

0

node.js 0.8以降、keypressイベントは存在しなくなりました。ただし、イベントを再実装するkeypressと呼ばれるnpmパッケージがあります。

でインストールしてからnpm install keypress、次のようにします。

// Windows doesn't use POSIX signals
if (process.platform === "win32") {
    const keypress = require("keypress");
    keypress(process.stdin);
    process.stdin.resume();
    process.stdin.setRawMode(true);
    process.stdin.setEncoding("utf8");
    process.stdin.on("keypress", function(char, key) {
        if (key && key.ctrl && key.name == "c") {
            // Behave like a SIGUSR2
            process.emit("SIGUSR2");
        } else if (key && key.ctrl && key.name == "r") {
            // Behave like a SIGHUP
            process.emit("SIGHUP");
        }
    });
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.