2017-12-19 13 views
0

目的:私は、ユーザーがただ1つの文字(任意の文字)を入力し、 "enter"キーの追加キーストロークなしで即座に応答します。ユーザーが以前に入力した文字を入力せずにキーを入力すると、スクリプトは応答しません。どのように表示された単一の文字を入力し、すぐにバッチCMDで処理する

私はこのコードで立ち往生しています:

@Echo Off 

SET Alnum=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 

:: ordinary symbol string would not work! 
:: it must be escaped, but i don't know how. 
SET Symbol= 

SETLOCAL EnableExtensions EnableDelayedExpansion 

CALL :CharInput "Type one char: " 
ECHO Your input was: "!RetVal!" 
ECHO(

CALL :CharInput "one more char: " 
ECHO Your input was: "!RetVal!" 
ECHO(

CALL :CharInput "still need more: " 
ECHO Your input was: "!RetVal!" 
ECHO(

GOTO :eof 


:: @param1 %~1  message to print 
:: @return RetVal the single character entered by user 
:CharInput 
    IF "" == "!VisibleChars!" (
     CALL :CharacterizedWord "%Alnum%%Symbol%" 
     SET VisibleChars=!RetVal! 
    ) 
    SET /P "=%~1" < Nul 

    SET Found=false 

    FOR /F "skip=1" %%# IN ('REPLACE "%~f0" . /U /W') DO SET "CHR=%%#" 
    SET /P "=!CHR!" <Nul 

    FOR %%a in (!VisibleChars!) DO (
     IF "%%a" == "!CHR!" (
      SET Found=true 
     ) 
    ) 

    :: needs work around to make the script print only 1 message 
    :: each time the user presses the "enter" key 
    :: without any visible characters previously entered 
    IF "false" == "!Found!" (
     ECHO(
     GOTO :CharInput 
    ) ELSE (
     SET "RetVal=!CHR!" 
     ECHO(
    ) 
GOTO :eof 


:: @param1 %~1  the word being characterized 
:: @return RetVal the string contains words each of single character 
:CharacterizedWord 
    SET Word=%~1 
    SET tempstr=%~1 
    SET count=0 
    :CharacterizedWordLoop 
    IF DEFINED tempstr (
     SET tempstr=%tempstr:~1% 
     SET /a count+=1 
     SET /a pos=%count%-1 
     SET RetVal=!RetVal! !Word:~%pos%,1! 
     GOTO :CharacterizedWordLoop 
    ) 
GOTO :eof 
  1. 私は一つの単語にすべてのシンボル文字を収集するための任意の組み合わせを試してみました。誰も私が "シンボル" varの空を埋めるのを助けることができますか?

  2. 新しい文字が見つかるたびにリストを編集せずに可視の文字リストを拡張するには、これ以外のアルゴリズムはありますか?

  3. このアプリは、ユーザーが「入力」キーを押すたびに「タイプ1のチャット」メッセージを表示します。誰でもこれを修正できますか?

+2

https://stackoverflow.com/questions/13166100/how-can-i-return-a-single-character-from-the-console-in-a-batch-script-without-p CHOICE – Ctznkane525

+0

@ジョン・ケイン:記号はどうですか?ネイティブの選択はシンボルをサポートしていません。 –

+3

これには、選択時に特殊文字を使用する方法に関する情報があります。それは技術的にはサポートされていませんが、回避策はhttps://stackoverflow.com/questions/41456194/how-to-use-special-characters-in-choice-command-batch-file – Ctznkane525

答えて

0

コンソールでは、$ホストのReadKeyメソッドを使用して、Enterキーが不要な単一のキーを読み取ることができます。これはあなたが望むような何かをしますか?

"thekey.ps1"というファイルに入れます。

<# Ignore: 
    Enter 
    Shift 
    Ctrl 
    Alt 18 
    CapsLock 
    LeftArrow 
    RightArrow 
    UpArrow 
    DownArrow 
    Delete 
    End 35 
    Home 36 
    Insert 45 
    PgUp 33 
    PgDown 34 
    Windows 91 
#> 

$nowatch = $(13, 16, 17, 18, 20, 37, 38, 39, 40, 46, 35, 36, 45, 33, 34, 91) 

do { 
    $key = $host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown') 

    #$key.VirtualKeyCode 

    $vkc = $key.VirtualKeyCode 
    $k = $key.Character 
} while ($nowatch -contains $vkc) 
$k 

あなたは、発見#$key.VirtualKeyCodeからのコメント「#」を削除して実行します。\ thekey.ps1 PowerShellコンソール(ないISE)にする必要がある他のキーがある場合。

"thekey.bat"というファイルに入れます。また

@ECHO OFF 
:Head 
FOR /F "usebackq tokens=*" %%k IN (`powershell -NoProfile -File .\thekey.ps1`) DO (
    SET "THEKEY=%%k" 
) 
ECHO THEKEY is %THEKEY% 
GOTO Head 

あなたがいないこれらのではなく、認識したいキーを指定する方が簡単かもしれません。

$keylist = @() 
0x21..0x7E | ForEach-Object { $keylist += $_ } 

do { 
    $key = $host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown') 

    #$key.VirtualKeyCode 

    $vkc = $key.VirtualKeyCode 
    $k = $key.Character 
} while ($keylist -notcontains $vkc) 
$k 
+0

スクリプトはすぐに「押された」キーに応答しますコンパニオンキーの前に "THEKEY is"が何度か印字されます。これは私が望む行動ではありません。 –

+0

@thethe金属 - 私はコードに行った改正を確認してください。私はこれがあなたが求めているものに近いことを望みます。 – lit

関連する問題