バッチ ファイルにパラメタが渡らない

Issue #83 closed
MonthlySpecial created an issue
  1. test.cmd ファイルを作成。(添付)
  2. 「Pe 設定」を開く。
  3. [ランチャ] タブでアイテムを作成。

    • 種類: ファイル
    • アイテム名: Test
    • コマンド: [置いた場所]\test.cmd
    • オプション: var1
  4. [ツールバー] タブで、グループに、作成したての「Test」を追加。

  5. [OK] をクリックして「Pe 設定」を閉じる。
  6. ツールバーに現れた「Test」の右端の矢印をクリック。

期待

C:\Windows>echo var1
var1

実際

C:\Windows>echo
ECHO is on.

  • Pe 0.31.0 x64
  • .NET Framework 4.5.1
  • Windows 7 SP1 x64

Comments (18)

  1. sk ☃#QQ repo owner

    ファイルアイテムは現在二つの内部状態を持ちます。

    • 実行ファイル
    • 通常ファイル(とディレクトリ)

    実行ファイルの区別は単純に拡張子で判断しています。

    *.exeであれば実行ファイルの権限として以下を設定可能にしており、通常ファイルは無視されます。

    • 指定して実行
    • 引数
    • 作業ディレクトリ
    • 環境変数
    • 標準入出力リダイレクト

    *.batに対して引数を渡せるように改修するのであれば環境変数PATHEXTを参照するようにしてファイルアイテムに3種類の内部状態を持たせるようにするのが悪くない案かと。

    • 実行ファイル(*.exe)
      • 指定して実行
      • 引数
      • 作業ディレクトリ
      • 環境変数
      • 標準入出力リダイレクト
    • 実行可能ファイル(.EXEを含まない%PATHEXT%)
      • 指定して実行
      • 引数
    • 通常ファイル
      • 通常実行
  2. MonthlySpecial reporter

    ハードコードに近い存在の PATHEXT に強く依存するのはあまり筋がよくないように思います。たとえば、*.lnk にも引数を渡したり、一介の関連付けファイルに作業ディレクトリを指定したかったりします。

    ShellExecute() に渡せるものをあえて削っているのは、何か理由があるのでしょうか。

  3. sk ☃#QQ repo owner

    PATHEXTはその拡張子を持つファイルに対する拡張子抜きで実行可能なファイル名を示すものであるためユーザー環境にうまく適応されると考えています。 ショートカット読み込み処理後の実行パスに対しても適応されるはずです(WindowsなのかExplorerの担当なのかは未調査)。 ですのでここで判定することはシステム環境に依存することであり、現状の .exe 固定よりかは柔軟に処理できます。

    実運用を考えれば exe, com, cmd, bat + %PATHEXT% が妥当案だとは思います。

    ショートカットはショートカットファイル読み込み時にリンク先をアイテムとして登録しますので引数が設定されていればアイテムの設定として引き継ぎます(注意: #68)。 そのため敢えてショートカットを登録した際の処理は未確認です。

    記憶が定かではなく試してもいないんですが ShellExecute(handle, "open", "xxx.bat", "param", "dir", SW_xxx) で実行ファイルでない場合に "param""dir" って有効値扱いでしたっけ?

    削ったのは実装時に「たぶん無視されそうだし設定しなくていいや」程度の理由だったと思います。

    標準入出力とプロセス監視を除外すれば通常ファイルに対する引数, 作業ディレクトリを渡す処理にしても問題ありませんがなるべく上記の妥当案を使用したいです。 管理者権限, 環境変数がどうなるか等の調査も必要ですが渡して無視されるなら渡しても構わないと考えます。

  4. MonthlySpecial reporter

    ショートカットはショートカットファイル読み込み時にリンク先をアイテムとして登録しますので引数が設定されていればアイテムの設定として引き継ぎます(注意: #68)。

    とりあえずこれについては、また別の意味で、困ります。

    たとえば、私のところでは、管理者が、ユーザーには実行ファイルのパスを直接与えず、書き込み不可の *.lnk のパスを与えることによって、実行ファイルのパスやオプションに変更があってもショートカットの中身だけ変更することによって対応することがあります。登録時に実体として解決されてしまうと、こういうスタブとしての柔軟性がなくなってしまいます。

    そのため敢えてショートカットを登録した際の処理は未確認です。

    あまり試していませんが、今のところ問題ないようです。

  5. MonthlySpecial reporter

    記憶が定かではなく試してもいないんですが ShellExecute(handle, "open", "xxx.bat", "param", "dir", SW_xxx) で実行ファイルでない場合に "param" と "dir" って有効値扱いでしたっけ?

    処理可能なときには shell がよしなに処理してくれると思います。

    .cmd

    SHELL32!ShellExecuteExW:
           75ea1dde 8bff            mov     edi,edi
    0:000> dt SHELLEXECUTEINFOW poi(@$csp+4)
    ShellExecuteEx!SHELLEXECUTEINFOW
       +0x000 cbSize           : 0x3c
       +0x004 fMask            : 0x40
       +0x008 hwnd             : (null) 
       +0x00c lpVerb           : 0x01ee13b4  "open"
       +0x010 lpFile           : 0x01ee13be  "p:\test.cmd"
       +0x014 lpParameters     : 0x01ee13d6  "var1"
       +0x018 lpDirectory      : 0x01ee13e0  "p:\dir"
       +0x01c nShow            : 0n3
       +0x020 hInstApp         : (null) 
       +0x024 lpIDList         : (null) 
       +0x028 lpClass          : (null) 
       +0x02c hkeyClass        : (null) 
       +0x030 dwHotKey         : 0
       +0x034 hIcon            : (null) 
       +0x034 hMonitor         : (null) 
       +0x038 hProcess         : (null) 
    0:000> g kernel32!CreateProcessW
    ...
    kernel32!CreateProcessW:
           76f3103d 8bff            mov     edi,edi
    0:001> dpu @$csp+4 l0n10
    0233fa80  00000000
    0233fa84  0056c110 ""P:\test.cmd" var1"
    0233fa88  00000000
    0233fa8c  00000000
    0233fa90  00000000
    0233fa94  04080414
    0233fa98  00000000
    0233fa9c  0055aab0 "p:\dir"
    0233faa0  0233fae4 "H"
    0233faa4  00556738 ""
    0:001> dt STARTUPINFOW 0233fae4 
    MSVCR100D!STARTUPINFOW
       +0x000 cb               : 0x48
       +0x004 lpReserved       : (null) 
       +0x008 lpDesktop        : (null) 
       +0x00c lpTitle          : (null) 
       +0x010 dwX              : 0
       +0x014 dwY              : 0
       +0x018 dwXSize          : 0
       +0x01c dwYSize          : 0
       +0x020 dwXCountChars    : 0
       +0x024 dwYCountChars    : 0
       +0x028 dwFillAttribute  : 0
       +0x02c dwFlags          : 1
       +0x030 wShowWindow      : 3
       +0x032 cbReserved2      : 0
       +0x034 lpReserved2      : (null) 
       +0x038 hStdInput        : (null) 
       +0x03c hStdOutput       : (null) 
       +0x040 hStdError        : (null) 
    

    .txt

    SHELL32!ShellExecuteExW:
           75ea1dde 8bff            mov     edi,edi
    0:000> dt SHELLEXECUTEINFOW poi(@$csp+4)
    ShellExecuteEx!SHELLEXECUTEINFOW
       +0x000 cbSize           : 0x3c
       +0x004 fMask            : 0x40
       +0x008 hwnd             : (null) 
       +0x00c lpVerb           : 0x01e013b4  "open"
       +0x010 lpFile           : 0x01e013be  "p:\test.txt"
       +0x014 lpParameters     : 0x01e013d6  "var1"
       +0x018 lpDirectory      : 0x01e013e0  "p:\dir"
       +0x01c nShow            : 0n3
       +0x020 hInstApp         : (null) 
       +0x024 lpIDList         : (null) 
       +0x028 lpClass          : (null) 
       +0x02c hkeyClass        : (null) 
       +0x030 dwHotKey         : 0
       +0x034 hIcon            : (null) 
       +0x034 hMonitor         : (null) 
       +0x038 hProcess         : (null) 
    0:000> g kernel32!CreateProcessW
    ...
    kernel32!CreateProcessW:
           76f3103d 8bff            mov     edi,edi
    0:001> dpu @$csp+4 l0n10
    023af7f8  003083ec "C:\Windows\system32\NOTEPAD.EXE"
    023af7fc  0030af30 ""C:\Windows\system32\NOTEPAD.EXE" P:\test.txt"
    023af800  00000000
    023af804  00000000
    023af808  00000000
    023af80c  04080414
    023af810  00000000
    023af814  0030aab0 "p:\dir"
    023af818  023af85c "H"
    023af81c  00306738 ""
    

    拡張子の判断ふくめ shell がものすごく努力してやってくれるわけで、であれば、アプリケーション側で拡張子を判断するのはなるべく控えて、伝えられるものはすべて shell に伝えて shell のよしなに任せるのを本則にして、どうしても必要なときだけしかたなく CreateProcess() するのがよいのではないでしょうか。

  6. MonthlySpecial reporter

    肝心な .lnk の例が抜けてました。

    SHELL32!ShellExecuteExW:
           75ea1dde 8bff            mov     edi,edi
    0:000> dt SHELLEXECUTEINFOW poi(@$csp+@$ptrsize)
    ShellExecuteEx!SHELLEXECUTEINFOW
       +0x000 cbSize           : 0x3c
       +0x004 fMask            : 0x40
       +0x008 hwnd             : (null) 
       +0x00c lpVerb           : 0x008913b4  "open"
       +0x010 lpFile           : 0x008913be  "p:\test.lnk"
       +0x014 lpParameters     : 0x008913d6  "var1"
       +0x018 lpDirectory      : 0x008913e0  "p:\dir"
       +0x01c nShow            : 0n3
       +0x020 hInstApp         : (null) 
       +0x024 lpIDList         : (null) 
       +0x028 lpClass          : (null) 
       +0x02c hkeyClass        : (null) 
       +0x030 dwHotKey         : 0
       +0x034 hIcon            : (null) 
       +0x034 hMonitor         : (null) 
       +0x038 hProcess         : (null) 
    0:000> g kernel32!CreateProcessW
    ...
    kernel32!CreateProcessW:
           76f3103d 8bff            mov     edi,edi
    0:001> dpu @$csp+@$ptrsize l0n10
    00d3ea00  002b8bf4 "C:\Windows\System32\notepad.exe"
    00d3ea04  002418d0 ""C:\Windows\System32\notepad.exe" var1"
    00d3ea08  00000000
    00d3ea0c  00000000
    00d3ea10  00000000
    00d3ea14  04080414 "stall them as you shut down your computer?'AUTOMATICALL"
    00d3ea18  00000000
    00d3ea1c  002ae120 "C:\Windows"
    00d3ea20  00d3ea64 "H"
    00d3ea24  002b6f40 ""
    
  7. sk ☃#QQ repo owner

    おおぉ・・・、調査どうもです。

    まずショートカットファイルの登録時の挙動については別課題としておきます。

    #85: ショートカットファイルの登録処理


    ほー。内部的にCreateProcess呼ばれるんですね。 当然っちゃ当然ですが初めて知りました。

    ならば登録されているパラメータはそのまま使用してお後は.NETとWindowsに丸投げしましょうか。

    ちなみに作業簡略化のためリダイレクトについては今回課題ではあまり注視せず実装を行います。 必要であれば別課題でopenということで。

    これでよろしければ open しますがどうでしょうか。

  8. MonthlySpecial reporter

    ご検討ありがとうございます。

    はい。verb なしで、パラメタをみな shell に渡していただけると、自由度と互換性の面で、ありがたいです。

  9. sk ☃#QQ repo owner

    f0edf312ffbb7b9905e03409c317308c6f7060a6

    verb なしという意見ですがExplorer(実質シェル)ではexe, bat, comが管理者として実行可能であったためシェル操作に合わせるためその拡張子ファイルはverbへのrunas指定を許可しています。 runas指定時の挙動はシステムの制約もありますが現行と同じ引数のみとなります。

    runasが未指定でファイルアイテムの場合は各種設定は有効となりますがあくまで本ソフトウェアの処理可能範囲で有効であり実行環境であるWindows/.NET上での有効保障ではありません。

  10. sk ☃#QQ repo owner

    通常ファイルのリダイレクト関係に不備がありますが本改修による影響でありrc-0.32.0ブランチのリリース前に修正を行います。

  11. MonthlySpecial reporter

    verb なしというのは、もし open 固定だと、既定の verb が無視されて困るので申し上げました。runas を指定することは問題ないと思います。

    runas指定時の挙動はシステムの制約もありますが現行と同じ引数のみとなります。

    ruans のときに引数だけが使われるわけではないので、制限することなく渡せるものは渡していただけるとありがたいです。

    SHELL32!ShellExecuteExW:
           76451dde 8bff            mov     edi,edi
    0:000> dt SHELLEXECUTEINFOW poi(@$csp+@$ptrsize)
    ShellExecuteEx!SHELLEXECUTEINFOW
       +0x000 cbSize           : 0x3c
       +0x004 fMask            : 0x40
       +0x008 hwnd             : (null) 
       +0x00c lpVerb           : 0x00201314  "runas"
       +0x010 lpFile           : 0x00201320  "notepad.exe"
       +0x014 lpParameters     : 0x00201338  "var1"
       +0x018 lpDirectory      : 0x00201342  "p:\dir"
       +0x01c nShow            : 0n3
       +0x020 hInstApp         : (null) 
       +0x024 lpIDList         : (null) 
       +0x028 lpClass          : (null) 
       +0x02c hkeyClass        : (null) 
       +0x030 dwHotKey         : 0
       +0x034 hIcon            : (null) 
       +0x034 hMonitor         : (null) 
       +0x038 hProcess         : (null) 
    0:000> g shell32!RAiLaunchAdminProcess
    ...
    SHELL32!RAiLaunchAdminProcess:
           7650db93 8bff            mov     edi,edi
    0:001> dpu @$csp+@$ptrsize l0n13
    00def44c  00def490 "D"
    00def450  0075ce30 "夰疞췯覫"
    00def454  007599fc "P:\dir\notepad.exe"
    00def458  0076bc70 ""P:\dir\notepad.exe" var1"
    00def45c  00000019
    00def460  04000410
    00def464  007720c0 "p:\dir"
    00def468  0075d910 "WinSta0\Default"
    00def46c  00def4fc ""
    00def470  00000000
    00def474  ffffffff
    00def478  00757d48 ""
    00def47c  00def548 "."
    
  12. MonthlySpecial reporter

    Explorer(実質シェル)ではexe, bat, comが管理者として実行可能であったためシェル操作に合わせるためその拡張子ファイルはverbへのrunas指定を許可しています。

    技術的制限以外の事情で、runas できるものを限る必要はないのではないでしょうか。shell も runas させる拡張子をハードコードして判定しているわけではありませんし。現に、Explorer からは上記拡張子以外に一般ユーザーが MMC ファイル (.msc) も runas できますし、このような拡張子は将来も増減することと思います。また、インストールしたアプリケーションによっても異なるかと思います。そうした対応をするのに、コード変更が必要になってしまいます。

    …横槍が多くてすみません。

  13. sk ☃#QQ repo owner

    runasした際に渡した引数以外がことごとく闇に飲まれていったようなあてにならない記憶があったのでなるべく触らないようにしていたのですが、うーん、大丈夫そうですしrunasはどれも有効にしましょうか。

    管理者実行の可能判定はレジストリのどっかで行われていたので暇があったら調べてみます。

    というわけで open します。

  14. MonthlySpecial reporter

    Verified on 0.32.0.38771 x64

    おかげで柔軟に使えるようになりました。ありがとうございます。

  15. Log in to comment