#SingleInstance ignore #NoEnv #NoTrayIcon if 1 <> { RegRead,Status,HKEY_CURRENT_USER,Software\SmartUnpack,Status If Status = RegWrite,Reg_SZ,HKEY_CURRENT_USER,Software\SmartUnpack,Status,1 If Status = 1 ExitApp ; Multiple Instances no no don't wanna never wanted bad stuff Unglücksbringer Verdammnis Unheil } SetTitleMatchMode,2 OnExit,ExitSub IfNotExist %A_ScriptDir%\Smart unpack.ini ; If there is no ini file, create one with sample entries + notify user { FileAppend,[settings]`n`n; Please configure your unpacker + necessary command line options`n;`n; SOURCE and TARGET are needed as placeholders.`n; The script will look for these strings and replace them.`n;`n; Example line for WinRAR: `n; C:\Program Files\WinRAR\winrar.exe x -o+ -df SOURCE TARGET`n;`n; Example line for 7Zip: `n; C:\Program Files\7zip\7z.exe x -aoa SOURCE -oTARGET`n`n`nUnpacker=C:\Program Files\WinRAR\winrar.exe x -o+ -df SOURCE TARGET`n`n`n; Delete the source archive after extracting (0 or 1)`n; Won't be deleted if the unpacker reports an errorlevel`n; !! The script will always delete in the recycle bin !!`n`nEraseSource=1`n`n`n; If configured`, SmartUnpack will send this key combination after`n; successful unpacking. This key combination should refresh the view`n; in your third party file explorer (like xplorer²). Ignore this setting`n; if you're using the Windows file explorer only.`n; Examples: ALT+R = !r SHIFT+R = +r CONTROL+R = ^r`n`nRefreshCombination=`n`n`n; Copy the filename without extension to the clipboard (0 or 1)`n`nCopyFilename=0,%A_ScriptDir%\Smart unpack.ini Run,Notepad %A_ScriptDir%\Smart unpack.ini ExitApp } IniRead,Unpacker,%A_ScriptDir%\Smart unpack.ini,settings,Unpacker ; Reading + checking ini file IniRead,EraseSource,%A_ScriptDir%\Smart unpack.ini,settings,EraseSource IniRead,RefreshCombination,%A_ScriptDir%\Smart unpack.ini,settings,RefreshCombination IniRead,CopyFileName,%A_ScriptDir%\Smart unpack.ini,settings,CopyFileName If (Unpacker = Error or EraseSource = Error) { msgbox, 48, Smart unpack, Error in "Smart Unpack.ini".`n`nPlease configure this file. Run,Notepad %A_ScriptDir%\Smart unpack.ini ExitApp } ifwinactive,ahk_class Progman ; Desktop loses focus... needs to be re-activated later desktop = yay StringGetPos,Count,Unpacker,.exe,l ; Checking unpacker If errorlevel <> 0 { msgbox, 48, Smart unpack, No ".exe" configured!`n`nPlease edit configuration file. Run,Notepad %A_ScriptDir%\Smart unpack.ini ExitApp } Count += 4 StringLeft,Count,Unpacker,%Count% IfNotExist,%Count% { msgbox, 48, Smart unpack, %Count% not found!`n`nPlease edit configuration file. Run,Notepad %A_ScriptDir%\Smart unpack.ini ExitApp } If 1 <> ; Parameter was given. Start the routine and exit { Gosub,RoutineStart ExitApp } RegWrite,Reg_SZ,HKEY_CURRENT_USER,Software\SmartUnpack,Status, ; Fail safe Gui, +ToolWindow +AlwaysOnTop ; If no parameter given, show GUI Gui, Font, S8 CDefault, Verdana Gui, Add, Button, x-252 y470 w308 h-430 , Button Gui, Add, CheckBox, gCheckbox vErase x16 y30 w110 h20 , Delete Archive Gui, Add, Text, vText x206 y32 w70 h20 , Gui, Add, GroupBox, x6 y10 w280 h50 , Drag and Drop archive files in this window GuiControl,,erase,%EraseSource% Gui, Show, x125 y549 h71 w297,Smart Unpack Return Checkbox: ; Updating ini file if user clicks checkbox Gui,Submit,nohide IniWrite,%Erase%,%A_ScriptDir%\Smart unpack.ini,settings,EraseSource Return GuiDropFiles: ; If user drags one or more files on the GUI GuiControl,,Text,Working! Gui,Submit,nohide Gui,+Disabled Loop,parse,A_GuiControlEvent,`n { 1 = %A_LoopField% Gosub,RoutineStart } Gui,-Disabled GuiControl,,Text, Return Configure: ; Unused (once there was a 'configure' button) Gui,Destroy RunWait,Notepad %A_ScriptDir%\Smart unpack.ini Reload Return RoutineStart: IniRead,EraseSource,%A_ScriptDir%\Smart unpack.ini,settings,EraseSource ; Reloading (changed) variables IniRead,Unpacker,%A_ScriptDir%\Smart unpack.ini,settings,Unpacker SplitPath,1,FileName,Dir,Extension,NameNoExt,Drive ; Preparing + creating temp folder on same drive as archive Random,random ; So it will be moved instead of copied + erased temp = %drive%\unpack_%random% FileCreateDir,%temp% StringReplace,Unpacker,Unpacker,SOURCE,"%1%" StringReplace,Unpacker,Unpacker,TARGET,"%temp%\" RunWait,%unpacker%,,UseErrorLevel ; Unpacking + checking errorlevel if errorlevel <> 0 { msgbox, 48, Smart unpack,Extracting produced errorlevel %errorlevel% Gosub,DeleteTEMP Return } If CopyFileName = 1 Clipboard := NameNoExt Loop: ; Now here starts the magic... Reading # of files Count = 0 Loop,%temp%\*.*,1,0 { Name = %A_LoopFileName% Count += 1 } If Count = 0 ; Zero files - This should never happen, { ; but I'm a firm believer in Murphy's Law... msgbox, 48, Smart Unpack says "WTF?", Well`, well`, well... something didn't work out.`nYou just wanted to unpack something`, but somehow I received no file. Nothing. Nada. `n`nMost likely you configured the "Smart unpack.ini" file wrong. `nPlease check again and read the instructions there.`n`nIf this error still appears`, please contact the author. `nTell him exactly what you did and include a copy of your configuration file. Gosub,DeleteTEMP Return } If Count = 1 ; One File { FileGetAttrib,Attribute,%temp%\%Name% ; File or Folder If Attribute Contains D ; It's a folder. Checking how many files are in this folder. { Count2 = 0 Loop,%temp%\%Name%\*.*,1,0 { Name2= %A_LoopFileName% Count2 += 1 } If count2 > 1 ; More than one file. Move the folder and be done. { Source = %temp%\%name% Target = %Dir%\%name% Gosub,MoveDIR } else ; Just one file. Determining if this is a SUBfolder or file. { FileGetAttrib,Attribute2,%temp%\%Name%\%Name2% If Attribute2 Contains D { ; It's a SUBfolder. So change the path and let the routine rerun Temp = %temp%\%Name% Goto, Loop ; Here it is. I'm using it. I know.... I suck as script writer. } else ; It's a file. So here's the question. Move the file, or the folder? { ; Checking if the archivename is the same as this folder's name. If NameNoExt = %Name% { Source = %temp%\%Name%\%Name2% ; It is. So move it without the folder. Target = %Dir%\%Name2% Gosub,MoveFILE } else { Source = %temp%\%name% ; It's not. So the folder might be important. Move the folder. Target = %Dir%\%name% Gosub,MoveDIR } } } } else ; It's a file, so move it and be done. { Source = %temp%\%Name% Target = %Dir%\%Name% Gosub,MoveFILE } If EraseSource = 1 ; Delete source archive? Gosub,EraseFiles Gosub,Refresh ; Force "refresh" view. Gosub,DeleteTEMP Return } Source = %temp% ; More than one file. Just move the temp folder and rename it while moving Target = %Dir%\%NameNoExt% Gosub,MoveDir If EraseSource = 1 ; Delete source archive? Gosub,EraseFiles Gosub,Refresh ; Force "refresh" view. Gosub,DeleteTEMP Return DeleteTEMP: ; Deleting temp folder and waiting/retrying if locked. IfExist,%temp% { Loop,5 { FileRemoveDir, %temp%,1 If ErrorLevel = 0 Break Sleep,1000 } } Return MoveDIR: ; Making sure there's no overwrite. Count = 1 SplitPath,Target,,TargetDIR,,TargetNAME MoveDIRloop: IfExist,%Target%\ { Target = %TargetDIR%\%TargetName%(%Count%) Count += 1 Goto,MoveDIRloop ; I like using it. Get over it. :) } FileMoveDir,%source%,%target%\ Return MoveFILE: ; Pretty much the same as MOVEDIR, just for files Count = 1 ; Not pretty, but it works SplitPath,Target,,TargetDIR,TargetEXT,TargetNAME MoveFILEloop: IfExist,%Target% { Target = %TargetDir%\%TargetName%(%Count%).%TargetExt% Count += 1 Goto,MoveFileLoop } FileMove,%source%,%Target%\ Return EraseFiles: ; So many lines just for erasing... who would've thought? ; Check for part1 in file name in most common varations... SplitPath,1,UnpackFileName,UnpackPath,UnpackExtension,Unpackname If UnpackExtension = rar { If Unpackname contains .part { StringLen,UnpackLaenge,UnpackName if UnpackFileName contains .part1. UnpackLaengeMinus := UnpackLaenge - 5 if UnpackFileName contains .part01. UnpackLaengeMinus := UnpackLaenge - 6 if UnpackFileName contains .part001. UnpackLaengeMinus := UnpackLaenge - 7 if UnpackFileName contains .part0001. UnpackLaengeMinus := UnpackLaenge - 8 StringMid,Unpackname,UnpackName,1,%UnpackLaengeMinus% } } ; Now it gets pretty lame and non-efficient, but hey... ; don't blame me. If I could actually code, I wouldn't use AHK... ;) ; (FileRecycle is much slower than FileDelete) FileRecycle,%1% FileRecycle,%UnpackPath%\%UnpackName%.r00 Loop,99 { Variations = .%a_index%,.0%a_index%,.00%a_index%,.r%a_index%,.r0%a_index%,.r00%a_index%,part%a_index%.rar,part0%a_index%.rar,part00%a_index%.rar,part000%a_index%.rar Loop,parse,Variations,`, { IfExist,%UnpackPath%\%UnpackName%%A_LoopField% FileRecycle,%UnpackPath%\%UnpackName%%A_LoopField% } } Return Refresh: ; I can only hope this works under anything else than XP if desktop = yay { winactivate,ahk_class Progman send,{F5} } else { ifwinactive,ahk_class ExploreWClass send,{F5} else { if RefreshCombination <> send,%RefreshCombination% } } Return GuiEscape: GuiClose: ExitSub: RegWrite,Reg_SZ,HKEY_CURRENT_USER,Software\SmartUnpack,Status, ExitApp