eamat @Cabinet
Path2.ahk(旧)
最終更新:
eamat
-
view
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
/************************************************************************
ファイルパス関数群 2 実在のパスを探す系 (全角ダメ文字問題も一応考慮) ※ AHKでのダメ文字問題は Loop(files) などの 文字列切出し関係で起こる。 IfExist / FileExist()での判定自体は問題ない。 グローバル変数 : なし 各関数の依存性 : なし(必要関数だけ切出してコピペでも使えます) AutoHotkey Version: 1.0.48.03 Language: Japanease Platform: Win NT (psapi.DLL使用) Author: eamat. ************************************************************************ 2009.01.23 Path2_ExtractPath() "c:\program files\hoge.txt - メモ帳" のような場合の取得対応 2009.01.18 Path2_GetTempFileName() 2009.07.01 Path2_ExtractPath() RegEx調整他 2009.07.26 Path2_GetTempFileName() コメント修正他 2009.10.23 _Path2_sample() 追加 2012.11.11 Path2_ProcessExeNameNT() → Path2_GetExecutablePath() 名称変更 */ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; 動作確認用 内部ルーチン ; 単体起動時のテスト用なので削除しても問題なし
_Path2_AutoExecute_Sample:
_Path2_sample(); _Path2_test() return _Path2_sample() {
buf := "c:\予定表\予\予定表.xls";APIやRegExチェックが面倒な時は、 ;ファイルパスにもSJISにも被らない記号に一旦変換する buf := RegExReplace(buf,"(?<=[^\x80-\x9F\xE0-\xFC])\\","|") ;\ を | に変更 Loop,parse,buf,| { msgbox,%A_LoopField% } } _Path2_test() {
;--- 有効パスサーチ関数 のテスト
---p := A_WinDir " """ A_ProgramFiles """ [" A_Temp "] " A_WinDir " " A_WinDir . "`n " . A_AppDataCommon " - メモ帳" . "`n Notepad - " . A_AppData a := Path2_ExtractPath(p) b := Path2_ExtractPath(p,2) c := Path2_ExtractPath(p,"ALL") msg := "Path2_ExtractPath(Target="",Multi=0)`n`n" . "対象文字列`n --> " p "`n`n" . "通常は最初に見つかったパスを返します。`n'" a "'`n`n" . "Multi=nでn番目に見つかったパスを返します。`n(Multi=2の場合) : " b "`n`n" . "Multi=ALL指定時は 改行区切りで列挙して返します。`n" c "`n`n" msgbox,1,有効パスサーチ`関数 のテスト,%msg% IfMsgBox,Cancel, return ;--- 起動中プロセスの取得関数のテスト --- p := Path2_ProcessExeNameNT() msg := "Path2_ProcessExeNameNT(pid=0,WinTitle=""A"")`n`n" . "PID指定なしでアクティブウィンドウのパスを返します。`n -> " . p . "`n`n`n" p2 := Path2_GetCommandLine() msg .= "Path2_GetCommandLine(pid=0,WinTitle=""A"")`n`n" . "PID指定なしでアクティブウィンドウのコマンドラインを返します。`n -> " . p2 msgbox,1,起動中プロセスの取得関数のテスト,%msg% IfMsgBox,Cancel, return ;--- テンポラリファイル作成のテスト --- p := Path2_GetTempFileName() msg := "Path2_GetTempFileName(TargetDir="""",PrefixString=""ahk"")`n`n" . "指定のディレクトリにテンポラリファイルを作成します。`n -> " . p "`n" msgbox,1,テンポラリファイル作成のテスト,%msg% IfMsgBox,Cancel, return if (p) FileDelete,%p% ;一応後始末 ;--- ファイルドロップ関数のテスト --- Run,notepad,,,pid msg := "Path2_DropFiles(hwnd,fnames)`n`n" . "指定されたハンドルのウィンドウにファイルをドロップします`n" . "とりあえずメモ帳にこのファイルをドロップしてみます`n" msgbox,4096,ファイルドロップ関数のテスト,%msg% WinActivate,ahk_pid %pid% WinWaitActive,ahk_class Notepad Path2_DropFiles("",A_LineFile) } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;--------------------------------------------------------------------------- ; 汎用関数 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; テンポラリファイルを作成し名前を返す。(winAPI GetTempFileName使用) ; 対象: AHK v1.0.34以降 ; TargetDir : ファイルを作成するディレクトリ (省略時 A_temp) ; PrefixString : ファイル接頭語(3文字以内) (省略時 ahk) ; リターン値 テンポラリフォルダパス(エラー時:0) ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Path2_GetTempFileName(TargetDir="",PrefixString="ahk") {
TargetDir := (!TargetDir) ? A_temp : TargetDirif (Instr(FileExist(TargetDir),"D")) FileCreateDir,%TargetDir% VarSetCapacity(TempFileName , 260) ret := Dllcall("GetTempFileName",Str ,TargetDir ,Str ,SubStr(PrefixString,1,3) ,UInt,0 ,Str ,TempFileName, Uint) return (!ret) ? ret : TempFileName } ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; プロセスID or WinTitle を指定して実行ファイルパスを得る ; 対象: NT系 / AHK v1.0.34以降 ; in pid : プロセスID(省略時 WinTitleが対象となる) ; WinTitle : 対象Window(pid未設定時に適用、省略時アクティブウィンドウ) ; 戻り値 : 実行ファイルパス ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ;Path2_ProcessExeNameNT(pid=0,WinTitle="A") {
Path2_GetExecutablePath(pid=0,WinTitle="A"){
; 参考:
http://cgi19.plala.or.jp/lukewarm/news/2005_05.html#14; by 流行らせるページ管理人 (ほぼそのまま) if (!pid) WinGet,pid,PID,%WinTitle% ;2008.12.10 追加 hModule := dwNeed := l := 0 max:=VarSetCapacity(s,256) ; プロセスのハンドルを取り出す PROCESS_ALL_ACCESS:=0x001F0FFF hProcess := DllCall("OpenProcess", UInt,0x001F0FFF, Int,0, UInt,pid, Int) ; このプロセスの全てのモジュールのリストの最初の1個を取得する ; BOOL EnumProcessModules(HANDLE hProcess, MODULE *lphModule, DWORD cb, ; LPDWORD lpcbNeeded); if (DllCall("psapi\EnumProcessModules",Int ,hProcess ,IntP ,hModule ,Int ,4 ,UIntP,dwNeed, Int)) { ; DWORD GetModuleFileNameEx(HANDLE hProcess, HMODULE hModule, LPTSTR FileName, DWORD FileNameSize); l:=DllCall("psapi\GetModuleFileNameExA",Int,hProcess ,Int,hModule ,Str,s ,Int,max, Int) } DllCall("psapi\CloseProcess", Int,hProcess) ;開けたら閉める return SubStr(s,1,l) } ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; プロセスID or WinTitle を指定してコマンドラインを取得 ; in pid : プロセスID(省略時 WinTitleが対象となる) ; WinTitle : 対象Window(pid未設定時に適用、省略時アクティブウィンドウ) ; 戻り値 : 実行ファイルパス ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Path2_GetCommandLine(pid=0,WinTitle="A"){
; 参考:流行らせるページ管理人氏 の MouseGesture2 スクリプト内 ; MG_CommandLine()より (ほぼそのまま) ; http://lukewarm.s101.xrea.com/myscripts/mousegesture/index.html if (!pid) WinGet,pid,PID,%WinTitle% ;2008.12.14 追加 ; kernel32\GetCommandLineA のアドレスへのポインタを設定? ptr:=(NumGet(DllCall("kernel32.dll\GetProcAddress" ,UInt,DllCall("kernel32.dll\GetModuleHandle",Str,"Kernel32") ,Str ,"GetCommandLineA",UInt)+1)) ; プロセスのハンドルを取り出す hp:=DllCall("kernel32.dll\OpenProcess",UInt,0x001F0FFF,UInt,0,UInt,pid,UInt) VarSetCapacity(res,1024) ; GetCommandLineのメモリアドレスを取得してからコマンドライン文字列を取得 DllCall("kernel32.dll\ReadProcessMemory" ,UInt ,hp ,UInt ,ptr ,UIntP,addr ,UInt ,4 ,UInt ,0) DllCall("kernel32.dll\ReadProcessMemory" ,UInt,hp ,UInt,addr ,Str,res ,UInt,1024 ,UInt,0) DllCall("psapi\CloseProcess", UInt,hp) ;開けたら閉める return res } ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ファイルドロップ関数 by 流行らせるページ管理人 ; 指定ウィンドウへのファイルドロップを発生させる ; 引数 ; hwnd : 指定されたウィンドウに ; fnames : ファイルをドロップする(複数対応:改行区切り) ; WinTitle : 対象Window(hwnd未設定時に適用、省略時アクティブウィンドウ) ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Path2_DropFiles(hwnd="",fnames="", WinTitle="A") {
; 参考:
http://lukewarm.s101.xrea.com/myscripts/index.html; by 流行らせるページ管理人 (ほぼそのまま) hwnd := (!hwnd) ? WinExist(WinTitle) : hwnd fns:=RegExReplace(fnames,"\n$","") hDrop:=DllCall("GlobalAlloc", UInt,0x42, UInt,20+StrLen(fns)+2, UInt) p:=DllCall("GlobalLock","UInt",hDrop) NumPut(20 ,p+0) ;offset NumPut(0 ,p+4) ;pt.x NumPut(0 ,p+8) ;pt.y NumPut(0 ,p+12) ;fNC NumPut(0 ,p+16) ;fWide p2:=p+20 Loop,Parse,fns,`n,`r { DllCall("RtlMoveMemory", "UInt",p2,"Str",A_LoopField,"UInt",StrLen(A_LoopField)) p2+=StrLen(A_LoopField)+1 } DllCall("GlobalUnlock",UInt,hDrop) PostMessage,0x233,%hDrop%,0,,ahk_id %hwnd% } ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; 有効パスを抽出して返す (ダメ文字考慮改訂版) 2009.07.01 ; ; 対象: AHK v1.0.48以降(While-loop使用) ; in Target : 対象文字列(省略時:アクティブウィンドウタイトル) ; Multi : n(数値)= n個に見つかったパスを返す(デフォルト:1) ; ALL = 有効パスが複数あるとき改行区切りで全部返す ; 戻り値 パス情報 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Path2_ExtractPath(Target="",Multi=1) {
ifEqual
Target,, WinGetTitle,Target,A;--- RegEx判定用定義 --- ;対応する括弧 (<> と " " は↑の無効文字で対応) ; []{}の全角誤爆問題は対策できてるはず reg := "\((.*?)\)|'(.*?)'" . "|(?<=^|[^\x80-\x9F\xE0-\xFC])\[(.*?[^\x80-\x9F\xE0-\xFC])\]" . "|(?<=^|[^\x80-\x9F\xE0-\xFC])\{(.*?[^\x80-\x9F\xE0-\xFC])\}" . "|((.*?))|「(.*?)」|{(.*?)}|『(.*?)』|【(.*?)】|[(.*?)]" . "|‘(.*?)’|“(.*?)”|〔(.*?)〕|〈(.*?)〉|《(.*?)》|<(.*?)>" . "|`(.*?)´|「(.*?)」" ;空白Trim用 Trim := "im)^(?: | )*(.*?)(?: | )*$" ;--- パスとして無効な文字列で分割 --- Target := RegExReplace(Target, "im)" . "(\x22|\x2C|(?<=^|[^\x80-\x9F\xE0-\xFC])\||;|<|>|/|\*|\?|\t|`r|`n)" , "`n") Loop,Parse,Target,`n { ;--- パス判定 --- str := !FileExist(A_LoopField) ? RegExReplace(A_LoopField, Trim,"$1") : A_LoopField found := FileExist(str) ? str "`n" : "" , str_sav := str ;空白区切り or 対応する括弧でチェック 例) [c:\hoge.txt] - AppName If (!found) { p="dmy" While (p) { ;抽出 ss := (!p:=RegExMatch(str,"im)" reg "|(?P<sp>(?: | )+)", $)) ? str : "" if (p) && ($sp) { ;空白が先に見つかった時 ss := SubStr(str,1,p-1) str := SubStr(str,p+strlen($sp),strlen(str)-p) }else if (p) && (!$sp) { ;対応する括弧が見つかった時 While !ss ss:=$%A_Index% str := SubStr(str,p+strlen($),strlen(str)-p) } ;パス判定 found .= FileExist(ss) ? ss "`n" : FileExist(ss:=RegExReplace(ss, Trim,"$1")) ? ss "`n" : "" } } ;見つからなかったら空白区切りで左右から削ってってみる。2009.01.23 ; 例1) c:\program files\hoge.txt - メモ帳 ; 例2) Notepad - c:\program files\hoge.txt ; × aaa - c:\program files\hoge - bbb みたいなのは対応できない。 If (!found) && Instr(str_sav," "){ Loop,2 { ifNotEqual,found,, break str := str_sav ph := A_Index ; ph1:右から削る ph2:左から削る While (pos:=(ph=1) ? Instr(str," ",False, 0) : Instr(str," ")){ str := RegExReplace((ph=1) ? SubStr(str,1,pos-1) : SubStr(str,pos+1),"^\s*(.+?)\s*$","$1") found .= FileExist(str) ? str . "`n" : "" ifNotEqual,found,, break } } } foundAll .= found } if (Multi = "ALL") return SubStr(foundAll,1,StrLen(foundAll)-1) return RegExReplace(foundAll,"m`n)(?:.*`n){" Multi-1 "}(.*$)(?:.*`n)*","$1") } |