概要
ブラウザから外部プログラムを起動することはブラウザ単体では(拡張機能を使っても)出来ないので、node.jsで外部プログラムを起動するサーバーを作ってみた。
ブックマーク機能を使えば簡単なランチャーにもなりそう。
ソース
Executer.js
varhttp=require('http');varurl=require('url');varproc=require('child_process');//ヘッダHTMLの出力varheader=function(res){res.write(`<html>
<head>
<title>Node Executer</title>
</head>
<body>
`);};//フォームの出力varform=function(res){res.write(`<form action="http://localhost:8888" method="GET">
<input type="text" name="command" value="" />
<input type="submit" value="Execute!">
</form>
`);};//フッターHTMLの出力varfooter=function(res){res.write(`</body>
</html>
`);res.end();};//サーバー起動http.createServer(function(req,res){if(req.method==='GET'){//キャッシュしない設定でHTTPヘッダを出力res.writeHead(200,{'Content-Type':'text/html','Cache-Control':'private, no-cache, no-store, must-revalidate'});varquery=url.parse(req.url,true).query;varcommand='';varout='';variserr=false//HTTP Queryからコマンド文字列を取得if(typeofquery.command!=='undefined'){command=query.command;}//ヘッダを出力header(res,command);if(command.length>0){//クエリにコマンド文字列が設定されていればspawnで起動res.write('<pre id="output" style="color:red">');varresult=command.match(/(S+)\s?(.*)/);varspwn=proc.spawn(command,[],{shell:true,env:process.env});//spawnのエラーイベント・エラー出力があればそのままレスポンスとして出力spwn.on('error',(err)=>{iserr=true;res.write(data);console.log(data);});spwn.stdout.on('data',(data)=>{//標準出力は出力しない//res.write(data);});spwn.stderr.on('data',(data)=>{iserr=true;res.write(data);});//2秒後にフッタを出力して切断(起動したアプリはそのまま)setTimeout(()=>{res.write('</pre>');//エラーがなければそのまま前のページに戻るif(!iserr)res.write('<script>history.back();</script>');footer(res);},2000);}else{//コマンド文字列が設定されていなければフォームとフッタを出力して切断form(res);footer(res);}}else{//GETメソッド以外は404エラーを返すres.writeHead(404,{'Content-Type':'text/plain'});res.write('Not Found');res.end();}}).listen(8888,'127.0.0.1');
起動は
>node Executer.js
http://localhost:8888
で接続できる
終了はCtrl-Cで。
外部からサーバーを(強制)終了させる
ポート番号がわかっていればnetstatコマンドでポートを確保しているプロセス番号がわかるので、それを元にkillすることで正常終了させる仕組みがないサーバーでも外部からサーバーを強制終了させることができるらしい。
下記はWindowsが対象だが、たぶんLinuxでも同じようなことは出来ると思う。
参考:
- ポートを握っているプロセスを見たい時
- Windowsで、特定のポート番号でLISTENINGしているプロセスを強制終了させる方法
- Node.jsでport 3000のプロセスを探してkillするDOS バッチファイル(Windows10)
このサーバーの場合は、
@echo offFOR/F "delims="%%iin('netstat -aon ^| findstr 127.0.0.1:8888')dosetNODEPORT=%%iechoofffor%%ain(%NODEPORT%)do(setTEMPB=%%a)echo%TEMPB%taskkill/pid %TEMPB%/F
こんな感じのバッチファイルを作っておけば外部からkillできる。