none
batファイルからPowerShell引数にspaceのあるパスを渡したい

    質問

  • お世話になります。

    batファイルを使って、Program Files内でファイルをコピー&ペーストするのが目的で

    スクリプトを作ったのですが、powershellの引数設定がうまく行かず悩んでいます。

    管理者権限を回避するため、2つのbatファイルを用意し、一方のファイルから

    powershellのStart-Processを使ってもう一方のファイルを呼び出してコピーを行う方法で

    以下のように記述しています。

    <file1.bat>

    powershell.exe -Command Start-Process .\file2.bat  '%1 %2'  -Verb Runas

    <file2.bat>

    copy %1 %2

    2つの引数に指定するパスにスペースが含まれていない場合は、これでうまく行くのですが

    「Program Files」にはスペースが含まれているため、「C:\Program」の所までで第一引数と認識されてしまい

    うまくパスを渡せません。

    ダブルクォーテーションで囲む、「&」を付ける、バッククォート(`)で無効化・・・等、ネットで調べられる限りの工夫をしてみましたが

    いずれも効果がないかエラーになるかのどちらかで、正解は見つかりませんでした。

    何かうまい方法はないでしょうか。よろしくお願い致します。


    2018年3月26日 8:47

すべての返信

  • powershell -Command "Start-Process .\file2.bat '"""%1""" """%2"""'" -verb Runas

    copy "%1" "%2"

    でどうでしょう。

    // エスケープやらなんやらで大変なことになってますなぁ。

    2018年3月26日 11:10
  • Hongliang様

    回答ありがとうございます。

    下記の通り記述してやってみましたが、うまくいきませんでした。

    <file1.bat>

    powershell -Command "Start-Process .\file2.bat '"""%1""" """%2"""'" -verb Runas

    <file2.bat>

    copy "%1" "%2"

    <コマンドプロンプト>

    方法1:file1.bat C:\Program Files\Test\test1.txt C:\Program Files\Test\test2.txt

    方法2:file1.bat "C:\Program Files\Test\test1.txt" "C:\Program Files\Test\test2.txt"

    方法1では、file1.bat実行時点で引数のパスがスペースで分割されてしまい、

    方法2では、単なる文字列として認識されてしまう様です。


    2018年3月27日 1:02
  • こんな感じかな…?

    file1.bat

    set bat2="""""%~dp0bat2.bat"""""
    PowerShell -Command "Start-Process -Verb RunAs cmd.exe '/c %bat2% ""%1"" ""%2"""""'"
    file2.bat
    copy %1 %2
    2018年3月27日 4:02
  • 順に説明します。

    「copy %1 %2」の引数 %1、%2が正しく分割されるためにはここで渡されるパス文字列は "" で括られている必要があります。つまり

    .\file2.bat "%~1" "%~2"

    でコマンドが起動される必要があります。次にPowerShellのコマンドレットStart-Processでこのようなプロセスを起動するには '' か "" で括られている必要があります。つまり

    Start-Process .\file2.bat '"%~1" "%~2"'
    Start-Process .\file2.bat "`"%~1`" `"%~2`""

    どちらかですが、""で括る場合、 " を ` でエスケープする必要が生じるので '' の方が楽です。次にPowerShellのコマンドライン引数で上記コマンドレットを実行する方法ですが、コマンドライン引数解析で分割されてしまわないよう "" で括る必要があります。つまり

    powershell.exe -Command Start-Process .\file2.bat "'\"%~1\" "%~2\"'"

    とします。"" で括った場合の " を \ でエスケープする必要があります(コマンドライン引数のエスケープであり通常の ` エスケープとは異なります)。質問では通常のプロセス起動でなくRunAsとのことで、HKEY_CLASSES_ROOT\batfile\shell\runas\commandには

    %SystemRoot%\System32\cmd.exe /C "%1" %*

    と登録されています。%*なので引数がそのまま引き継がれるはずなのですが、手元の環境ではなぜかbatファイルが起動されませんでした。仕方がないので cmd /c をもう一段はさみます。最終的に

    powershell.exe -Command Start-Process cmd "'/c C:\path\to\file2.bat \"%~1\" \"%~2\"'" -Verb Runas

    こうなります。カレントディレクトリが引き継がれないので file2.bat はフルパスで記述する必要があります。

    2018年3月27日 4:12
  • このままですと、file2.bat に空白を含める事が出来ないので


    powershell.exe -Command Start-Process cmd "'/c,\"C:\path\t o\file2.bat\" \"%~1\" \"%~2\"'" -Verb Runas
    

    これでよろしいかと。

    2018年3月27日 8:34