The First Punic War Begins
Ok, as I was bored and wanted to get this out of the way, I whipped up this AutoIt script for you, replete with a GUI just so you can be sure of what you're doing before you do it:
Edit: For those without an interest in historical allusions or playing with scripts, a "proper boring version" of this can be downloaded from
here (392 KB) Last updated 03-Apr-11
Now, this is fairly self explanatory - when you run the script it automatically generates the bookmarks from x2's registry and displays them on the left, while the list on the right contains the current contents of your "Users\...\Links" folder. If duplicates are selected to be shown (not the default), any items coloured
blue are already in the Favourites list, and as such they are automatically unchecked. Links can be compared by
Name or by
Target (default), so "Étrangère" and "Etrangere" may or may not match depending on "Compare by" if they point the same place. If matching by "Target" any links displayed in
red used CLSID addresses as the link target, and as such cannot be compared to anything as AutoIt's FileGetShortcut() function can't retrieve a proper link to compare it to.
Note that x2 allows "illegal characters" in bookmark names, like ":" and "*", etc. I did a rudimentary strip in line 211 with StringRegExpReplace() to remove the common ones (replacing them with underscores '_'), but it should probably be expanded for completeness.
When you click "impetum facere" (it seems fitting to attack in Latin, no?), obviously the selected (checked) bookmarks will be created as proper .LNK files in your \Links folder, and the display will update (so whatever you just transferred will turn blue, as it's now a duplicate, and appearing in the Favourites column as well).
If you made a mistake and don't want a particular item in your Links folder, just Right-Click it in the second column and select "Delete Link" from the context menu. (It shouldn't be that hard to find as there is only one command in that context menu.
![Very Happy :D](./images/smilies/icon_biggrin.gif)
) The other column has a boring context menu for "Select\De-select All" and "Matching".
Remember that x2's registry is only updated when you actually save settings (manually or automatically on exit), so any new bookmarks that you made while x2 is still open won't be in the list - so just save your settings, and click the "Refresh" button - and the list will be repopulated to include (or exclude, in the case of deleting some) the appropriate bookmarks.
For simplification purposes, this script can't do the reverse - in other words, you can't put Bookmarks into x2 from the Links folder - I decided that was madness to attempt in the couple of hours I used for this. Doesn't really seem that practical anyway, so I feel properly self-justified now for not including it.
When the script exits, it automatically deletes the objects (1 reg file and one folder) it created in your temporary folder (that's the only location where processing is done), so everybody's happy.
Hope you like it - the script is "fairly" self-explanatory so you should be able to modify anything you like, if you feel the need. Or, just ask.
Obviously, you need
AutoIt to run it (I could have just supplied the compiled version as a link, but where's the fun in that?). You expressed familiarity with it earlier, so I assume you probably have it already.
It's a mere 220-odd lines, so nothing to get excited about. Just copy the following and save it as Hannibal
.au3 ![Wink :wink:](./images/smilies/icon_wink.gif)
, and away you go.
Code: Select all
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListviewConstants.au3>
#include <GuiListView.au3>
#include <File.au3>
Opt("MustDeclareVars", 1)
Global Const $Quote = """"
Global $dCount
Global $Folder = @UserProfileDir & "\Links" ; Set folder to synch into
If Not FileExists($Folder) Then
MsgBox(16, "The First Punic War", "Folder '" & $Folder & "' does not exist")
Exit
EndIf
Global $BookmarkOnes[1][2], $FavouriteOnes[1], $TargetOnes[1] ; all Redimmed in Functions, declared here to avoid syntax warnings
Global $FilesArray, $FilesArray2, $a_pid
Global $Name, $Target, $RawLine, $Content
Global $WinParent = GUICreate("The First Punic War", 585, 400, -1, -1, BitOR($WS_OVERLAPPED, $WS_CAPTION, $WS_SYSMENU, $WS_MINIMIZEBOX))
GUISetFont(9, 400, 0, "Segoe UI")
Global $Button_AddTo = GUICtrlCreateButton("impetum facere ->", 218, 200, 150, 30)
GUICtrlSetState(-1, $GUI_FOCUS)
GUICtrlSetState(-1, $GUI_DEFBUTTON)
GUICtrlSetFont(-1, 9, 800, 0, "Segoe UI") ; A little Love Emboldens even the most frightened heart
Global $Checkbox_ShowDups = GUICtrlCreateCheckbox("Show duplicates", 227, 40)
GUICtrlSetState($Checkbox_ShowDups, $GUI_UNCHECKED)
GUICtrlCreateGroup("Compare by:", 227, 130 - 40, 130, 85)
Global $Radio_Name = GUICtrlCreateRadio("Name ", 250, 153 - 40)
Global $Radio_Target = GUICtrlCreateRadio("Target ", 250, 178 - 40)
GUICtrlSetState(-1, $GUI_CHECKED)
GUICtrlCreateGroup("", -99, -99, 1, 1)
Global $Button_Refresh = GUICtrlCreateButton("Refresh", 237, 300, 110, 30)
Global $Button_Close = GUICtrlCreateButton("Exit", 237, 350, 110, 30)
Global $QuintusFabiusBookmarks = GUICtrlCreateListView("Carthaginian Bookmarks", 15, 15, 200, 366, -1, $LVS_EX_CHECKBOXES)
GUICtrlSetBkColor($QuintusFabiusBookmarks, 0xC0C0C0)
_GUICtrlListView_SetColumnWidth($QuintusFabiusBookmarks, 0, 179)
Global $ContextMenu2 = GUICtrlCreateContextMenu($QuintusFabiusBookmarks)
Global $Context_SelectAll = GUICtrlCreateMenuItem("Select All", $ContextMenu2)
Global $Context_DeSelectAll = GUICtrlCreateMenuItem("De-select All", $ContextMenu2)
Global $Context_Matching = GUICtrlCreateMenuItem("Matching", $ContextMenu2)
Global $HannibalFavourites = GUICtrlCreateListView("Legionary Favourites", 371, 15, 200, 366, -1, $LVS_EX_FULLROWSELECT)
_GUICtrlListView_SetColumnWidth($HannibalFavourites, 0, 179)
GUICtrlSetBkColor($HannibalFavourites, 0xC0C0C0)
Global $ContextMenu = GUICtrlCreateContextMenu($HannibalFavourites)
Global $Context_Delete = GUICtrlCreateMenuItem("Delete Link", $ContextMenu)
ReadFavourites()
ReadRegistryBookmarks()
ReadBookmarks()
GUISetState()
main()
Func main()
While 1
Switch GUIGetMsg()
Case $Button_AddTo
For $i = 0 To $dCount - 1
If BitAND(GUICtrlRead($BookmarkOnes[$i][0], 1), $GUI_CHECKED) = 1 Then
FileCopy(@TempDir & "\Carthage\" & $FilesArray2[$BookmarkOnes[$i][1]], $Folder, 1) ; Do the dirty deed
EndIf
Next
ReadFavourites()
ReadBookmarks()
SoundPlay(@WindowsDir & "\Media\Windows Exclamation.wav", 0)
Case $Radio_Name, $Radio_Target
ReadFavourites()
ReadBookmarks()
Case $Button_Refresh, $Checkbox_ShowDups
ReadFavourites()
ReadRegistryBookmarks()
ReadBookmarks()
Case $Context_Delete
$a_pid = _GUICtrlListView_GetSelectedIndices($HannibalFavourites, 1)
If IsArray($a_pid) And ($a_pid[0] = 1) Then
FileDelete($Folder & "\" & _GUICtrlListView_GetItemText($HannibalFavourites, $a_pid[1], 0) & ".lnk")
ReadFavourites()
ReadBookmarks()
EndIf
Case $Context_SelectAll
For $i = 0 To $dCount - 1
GUICtrlSetState($BookmarkOnes[$i][0], $GUI_CHECKED)
Next
Case $Context_DeSelectAll
For $i = 0 To $dCount - 1
GUICtrlSetState($BookmarkOnes[$i][0], $GUI_UNCHECKED)
Next
Case $Context_Matching
ReadBookmarks()
Case $Button_Close, $GUI_EVENT_CLOSE
Cleanup()
Exit
EndSwitch
WEnd
EndFunc
Func ReadFavourites()
_GUICtrlListView_DeleteAllItems($HannibalFavourites)
$FilesArray = _FileListToArray($Folder, "*.lnk", 1)
If @error <> 4 Then
Global $FavouriteOnes[UBound($FilesArray)] ; Redim and Clear
Global $TargetOnes[UBound($FilesArray)] ; ReDim and Clear
For $i = 1 To UBound($FilesArray) - 1
$FavouriteOnes[$i] = GUICtrlCreateListViewItem(StringReplace($FilesArray[$i], ".lnk", ""), $HannibalFavourites)
$a_pid = FileGetShortcut($Folder & "\" & $FilesArray[$i])
If $a_pid[0] = "" Then
If BitAND(GUICtrlRead($Radio_Name), $GUI_CHECKED) = 0 Then
GUICtrlSetColor($FavouriteOnes[$i], 0xFF0000) ; Display as Red as no matches are possible by location
EndIf
$TargetOnes[$i] = "<<CLSID>>" ; Can't accidentally match anything else
Else
$TargetOnes[$i] = $a_pid[0]
EndIf
Next
EndIf
EndFunc
Func ReadBookmarks()
Local $Name, $Found
$dCount = 0
_GUICtrlListView_DeleteAllItems($QuintusFabiusBookmarks)
$FilesArray2 = _FileListToArray(@TempDir & "\Carthage", "*.lnk", 1)
If @error <> 4 Then
Global $BookmarkOnes[UBound($FilesArray2)][2] ; Redim and Clear
For $i = 1 To UBound($FilesArray2) - 1
$Name = StringReplace($FilesArray2[$i], ".lnk", "")
$a_pid = FileGetShortcut(@TempDir & "\Carthage\" & $FilesArray2[$i])
If BitAND(GUICtrlRead($Radio_Name), $GUI_CHECKED) = 1 Then
$Found = _ArraySearch($FilesArray, $FilesArray2[$i], 1) ; Try and match by name
Else
$Found = _ArraySearch($TargetOnes, $a_pid[0], 1) ; Try by location
EndIf
Switch $Found
Case -1 ; Not Found
$BookmarkOnes[$dCount][0] = GUICtrlCreateListViewItem($Name, $QuintusFabiusBookmarks)
$BookmarkOnes[$dCount][1] = $i
GUICtrlSetState($BookmarkOnes[$dCount][0], $GUI_CHECKED)
If $a_pid[0] = "" Then GUICtrlSetColor($BookmarkOnes[$dCount][0], 0xFF0000) ; Red
$dCount += 1
Case Else ; Found
If BitAND(GUICtrlRead($Checkbox_ShowDups), $GUI_CHECKED) = 1 Then
$BookmarkOnes[$dCount][0] = GUICtrlCreateListViewItem($Name, $QuintusFabiusBookmarks)
$BookmarkOnes[$dCount][1] = $i
GUICtrlSetColor($BookmarkOnes[$dCount][0], 0x0000A0) ; Blue
$dCount += 1
EndIf
EndSwitch
Next
EndIf
EndFunc
Func ReadRegistryBookmarks()
Local $FixedName, $Link, $Icon, $IconRef, $IconRefNum, $Err
Cleanup()
DirCreate(@TempDir & "\Carthage")
RunWait($Quote & @WindowsDir & "\regedit.exe" & $Quote & " /e " & _
$Quote & @TempDir & "\Carthage\HannibalsRearGuard.reg" & $Quote & " " & _
$Quote & "HKEY_CURRENT_USER\Software\ZabaraKatranemia Plc\xplorer2_UC.global\Favorites" & $Quote, "", @SW_HIDE)
Local $tFile = FileOpen(@TempDir & "\Carthage\HannibalsRearGuard.reg", 0)
FileReadLine($tFile, 3) ; Disregard the redundant reg5 header (3 lines)
Do
$RawLine = FileReadLine($tFile)
$Err = @error
$Content = StringLen($RawLine) ; RegEdit adds extra linefeeds at the end of its export - consider the first an EOF
If Not $Err And $Content Then
$RawLine = StringReplace($RawLine, """", "") ; Remove quotations
$RawLine = StringReplace($RawLine, "\\", "\") ; Remove doublestrikes
$Link = StringSplit($RawLine, "=") ; Left (Link[1]) is Bookmark Name, Right (Link[2]) is Location
$FixedName = StringRight($Link[1], StringLen($Link[1]) - 3)
$Icon = RegRead("HKEY_CURRENT_USER\Software\ZabaraKatranemia Plc\xplorer2_UC.global\Favorites_icons", $FixedName)
$IconRef = StringSplit($Icon, ",")
If $IconRef[0] = 1 Then
$IconRefNum = 0
Else
$IconRefNum = Number($IconRef[2])
$Icon = $IconRef[1]
EndIf
$FixedName = StringRegExpReplace($FixedName, "[\\\*.,:]", "_") ; Strip out illegal filename characters
FileCreateShortcut($Link[2], _
@TempDir & "\Carthage\" & $FixedName & ".lnk", _
"", _
"", _
"", _
$Icon, _
"", _
$IconRefNum)
EndIf
Until $Err Or Not $Content
FileClose($tFile)
EndFunc
Func Cleanup()
DirRemove(@TempDir & "\Carthage", 1)
EndFunc