バッチ ファイルにパラメタが渡らない
- test.cmd ファイルを作成。(添付)
- 「Pe 設定」を開く。
-
[ランチャ] タブでアイテムを作成。
- 種類: ファイル
- アイテム名: Test
- コマンド:
[置いた場所]\test.cmd
- オプション:
var1
-
[ツールバー] タブで、グループに、作成したての「Test」を追加。
- [OK] をクリックして「Pe 設定」を閉じる。
- ツールバーに現れた「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)
-
repo owner -
reporter ハードコードに近い存在の PATHEXT に強く依存するのはあまり筋がよくないように思います。たとえば、*.lnk にも引数を渡したり、一介の関連付けファイルに作業ディレクトリを指定したかったりします。
ShellExecute() に渡せるものをあえて削っているのは、何か理由があるのでしょうか。
-
repo owner PATHEXT
はその拡張子を持つファイルに対する拡張子抜きで実行可能なファイル名を示すものであるためユーザー環境にうまく適応されると考えています。 ショートカット読み込み処理後の実行パスに対しても適応されるはずです(WindowsなのかExplorerの担当なのかは未調査)。 ですのでここで判定することはシステム環境に依存することであり、現状の.exe
固定よりかは柔軟に処理できます。実運用を考えれば exe, com, cmd, bat + %PATHEXT% が妥当案だとは思います。
ショートカットはショートカットファイル読み込み時にリンク先をアイテムとして登録しますので引数が設定されていればアイテムの設定として引き継ぎます(注意:
#68)。 そのため敢えてショートカットを登録した際の処理は未確認です。記憶が定かではなく試してもいないんですが
ShellExecute(handle, "open", "xxx.bat", "param", "dir", SW_xxx)
で実行ファイルでない場合に"param"
と"dir"
って有効値扱いでしたっけ?削ったのは実装時に「たぶん無視されそうだし設定しなくていいや」程度の理由だったと思います。
標準入出力とプロセス監視を除外すれば通常ファイルに対する引数, 作業ディレクトリを渡す処理にしても問題ありませんがなるべく上記の妥当案を使用したいです。 管理者権限, 環境変数がどうなるか等の調査も必要ですが渡して無視されるなら渡しても構わないと考えます。
-
reporter ショートカットはショートカットファイル読み込み時にリンク先をアイテムとして登録しますので引数が設定されていればアイテムの設定として引き継ぎます(注意:
#68)。とりあえずこれについては、また別の意味で、困ります。
たとえば、私のところでは、管理者が、ユーザーには実行ファイルのパスを直接与えず、書き込み不可の *.lnk のパスを与えることによって、実行ファイルのパスやオプションに変更があってもショートカットの中身だけ変更することによって対応することがあります。登録時に実体として解決されてしまうと、こういうスタブとしての柔軟性がなくなってしまいます。
そのため敢えてショートカットを登録した際の処理は未確認です。
あまり試していませんが、今のところ問題ないようです。
-
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() するのがよいのではないでしょうか。
-
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 ""
-
repo owner おおぉ・・・、調査どうもです。
まずショートカットファイルの登録時の挙動については別課題としておきます。
#85: ショートカットファイルの登録処理
ほー。内部的に
CreateProcess
呼ばれるんですね。 当然っちゃ当然ですが初めて知りました。ならば登録されているパラメータはそのまま使用してお後は.NETとWindowsに丸投げしましょうか。
ちなみに作業簡略化のためリダイレクトについては今回課題ではあまり注視せず実装を行います。 必要であれば別課題でopenということで。
これでよろしければ open しますがどうでしょうか。
-
reporter ご検討ありがとうございます。
はい。verb なしで、パラメタをみな shell に渡していただけると、自由度と互換性の面で、ありがたいです。
-
repo owner - changed status to open
-
repo owner - changed status to resolved
f0edf312ffbb7b9905e03409c317308c6f7060a6
verb なしという意見ですがExplorer(実質シェル)ではexe, bat, comが管理者として実行可能であったためシェル操作に合わせるためその拡張子ファイルは
verb
へのrunas
指定を許可しています。runas
指定時の挙動はシステムの制約もありますが現行と同じ引数のみとなります。runas
が未指定でファイルアイテムの場合は各種設定は有効となりますがあくまで本ソフトウェアの処理可能範囲で有効であり実行環境であるWindows/.NET上での有効保障ではありません。 -
repo owner 通常ファイルのリダイレクト関係に不備がありますが本改修による影響でありrc-0.32.0ブランチのリリース前に修正を行います。
-
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 "."
-
reporter Explorer(実質シェル)ではexe, bat, comが管理者として実行可能であったためシェル操作に合わせるためその拡張子ファイルはverbへのrunas指定を許可しています。
技術的制限以外の事情で、runas できるものを限る必要はないのではないでしょうか。shell も runas させる拡張子をハードコードして判定しているわけではありませんし。現に、Explorer からは上記拡張子以外に一般ユーザーが MMC ファイル (.msc) も runas できますし、このような拡張子は将来も増減することと思います。また、インストールしたアプリケーションによっても異なるかと思います。そうした対応をするのに、コード変更が必要になってしまいます。
…横槍が多くてすみません。
-
repo owner runasした際に渡した引数以外がことごとく闇に飲まれていったようなあてにならない記憶があったのでなるべく触らないようにしていたのですが、うーん、大丈夫そうですしrunasはどれも有効にしましょうか。
管理者実行の可能判定はレジストリのどっかで行われていたので暇があったら調べてみます。
というわけで open します。
-
repo owner - changed status to open
-
repo owner - changed status to resolved
-
reporter - changed status to closed
Verified on 0.32.0.38771 x64
おかげで柔軟に使えるようになりました。ありがとうございます。
-
repo owner - removed component
Removing component: PeMain (automated comment)
- Log in to comment
ファイルアイテムは現在二つの内部状態を持ちます。
実行ファイルの区別は単純に拡張子で判断しています。
*.exe
であれば実行ファイルの権限として以下を設定可能にしており、通常ファイルは無視されます。*.bat
に対して引数を渡せるように改修するのであれば環境変数PATHEXT
を参照するようにしてファイルアイテムに3種類の内部状態を持たせるようにするのが悪くない案かと。.EXE
を含まない%PATHEXT%
)