人気ブログランキング | 話題のタグを見る

AutoHotKey_Lで、Link Shell Extensionを使ってリパースポイントを相対パスで作り直す。

 親フォルダをリネームしただけで、絶対パスで作ってあったシンボリックリンクが死んだので、相対パスで作り直そうと思ったのだけど、数が多くて面倒なのでAHKスクリプト書いた。

 自前でリパースポイントいじるにはDeviceIoControl叩く必要があるらしく面倒なので、「Link Shell Extension」が拡張するプロパティ項目を利用する。

;--------------------------------------------------------------------------------------
; WindowsExplorer
;--------------------------------------------------------------------------------------
#IfWinActive, ahk_class CabinetWClass

!l::  ; 選択したリパースポイントを相対パスに
  KeyWait, l
  KeyWait, alt
  
  SetTitleMatchMode, Slow
  
  CurPath := RegExEscape(GetCurPath())
  
  PathList := GetSelectItemPath()
  Loop, Parse, PathList, `n, `r%A_Space%"
  {
    Run, AutoHotkeyU64 _Script\FilePropertyOpen.ahk %A_LoopField%
    SplitPath, A_LoopField, FileName, DirName
    
    WinWaitActive, %FileName%のプロパティ ahk_class #32770, %DirName%
    Loop
    {
      Control, TabRight , 1, SysTabControl321
      WinGetText, WinTxt
      IfInString, WinTxt, リンクの種類
        break
    }
    ControlGetText, CtrlTxt, Edit2
    CtrlTxt2 := RegExReplace(CtrlTxt, CurPath "[^\\]*\\", ".\")
    if (CtrlTxt2 != CtrlTxt)
      ControlSetText, Edit2, %CtrlTxt2%
    Sleep, 50
    Send, {Enter}
  }
return

GetCurPath(DQSW = 0) {  ; アクティブなエクスプローラのパス。
  WinGetText, CurPath, A
  RegExMatch(CurPath, "([A-Z]:\\[^\r\n]+)", $)
  if DQSW
    return """" $1 """"
  else
    return $1
}

GetSelectItemPath(DQSW = 0, FldSW = 0, ParseStr = "`n") {  ; エクスプローラで選択中のアイテムのパス。AutoHotkey スレッド part11 >>913
  for Window in ComObjCreate("Shell.Application").Windows
    if (Window.hwnd == WinExist()) {
      for Item in Window.Document.SelectedItems
      {
        if (FldSW && !Item.IsFolder)
          continue
        if DQSW
          FileList .= """" Item.Path """" ParseStr
        else
          FileList .= Item.Path ParseStr
        Cnt++
      }
      break
    }
  ErrorLevel := Cnt
  return, SubStr(FileList, 1, -1)
}

RegExEscape(StrBuf) {  ;正規表現で特別な文字を回避。
  EscList := "
(
\
.
*
?
+
[
{
}
|
(
`)
^
$
)"
  
  Loop, Parse, EscList, `n
    StringReplace, StrBuf, StrBuf, %A_LoopField%, \%A_LoopField%, All
  
  return, StrBuf
}

;--------------------------------------------------------------------------------------
; FilePropertyOpen.ahk
;  渡されたファイルのプロパティを開く。
;--------------------------------------------------------------------------------------

  SetTitleMatchMode, 3
  SetTitleMatchMode, Slow
  
  Loop, %0%
    Cmdline .= %A_Index% " "
  Cmdline := SubStr(Cmdline, 1, -1)
  
  RunWait, properties %Cmdline%
  SplitPath, Cmdline, FileName, DirName
  
  WinWait, %FileName%のプロパティ ahk_class #32770, %DirName%
  WinWaitClose
  
ExitApp

 エクスプローラでジャンクション/シンボリックリンクを選択してAlt+Lすると、現在表示しているフォルダを起点とした相対パスでリンクを作り直す。ただし「../」には非対応。

 AHKは32bit版を使っているため、64bit版Link Shell Extensionのプロパティ項目を開くのに、わざわざ64bit版AHKでFilePropertyOpen.ahkを実行する仕組みなので、Runのパスに注意。普通に開けるのなら、そのように。


by lordnoesis | 2013-10-20 22:31 | テクノロジ | Trackback | Comments(0)
ブログトップ | ファンになる