2016-06-18 8 views
1

おそらく簡単な答えですが、オンラインで見つけることはできません。新しく開いたCMDウィンドウの上にバッチスクリプトのCMDウィンドウを保存する

私はいくつかのプログラムを開くための.batスクリプトを持っており、またそれがすべて正常に動作し、ユーザー入力(Y [N])を望んでいます。

私の質問です。

新しく開いたウィンドウの上にスクリプトウィンドウを保持するにはどうすればよいですか。ユーザーはスクリプトが入力を探しているのを見ることができます。

@ECHO OFF 
REM 2016-06-17 GMAN 

REM Start Zookeeper 
cd zookeeper-3.4.8 
CALL StartZookeeper.bat 

REM Give Zookeeper a chance to start 
sleep 4 

REM Start Kafka 
cd ..\kafka_2.11-0.10.0.0 
CALL StartKafka.bat 

REM Give Kafka a chance to start 
sleep 2 

setlocal 
:PROMPT 
SET /p prodCons="Open a CMD for Producer and Consumer: (Y/[N]"?) 
echo You entered: %prodCons% 
sleep 1 

IF /I "%prodCons%" NEQ "Y" GOTO END 

REM Producer Terminal 
start cmd.exe /k "TITLE Producer && cd .\kafka_2.11-0.10.0.0\bin\windows" 

REM Consumer Terminal 
start cmd.exe /k "TITLE Consumer && cd .\kafka_2.11-0.10.0.0\bin\windows" 

:END 
endlocal 

ユーザーが常にオントップフラグを設定する

+0

ところで、「スリープ」は、内部または外部のコマンド、操作可能なプログラム、またはバッチファイルとして認識されません。「タイムアウト/ t 4/nobreak> NUL'ですか? – rojo

答えて

0

一つの方法は、SetWindowPos() function from user32.dllをインポートし、その引数でそれを呼び出すことであるYまたはNを入力するために見ることができるように私のスクリプトウィンドウが新しいCMDの背後に隠されています:

  • がHWND_TOPMOSTにウィンドウ親設定(-1)
  • スキップリサイズ/ SWP_NOMOVE(0×01)とSWP_NOSIZEでウィンドウを移動させる(0×02)フラグ

は、純粋なバッチでこれを行う方法はありませんが、あなたはPowerShellが力仕事を行うことができます。ここでは、一番上に常にコンソールを作るためにあなたのバッチコードを貼り付けることができますそこにバット+ PowerShellのハイブリッドスクリプトテンプレートです:

一つでもするかどうかを決定するために、拡張ウィンドウスタイルを照会する GetWindowLong()を使用することができます
<# : AlwaysOnTop.bat -- http://stackoverflow.com/a/37912693/1683264 
@echo off & setlocal 

rem // Relaunch self in PowerShell to run this window Always On Top 
powershell -noprofile "iex (${%~f0} | out-string)" 

rem /* ############################### 
rem Your main batch code goes here. 
rem ############################### */ 

goto :EOF 
rem // end batch/begin PowerShell hybrid code #> 

# // Solution based on http://stackoverflow.com/a/34703664/1683264 
add-type user32_dll @' 
    [DllImport("user32.dll")] 
    public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, 
     int x, int y, int cx, int cy, uint uFlags); 
'@ -namespace System 

# // Walk up the process tree until we find a window handle 
$id = $PID 
do { 
    $id = (gwmi win32_process -filter "ProcessID='$id'").ParentProcessID 
    $hwnd = (ps -id $id).MainWindowHandle 
} while (-not $hwnd) 

$rootWin = [IntPtr](-1) 
$topmostFlags = 0x0003 
[void][user32_dll]::SetWindowPos($hwnd, $rootWin, 0, 0, 0, 0, $topmostFlags) 

ウィンドウは常に上に常に設定されています - そしてそれをトグルします。

<# : AlwaysOnTop2.bat -- http://stackoverflow.com/a/37912693/1683264 
@echo off & setlocal 

call :toggleAlwaysOnTop 

rem /* ############################### 
rem Your main batch code goes here. 
rem ############################### */ 

goto :EOF 

:toggleAlwaysOnTop 
powershell -noprofile "iex (${%~f0} | out-string)" 
goto :EOF 
rem // end batch/begin PowerShell hybrid code #> 

add-type user32_dll @' 
    [DllImport("user32.dll")] 
    public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, 
     int x, int y, int cx, int cy, uint uFlags); 

    [DllImport("user32.dll")] 
    public static extern int GetWindowLong(IntPtr hWnd, int nIndex); 
'@ -namespace System 

$id = $PID 
do { 
    $id = (gwmi win32_process -filter "ProcessID='$id'").ParentProcessID 
    $hwnd = (ps -id $id).MainWindowHandle 
} while (-not $hwnd) 

$style = [user32_dll]::GetWindowLong($hwnd, -20) 
# // If flag 0x08 is set, make parent HWND -2 to unset it. Otherwise, HWND -1 to set it. 
[IntPtr]$rootWin = ($style -band 0x08)/-8 - 1 
[void][user32_dll]::SetWindowPos($hwnd, $rootWin, 0, 0, 0, 0, 0x03)