2016-12-17 5 views
0

私は、Pythonクライアントプログラムを実行しているWindowsマシンでコマンドを実行しようとしています。コマンドを実行する前に、サーバーに値を返す必要があります。Windowsで遅れてバックグラウンドでシャットダウンコマンドを実行する

def shutdown(): 
    if OS_LINUX: 
     os.system("sleep 10s && sudo shutdown &") 
    elif OS_WIN: 
     os.system(<What to put HERE>) 
    return (1,"Shutting down") 

ご覧のとおり、unixコマンドは正常に動作します。

バックグラウンドでは、10秒間スリープ状態になり、その後、sudo shutdownが実行されます。この関数は適切に返され、 "sudo shutdown"が実行される前にクライアントがシャットダウンしていることをサーバが通知します。

しかし、物事の窓側では、遅延の後にシャットダウン-sを実行してバックグラウンドで実行するように見えません。

これは私がこれまで持っているものです。

start /b /wait timeout 10 && shutdown -s 

私はそれの多くのバリエーションを試してみました:付き/なし/待ってから/ B、代わりにタイムアウトのPINGを使用して、するには、ping /タイムアウトの出力を送信"> nul"など

これは私が望むものに最も近いものですが、タイムアウトは実行されるまでコマンドラインを引き継ぎます。これは、return文がシャットダウン()の前に適用されないようにします"shutdown -s"が実行されます。これにより、タイムアウトするまでサーバーが停止してしまいます。特に、サーバーがシャットダウンすると同時にクライアントが接続を失ったことを保証できないため、ユーザーに見せたくないものです。

私は、バッチスクリプトで「タイムアウト10 & &シャットダウン-s」を投げ、バックグラウンドでos.system(「スタート/ Bのshutdown_script.bat」)を使用していることを実行することで問題を解決することはできますが、この可能性がありますクライアントプログラムは配布上の理由から単一の移植可能なファイルである必要があります。

解決策はUNIX上で簡単ですが、私はDOSで何が欠けていますか?

EDIT:os.system( "shutdown -s")コマンド(少なくともwin10)を実行すると、システムがシャットダウンすることをユーザーに示す画面が表示されます。これにより、私の関数が正しく動作し、サーバーに値を返すことができます。これは、hibernate( "shutdown -h")のような他のコマンドの場合には当てはまりません。古いバージョンのウィンドウでは必ずしもそうではありません。この問題は、クライアントプログラムをリモートで閉じるなどの他のコマンドでも引き続き発生します。

EDIT2:また、休止状態とログオフのコマンドを実行する必要があります。 -hと-lをそれぞれシャットダウンします。シャットダウンの-tパラメータのみ(少なくとも、窓10上)-sと-rで動作

+0

'/ l'(ログオフ)と'/p'(電源オフ)['ExitWindowsEx'](https://msdn.microsoft.com/en-us/library/aa376868)を呼び出し、タイムアウトをサポートしません。 '/ h'(休止状態)は、サポートされ、有効化されていれば、' NtInitiatePowerAction'システムコールによってタイムアウトのサポートなしで実装されます。 '/ s'(シャットダウン)と'/r'(リブート)コール '' InitiateSystemShutdownEx'(https://msdn.microsoft.com/en-us/library/aa376874)ハイブリッド 'は[' InitiateShutdown'](https://msdn.microsoft.com/en-us/library/aa376872)を呼び出します。どちらも最大10年間のタイムアウトをサポートしています。 – eryksun

+0

'threadprocess.Timer'のようなPython内部の共通のソリューションを使うことができます。これは、' subprocess.check_call'を通してshutdownコマンドを実行します。あなたが '/ s'や'/r'を実行している場合、システムワイドの警告が表示されてタイムアウトをサポートしている場合は、タイマーをスキップできます。 – eryksun

答えて

0

を私はシャットダウンだけタイムアウトをサポートしているためでschtasksを使用して問題を解決することになりました/ sと/ rのために。

Pythonコードは現在の時間に1分のオフセットを追加し(schtasksは数秒で処理されません)、schtaskを保持しないように/ fパラメータを指定してos.system( "schtasks .....")を呼び出しますay/n上書きを求めるコンソールを起動します。

def get_time_offset(offset): 
    now = datetime.datetime.now() 
    offset_now = now + datetime.timedelta(minutes=offset) 
    offset_now_time = offset_now.time() 
    future_time = (str(offset_now_time.hour) + ":" + str(offset_now_time.minute) + ":" + str(offset_now_time.second)) 
return future_time 

def sch_task(name, time, task): 
    os.system("schtasks /create /tn \"" + str(name) + "\" /sc once /st " + str(time) + " /tr \"" + str(task) + "\" /f") 

最終呼び出しは次のようになります。

sch_task("client_hibernate", get_time_offset(1), "shutdown /h") 

呼び出しが行われた後、それは1分を実行します。

このソリューションの唯一の問題は、schtasksは分単位の精度しか持たないため、今後1分未満でタスクをスケジュールできないことです。

私はおそらく、schtasksをWindowsに依存せずにlinuxをスリープさせる代わりに、コマンドを実行するためにPythonでマルチスレッドタイマーを書いています。

0

私にとってこのコマンドは、作業罰金:

shutdown /t 10 /s 
+0

/tオプションは、/ l、/ h、または/ pオプションで使用できません。いくつかの奇妙な理由で、/ s以外のものでは動作しません。 –

+0

「利用できません」とはどういう意味ですか?助けに記載されていない?コマンドはそれを拒否する?どのバージョンのウィンドウですか? – user2956477

+0

私はWin10を実行しています。/hまたは/ lを指定してshutdown/tを実行しても、実行されません。代わりに、shutdownコマンドの正しい使用法が一覧表示されます(「help shutdown」を実行した場合と同様)。 [/ hまたは/ l.](https://www.lifewire.com/shutdown-command-2618100)で/ tを実行していることを示すソースが1つしか見つかりません。 –

0

は、だから私はあなたがコマンドウィンドウを表示することを取っていますタイマーが立ち上がると、SHUTDOWNコマンドを実行して終了します。ここで私はどうなるのかです:

echo off 
goto :a 
cls 

:a 
cls 
timeout 10 
cls 

:b 
cls 
shutdown -s >nul 
cls 

また、あなたはSHORTER VERSIONたい場合は、このコマンドを使用できます。

shutdown /t 10 /s 
関連する問題