コマンドラインから呼び出されたときに正しく機能しているにもかかわらず、ショートカットから呼び出されたときにこのバッチファイルがすぐに閉じるのはなぜですか?

スカム

編集3(解決策):

以下のようmichael_heathはショートカットを通じて何かを実行するときにWindowsがコマンドを構築する方法を正確に、そして非常に具体的な(と率直に言ってとんでもない)の結果:彼の答えで説明し、問題は2つのことに降りてきた\C上のスイッチcmd.exe将来の参考のために、他の貧しい人々がこのStackOverflowの質問に遭遇した場合、ショートカットの「Target」プロパティをMichaelの回答のわずかに編集されたバージョンに変更することで問題を修正しましたC:\Windows\System32\cmd.exe /C @"C:\{path-to-script}\link.bat"残念ながら、ターゲットライン全体を表示することはできませんが、必要に応じてスクリーンショットも示します。

マイケルに改めて感謝します。


「送信先...>デスクトップ」がショートカットで機能するのとほぼ同じ方法で、デスクトップにシンボリックリンクを作成するためのパーソナルバッチユーティリティを作成しようとしています。シンボリックリンクを頻繁に使用して、bash構成ファイル(.bashrcや.bash_profileなど)のようなものを、移植性やコンピューター上の他のいくつかのもののために他の場所でバージョン管理できるようにします。

使いやすさのために、私のアイデアは、これを行うための簡単なバッチファイルを作成し、デスクトップにシンボリックリンクを配置することでした。次に、このファイルへのショートカットを[送信先]フォルダーに配置して、コンテキストメニューの[送信先]に表示します(mklinkには管理者権限が必要であるため、ショートカットは管理者としても実行するように設定されています)。

以下は私が書いたファイルです:

@echo off

set f=%~1
set switch=
if exist "%f%\*" set switch=/D

for /F "delims=" %%i in ("%f%") do set name=%%~nxi

mklink %switch% "%USERPROFILE%\Desktop\%name%" "%f%"
if not %ERRORLEVEL%==0 pause

これが私がやろうとしていることの一般的な考え方です:

  1. 入力の引用符がある場合は削除します(%〜1)
  2. 入力がディレクトリかどうかを確認します
  3. 入力のベース名とファイル拡張子を取得します(%% 〜nxi)
  4. リンクを張る
  5. エラーが発生した場合は、終了するのではなく表示されるように一時停止します(バッチファイルはショートカットから呼び出されるため)

ファイルまたはディレクトリの名前にスペースを含む入力を与えるまでは、完全に正常に機能します。パスにスペースが含まれているが、実際のファイルまたはディレクトリのベース名にはないディレクトリがある場合にどうなるかは実際にはテストしていませんが、同じ問題が発生すると思います。

スペースを含むファイルで機能するようにいくつかの変更を加えました。たとえば、最初の行の入力の引用符を削除して、後で引用符が2倍にならないようにしたり、forループの「delims =」を削除したりしました。実際、ここで見つけた2つの解決策。

しかし、最善を尽くしても、何をしても、スペースを入力するとすぐにファイルが閉じます。私はすべての行にpausesを散らかし、手動で入力した入力を使用してコマンドラインからスクリプトを実行し、終了しないようにし、コマンドラインから個々のコマンド(可能な場合)を実行しました。

腹立たしいことに、コマンドラインから実行したり、個々のコマンドを実行したりすると、入力にスペースがあってもすべて完全に機能します。受信した入力を出力するだけの別のバッチファイルを作成、Send Toから実行て、入力がコマンドラインから入力したものと同じであることを確認しました。

Send Toのショートカットから呼び出されたときに、いったい何がうまくいかないのでしょうか。


編集1:ショートカット自体のプロパティは次のとおりです。

  • ターゲット:C:\ Users {username} \ vc \ git \ util-scripts \ bat \ link.bat
  • 開始場所:C:\ Users {username} \ vc \ git \ util-scripts \ bat

これもスクリーンショットです:

ここでアカウントを作成したので、画像を埋め込むことはできませんが、ここにあります


編集2:これは、Gerhard Barnardによって提案されたように、私が使用している現在のコードですが、問題は依然として解決しません。

@echo off

set "fname=%~1"
set switch=
if exist "%fname%\.*" set "switch=/D"

for /F "delims=" %%i in ("%fname%") do (
    mklink %switch% "%USERPROFILE%\Desktop\%%~nxi" "%fname%"
    if errorlevel 1 pause
)
michael_heath
@echo off
setlocal

rem Set the path for the created symlink.
set "linkdir=%USERPROFILE%\Desktop"

for %%A in (%*) do call :link "%%~A"

rem Check results.
echo: & dir /A:L "%linkdir%" & pause
exit /b

:link
set "switch="
if exist "%~1\*" set "switch=/D"
for /F "delims=" %%A in ("%~1") do set "name=%%~nxA"
if not defined name echo Variable "name" not defined.& exit /b 1
mklink %switch% "%linkdir%\%name%" "%~1"
exit /b 0

バッチファイルコードが機能しています。このコードは、複数のファイルまたはフォルダーを実行します。このコードは、ファイル、フォルダー、シンボリックリンクされたファイル、およびシンボリックリンクされたフォルダーをターゲットとして一度にテストするのにも役立ちました。

1つのターゲットのみを処理する場合は、をに変更%*"%~1"ます。

主な問題は、ショートカットのコマンド文字列です。

C:\Users\{username}\vc\git\util-scripts\bat\link.bat

のファイルタイプは.bat、次のようなコマンドを作成します。

C:\Windows\System32\cmd.exe /C "C:\Users\{username}\vc\git\util-scripts\bat\link.bat" %*

%* 渡された引数に置き換えられます。

二重引用符付きの引数を持つコマンドがある場合、次のようになります。

C:\Windows\System32\cmd.exe /C "C:\Users\{username}\vc\git\util-scripts\bat\link.bat" "C:\Users\a file.txt"

後のコマンド文字列に/Cは4つの二重引用符があり、両端に二重引用符があります。二重引用符により動作が変わります。

からの引用cmd /?

If /C or /K is specified, then the remainder of the command line after
the switch is processed as a command line, where the following logic is
used to process quote (") characters:

    1.  If all of the following conditions are met, then quote characters
        on the command line are preserved:

        - no /S switch
        - exactly two quote characters
        - no special characters between the two quote characters,
          where special is one of: &<>()@^|
        - there are one or more whitespace characters between the
          two quote characters
        - the string between the two quote characters is the name
          of an executable file.

    2.  Otherwise, old behavior is to see if the first character is
        a quote character and if so, strip the leading character and
        remove the last quote character on the command line, preserving
        any text after the last quote character.

セクション1では、「/ Sスイッチなし」が真であり、次は「正確に2つの引用符」であり、これは偽です。これはセクション2に適用/Cされ、二重引用符を削除した後にコマンド文字列を作成できます。

C:\Users\{username}\vc\git\util-scripts\bat\link.bat" "C:\Users\a file.txt

残りは公開されていますが、スペースは引用符で囲まれています。これは、この場合は無効なコマンド文字列です。これC:\Users\a file.txtは、二重引用符で囲まれた渡された引数の例であることに注意してください"C:\Users\a file.txt"

次のショートカットのコマンド文字列の変更:

C:\Windows\System32\cmd.exe /C echo: & "C:\Users\{username}\vc\git\util-scripts\bat\link.cmd"

コマンドはC:\Windows\System32\cmd.exe、コマンド文字列でさらに制御できるようになりました。の後は/Cecho:コマンド文字列が二重引用符で始まらないようにするために使用されます。これは、コマンド文字列が二重引用符で始まらないため、両端で二重引用符が削除されるのを防ぐのに役立ちます。&は重要なコマンドであり、引数が二重引用符で終わっていても機能するようになりました。

echo: &を別の初期コマンドに置き換えることができます。@コマンド文字列の前に使用することもできるため、ショートカットコマンド文字列は次のようになります。

C:\Windows\System32\cmd.exe /C @"C:\Users\{username}\vc\git\util-scripts\bat\link.cmd"

したがって、ユースケースに最適なものは何でも。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ