It's a great little open-source app for taking snapshots of your registry and selected folders.
link:
http://sourceforge.net/projects/regshot/
I plan to start using it on a regular basis for taking snapshots of my registry and selected folders (A_WinDir\system32, A_AppData, A_AppDataCommon, ...) before and after new installs, and saving the comparison text files for potential post-uninstall clean up.
But going over the comparison logs manually is too much trouble, that's where AHK would come in. Please post here if you have any scripts for use with RegShot, or script that could be modified to analyze RegShot log files.
RegShot comparison logs include entries that were added, modified, and deleted between the two snapshots. The basic idea would be to write a script (for use following regular uninstall) that would take the info in the regshot log, get the corresponding current values (if remaining) for the added/modified entries, show you a comparison in tree form with options to Delete, 'Open Containing Folder' or 'Open in RegEdit' etc. How does that sound?
-----------------------------------------------------------------------
Edit: Here's my script so far (with support for regedit). Replace OpenWithRegEdit instances with OpenWithRegWksp if you have Registry Workshop.
I call this RegshotCleaner_RE.ahk. Highlight a regshot log file (txt-format) in Windows Explorer and press CTRL+R.
Update: The script now includes a third gui windows; a listview to display times (from log if available) when new folders or keys were created. Files and reg values created within x seconds of those times are shown in bold. you can adjust the time window and check/uncheck folder/keys used for filtering.
the InCtrl5_Laucher appends the creation times section automatically to the report, but to add it manually use the following format. Example:
Quote:
----------------------------------
Folder/key creation times:
----------------------------------
8/5/2009 01:02:17 PM (20090805130217), c:\Program Files\Foxit Software\Foxit Reader\plugins
8/5/2009 01:02:18 PM (20090805130218), c:\Documents and Settings\SK\Application Data\Foxit\images
8/5/2009 01:02:26 PM (20090805130226), HKCR\TypeLib\{4B1C1E16-6B34-430E-B074-5928ECA4C150}
8/5/2009 01:02:27 PM (20090805130227), HKCR\CLSID\{571715D7-3395-4DF0-B43C-784836209E60}\TypeLib
The idea is to add the main folder and with the creation times of a newly installed program. That way you can use those times help decide what is noise and what was added by the program.
Also, both 'probably harmless' and entries outside the time window are shown in regular as opposed to bold font. I wanted to use colors, but don't know how to modify treeview entries the way you can bold/unbold them with TV_Modify...
Code:
/*
-This script cleans up RegShot output by removing "background noise"
defined by the included list of entries (user should customize the list.)
-RegShot log file needs to be in the same directory as the script.
-only tested on winXP/SP3 AutoHotkey v1.0.48.03 and RegShot v1.8.2
*/
#NoEnv
#SingleInstance, Force
SetBatchLines, -1
SetWorkingDir, %A_ScriptDir%
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; ;;;
;;; Below specify options ;;;
;;; (generally, on = 1 and off = 0) ;;;
;;; ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
denoise_On = 0 ;option to save regshot after initial denoising
saveFileList = 0 ;option to save list of denoised files remaining on system
saveRegList = 0 ;option to save list of denoised reg entries remaining on system
;default time proximity used to highlight entries
threshold:= 10
GroupAdd, Explore, ahk_class CabinetWClass
GroupAdd, Explore, ahk_class ExploreWClass
#IfWinActive ahk_group Explore
^r::
ControlGetText, Dir, Edit1, A
ControlGet, file, List, Focused Col1, SysListView321, A
filepath:= StrLen(Dir)=3 ? dir . file : dir . "\" . file
StringTrimRight, filename, file, 4
shotClean=
If (denoise_On == 1)
FileDelete, %filename%_denoised.txt ;if exists
Loop, HKEY_CURRENT_USER,Software\Microsoft\Protected Storage System Provider,2
UserSID:= A_LoopRegName
FileRead, shot, %filepath%
;following loop changes long reg root key names to short form, if necessary
Loop, Parse, shot, `n,`r
{
;change long root key names to abbreviations (if necessary)
StringReplace,thisline,A_LoopField,HKEY_CLASSES_ROOT\,HKCR\
StringReplace,thisline,thisline,HKEY_CURRENT_USER\,HKCU\
StringReplace,thisline,thisline,HKEY_LOCAL_MACHINE\,HKLM\
StringReplace,thisline,thisline,HKEY_USERS\,HKU\
StringReplace,thisline,thisline,HKEY_CURRENT_CONFIG\,HKCC\
If thisline Contains \ntuser.dat,\Cookies\index.dat,\Local Settings\Application Data\Microsoft\Windows\UsrClass.dat.LOG,\Local Settings\desktop.ini
,C:\Documents and Settings\Administrator.%A_ComputerName%\Local Settings\Application Data\AnVir\
,%A_AppDataCommon%\Application Data\Rising\common\
,%A_AppDataCommon%\ABBYY\Retail.ScreenshotReader\9.00\Licenses\ProductLicensing.log
,C:\Documents and Settings\LocalService\Local Settings\Application Data\Microsoft\Windows\UsrClass.dat.LOG
,C:\Documents and Settings\LocalService\Local Settings\desktop.ini
,C:\Documents and Settings\%A_UserName%\ntuser.ini
,%A_AppData%\Microsoft\CryptnetUrlCache\Content
,%A_AppData%\Microsoft\CryptnetUrlCache\MetaData
,%A_AppData%\Microsoft\HTML Help\hh.dat
,%A_AppData%\Mozilla\Firefox\Profiles\k2qzu7cz.default
,%A_AppData%\Scooter Software\Beyond Compare 3
,C:\Documents and Settings\%A_UserName%\IETldCache\index.dat
,C:\Documents and Settings\%A_UserName%\Local Settings\Application Data\Bill2's Process Manager\
,C:\Documents and Settings\%A_UserName%\Local Settings\Application Data\Bill2_Software
,C:\Documents and Settings\%A_UserName%\Local Settings\Application Data\IconCache.db
,C:\Documents and Settings\%A_UserName%\Local Settings\Application Data\Microsoft\Windows\UsrClass.dat
,C:\Documents and Settings\%A_UserName%\Local Settings\Application Data\Microsoft\Windows\UsrClass.dat.LOG
,C:\Documents and Settings\%A_UserName%\Local Settings\Application Data\Microsoft\Windows Media\11.0\WMSDKNSD.XML
,C:\Documents and Settings\%A_UserName%\Local Settings\Application Data\Mozilla\Firefox\Profiles\k2qzu7cz.default
,C:\Documents and Settings\%A_UserName%\Local Settings\desktop.ini
,C:\Documents and Settings\%A_UserName%\Local Settings\History\desktop.ini
,C:\Documents and Settings\%A_UserName%\Local Settings\History\History.IE5
,C:\Documents and Settings\%A_UserName%\Local Settings\Temp\
,C:\Documents and Settings\%A_UserName%\Local Settings\Temporary Internet Files\Content.IE5
,C:\Documents and Settings\%A_UserName%\Local Settings\Temporary Internet Files\desktop.ini
,C:\Documents and Settings\%A_UserName%\SendTo\Bluetooth File Transfer Wizard.LNK
,C:\Documents and Settings\%A_UserName%\SendTo\desktop.ini
,%A_ProgramFiles%\Everything\Everything.db,%A_ProgramFiles%\Everything\Everything.ini
,%A_WinDir%\0.log,%A_WinDir%\bootstat.dat,%A_WinDir%\bthservsdp.dat
,%A_WinDir%\Rav.inf,%A_WinDir%\Rav.ini,%A_WinDir%\Sandboxie.ini,%A_WinDir%\Debug\PASSWD.LOG
,%A_WinDir%\erdnt,%A_WinDir%\Prefetch,%A_WinDir%\Security\edb.chk,%A_WinDir%\Security\edb.log
,%A_WinDir%\SoftwareDistribution\DataStore\DataStore.edb
,%A_WinDir%\SoftwareDistribution\DataStore\Logs\edb.chk
,%A_WinDir%\SoftwareDistribution\DataStore\Logs\edb.log
,%A_WinDir%\SoftwareDistribution\DataStore\Logs\tmp.edb
,%A_WinDir%\system32\BsMain.ini
,%A_WinDir%\system32\CatRoot2
,%A_WinDir%\system32\config\AppEvent.Evt
,%A_WinDir%\system32\config\default
,%A_WinDir%\system32\config\SecEvent.Evt
,%A_WinDir%\system32\config\sam
,%A_WinDir%\system32\config\security
,%A_WinDir%\system32\config\software
,%A_WinDir%\system32\config\SysEvent.Evt
,%A_WinDir%\system32\config\system
,%A_WinDir%\system32\LogFiles\WUDF\WUDFTrace.etl
,%A_WinDir%\system32\perf
,%A_WinDir%\system32\wbem
,%A_WinDir%\system32\wpa.dbl
,%A_WinDir%\Tasks\Clean System Memory.job,%A_WinDir%\Tasks\SA.DAT,%A_WinDir%\Tasks\SCHEDLGU.TXT
,%A_WinDir%\Temp\Perflib_Perfdata,%A_WinDir%\Temp\RavTemp,%A_WinDir%\Temp\WGAErrLog.txt
,%A_WinDir%\wiadebug.log,%A_WinDir%\wiaservc.log
,%A_WinDir%\WindowsUpdate.log
,HKLM\HARDWARE\DESCRIPTION\System
,HKLM\HARDWARE\DEVICEMAP\Scsi
,HKLM\HARDWARE\RESOURCEMAP
,HKLM\SOFTWARE\Broadcom\802.11
,HKLM\SOFTWARE\Microsoft\Cryptography\RNG
,HKLM\SOFTWARE\Microsoft\EventSystem
,HKLM\SOFTWARE\Microsoft\Rpc\UuidSequenceNumber
,HKLM\SOFTWARE\Microsoft\Rpc\WBEM\CIMON
,HKLM\SOFTWARE\Microsoft\Rpc\WBEM\Transports\Decoupled\Server
,HKLM\SOFTWARE\Microsoft\SchedulingAgent
,HKLM\SOFTWARE\Microsoft\UPnP Device Host
,HKLM\SOFTWARE\Microsoft\WBEM\CIMOM\ProcessID
,HKLM\SOFTWARE\Microsoft\WBEM\PROVIDERS\Performance\Performance Refreshed
,HKLM\SOFTWARE\Microsoft\WBEM\Transports\Decoupled\Server\CreationTime
,HKLM\SOFTWARE\Microsoft\WBEM\Transports\Decoupled\Server\MarshaledProxy
,HKLM\SOFTWARE\Microsoft\WBEM\Transports\Decoupled\Server\ProcessIdentifier
,HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State
,HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData
,HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RecentDocs
,HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Rav\DisplayVersion
,HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\LicenseInfo
,HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Prefetcher
,HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList
,HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\WgaLogon\Settings
,HKLM\SOFTWARE\Microsoft\WZCSVC
,HKLM\SOFTWARE\rising\Rav\Version
,HKLM\SYSTEM\ControlSet001\Control\Session Manager
,HKLM\SYSTEM\ControlSet001\Enum
,HKLM\SYSTEM\ControlSet002\Control\Class\{4D36E96C-E325-11CE-BFC1-08002BE10318}\0005\GlobalSettings\Cmplx\Node000
,HKLM\SYSTEM\ControlSet002\Control\DeviceClasses\{6994AD04-93EF-11D0-A3CC-00A0C9223196}\##?#
,HKLM\SYSTEM\ControlSet002\Control\Lsa\LsaPid
,HKLM\SYSTEM\ControlSet002\Control\Print\Providers\LogonTime
,HKLM\SYSTEM\ControlSet002\Control\Session Manager
,HKLM\SYSTEM\ControlSet002\Control\Watchdog\Display\ShutdownCount
,HKLM\SYSTEM\ControlSet002\Control\Windows\ShutdownTime
,HKLM\SYSTEM\ControlSet002\Enum
,HKLM\SYSTEM\ControlSet002\Services\Dhcp\Parameters\{CB5197AD-D73A-4647-A7B9-21959A0AC4DF}
,HKLM\SYSTEM\ControlSet002\Services\Dhcp\Parameters\{9B5BD65E-7AB9-4A8B-BD34-FC9647252CFC}
,HKLM\SYSTEM\ControlSet002\Services\ialm\Device0\HardwareInformation.Crc32
,HKLM\SYSTEM\ControlSet002\Services\lanmanserver\parameters\Guid
,HKLM\SYSTEM\ControlSet002\Services\SharedAccess\Epoch\Epoch: 0x0000B0F3
,HKLM\SYSTEM\ControlSet002\Services\SynTP\Parameters\DetectTimeMS
,HKLM\SYSTEM\ControlSet002\Services\Tcpip\Parameters\Interfaces\{9209A459-27B0-4707-9470-6297A52C59C4}\NTEContextList
,HKLM\SYSTEM\ControlSet002\Services\Tcpip\Parameters\Interfaces\{9B5BD65E-7AB9-4A8B-BD34-FC9647252CFC}
,HKLM\SYSTEM\ControlSet002\Services\Tcpip\Parameters\Interfaces\{CB5197AD-D73A-4647-A7B9-21959A0AC4DF}
,HKLM\SYSTEM\ControlSet002\Services\{9B5BD65E-7AB9-4A8B-BD34-FC9647252CFC}\Parameters\Tcpip
,HKLM\SYSTEM\ControlSet002\Services\{CB5197AD-D73A-4647-A7B9-21959A0AC4DF}\Parameters\Tcpip\Lease
,HKLM\SYSTEM\ControlSet002\Services\{CB5197AD-D73A-4647-A7B9-21959A0AC4DF}\Parameters\Tcpip\T
,HKLM\SYSTEM\ControlSet003\Control\Lsa\LsaPid
,HKLM\SYSTEM\ControlSet003\Control\Print\Providers\LogonTime
,HKLM\SYSTEM\ControlSet003\Control\Watchdog\Display\ShutdownCount
,HKLM\SYSTEM\ControlSet003\Control\Windows\ShutdownTime
,HKLM\SYSTEM\ControlSet003\Control\ServiceCurrent
,HKLM\SYSTEM\ControlSet003\Control\Session Manager
,HKLM\SYSTEM\ControlSet003\Enum
,HKLM\SYSTEM\ControlSet003\Services\a8hdx80i
,HKLM\SYSTEM\ControlSet003\Services\Dhcp\Parameters\{9B5BD65E-7AB9-4A8B-BD34-FC9647252CFC}
,HKLM\SYSTEM\ControlSet003\Services\Dhcp\Parameters\{CB5197AD-D73A-4647-A7B9-21959A0AC4DF}
,HKLM\SYSTEM\ControlSet003\Services\ialm\Device0\HardwareInformation.Crc32
,HKLM\SYSTEM\ControlSet003\Services\lanmanserver\parameters\Guid
,HKLM\SYSTEM\ControlSet003\Services\mssmbios\Data\BiosData
,HKLM\SYSTEM\ControlSet003\Services\SharedAccess\Epoch\Epoch
,HKLM\SYSTEM\ControlSet003\Services\SynTP\Parameters\DetectTimeMS
,HKLM\SYSTEM\ControlSet003\Services\Tcpip\Parameters\Interfaces\{9B5BD65E-7AB9-4A8B-BD34-FC9647252CFC}
,HKLM\SYSTEM\ControlSet003\Services\{9B5BD65E-7AB9-4A8B-BD34-FC9647252CFC}\Parameters\Tcpip
,HKLM\SYSTEM\ControlSet003\Services\Tcpip\Parameters\Interfaces\{CB5197AD-D73A-4647-A7B9-21959A0AC4DF}\DhcpRetryTime
,HKLM\SYSTEM\ControlSet003\Services\Tcpip\Parameters\Interfaces\{CB5197AD-D73A-4647-A7B9-21959A0AC4DF}\Lease
,HKLM\SYSTEM\ControlSet003\Services\Tcpip\Parameters\Interfaces\{CB5197AD-D73A-4647-A7B9-21959A0AC4DF}\T
,HKLM\SYSTEM\ControlSet003\Services\{CB5197AD-D73A-4647-A7B9-21959A0AC4DF}\Parameters\Tcpip\Lease
,HKLM\SYSTEM\ControlSet003\Services\{CB5197AD-D73A-4647-A7B9-21959A0AC4DF}\Parameters\Tcpip\T
,HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses
,HKLM\SYSTEM\CurrentControlSet\Control\Lsa\LsaPid
,HKLM\SYSTEM\CurrentControlSet\Control\Print\Providers\LogonTime
,HKLM\SYSTEM\CurrentControlSet\Control\ServiceCurrent
,HKLM\SYSTEM\CurrentControlSet\Control\Session Manager
,HKLM\SYSTEM\CurrentControlSet\Control\Watchdog\Display\ShutdownCount
,HKLM\SYSTEM\CurrentControlSet\Control\Windows\ShutdownTime
,HKLM\SYSTEM\CurrentControlSet\Enum
,HKLM\SYSTEM\CurrentControlSet\Services\a8hdx80i
,HKLM\SYSTEM\CurrentControlSet\Services\Dhcp\Parameters\{9B5BD65E-7AB9-4A8B-BD34-FC9647252CFC}
,HKLM\SYSTEM\CurrentControlSet\Services\Dhcp\Parameters\{CB5197AD-D73A-4647-A7B9-21959A0AC4DF}
,HKLM\SYSTEM\CurrentControlSet\Services\Disk\Enum
,HKLM\SYSTEM\CurrentControlSet\Services\hpdskflt\Enum
,HKLM\SYSTEM\CurrentControlSet\Services\ialm\Device0\HardwareInformation.Crc32
,HKLM\SYSTEM\CurrentControlSet\Services\kmixer\Enum
,HKLM\SYSTEM\CurrentControlSet\Services\lanmanserver\parameters\Guid
,HKLM\SYSTEM\CurrentControlSet\Services\LVUSBSta\Enum
,HKLM\SYSTEM\CurrentControlSet\Services\mssmbios\Data\BiosData
,HKLM\SYSTEM\CurrentControlSet\Services\PartMgr\Enum
,HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Epoch\Epoch
,HKLM\SYSTEM\CurrentControlSet\Services\snapman380\Enum
,HKLM\SYSTEM\CurrentControlSet\Services\SynTP\Parameters\DetectTimeMS
,HKLM\SYSTEM\CurrentControlSet\Services\tdrpman174\Enum
,HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{9B5BD65E-7AB9-4A8B-BD34-FC9647252CFC}
,HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{CB5197AD-D73A-4647-A7B9-21959A0AC4DF}\DhcpRetryTime
,HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{CB5197AD-D73A-4647-A7B9-21959A0AC4DF}\Lease
,HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{CB5197AD-D73A-4647-A7B9-21959A0AC4DF}\T
,HKLM\SYSTEM\CurrentControlSet\Services\USBSTOR\Enum
,HKLM\SYSTEM\CurrentControlSet\Services\{9B5BD65E-7AB9-4A8B-BD34-FC9647252CFC}\Parameters\Tcpip
,HKLM\SYSTEM\CurrentControlSet\Services\{CB5197AD-D73A-4647-A7B9-21959A0AC4DF}\Parameters\Tcpip\Lease
,HKLM\SYSTEM\CurrentControlSet\Services\{CB5197AD-D73A-4647-A7B9-21959A0AC4DF}\Parameters\Tcpip\T
,HKU\%UserSID%\SessionInformation\ProgramCount
,HKU\%UserSID%\Software\Analog Devices\IFShare\{7524D05B-038A-4015-A453-C426CAEB4462}\OEMInfo
,HKU\%UserSID%\Software\Broadcom\802.11\AuthDom
,HKU\%UserSID%\Software\Broadcom\802.11\AuthUser
,HKU\%UserSID%\Software\Broadcom\802.11\AuthPass
,HKU\%UserSID%\Software\LopeSoft\FileMenu Tools
,HKU\%UserSID%\Software\Microsoft\Windows\CurrentVersion\Explorer\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}\DefaultIcon
,HKU\%UserSID%\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32
,HKU\%UserSID%\Software\Microsoft\Windows\CurrentVersion\Explorer\Discardable\PostSetup\Component Categories
,HKU\%UserSID%\Software\Microsoft\Windows\CurrentVersion\Explorer\Discardable\PostSetup\ShellNew
,HKU\%UserSID%\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts
,HKU\%UserSID%\Software\Microsoft\Windows\CurrentVersion\Explorer\MenuOrder
,HKU\%UserSID%\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2\
,HKU\%UserSID%\Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs
,HKU\%UserSID%\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU
,HKU\%UserSID%\Software\Microsoft\Windows\CurrentVersion\Explorer\SessionInfo
,HKU\%UserSID%\Software\Microsoft\Windows\CurrentVersion\Explorer\StartPage
,HKU\%UserSID%\Software\Microsoft\Windows\CurrentVersion\Explorer\StreamMRU
,HKU\%UserSID%\Software\Microsoft\Windows\CurrentVersion\Explorer\Streams
,HKU\%UserSID%\Software\Microsoft\Windows\CurrentVersion\Explorer\TrayNotify
,HKU\%UserSID%\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist
,HKU\%UserSID%\Software\Microsoft\Windows\CurrentVersion\Ext\Stats
,HKU\%UserSID%\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections
,HKU\%UserSID%\Software\Microsoft\Windows\CurrentVersion\Shell Extensions
,HKU\%UserSID%\Software\Microsoft\Windows\Shell\Bags
,HKU\%UserSID%\Software\Microsoft\Windows\ShellNoRoam\BagMRU
,HKU\%UserSID%\Software\Microsoft\Windows\ShellNoRoam\Bags
,HKU\%UserSID%\Software\Microsoft\Windows\ShellNoRoam\MUICache
,HKU\%UserSID%\Software\UniExtract\Directory,HKU\%UserSID%\Software\UniExtract\File
,HKU\%UserSID%\Software\WinRAR
Continue
shotClean.= thisline "`n"
}
shot=
;Checks the output that's left after cleaning
If (shotClean == "")
{
MsgBox, 4,, No entries left:`nEither they were all noise or or an error occurred.`nDo you wish to continue script?
IfMsgBox No
ExitApp
Return
}
Else If (denoise_On == 1)
FileAppend, %shotClean%, %filename%_denoised.txt
/*
This script cleans up RegShot output in the following ways:
-drops summary info, empty lines, deleted files/values, etc.
-drops "background noise" defined by the included "IgnoreList.txt" (you
should customize the file for your needs.)
-checks the existence of the remaining entries, and in the case of
changed registry values, reports their current value as well.
TAGS:
-untagged files and values were "Added" during the installation, or otherwise
recorded by RegShot as "Folders/Files Added" or "Keys/Values Added."
-"modified" tag refers to files that RegShot recorded as "Files [attributes?]
modified" or "Values modified" that have been re-modified since then.
-"added" and "current" tags refers to "Added" registry entries that still exist, but
have a different value than before.
*/
;clear values (not necessary, but just in case)...
var1:=var2:=var3:=var4:=var5:=root:=rPath:=sub:=val:=valNow:=vname:=FilesX:=RegX:=cTimes:=message1:=""
matcher:= 1, modOld:= 1, section:= ""
FileRead, IgnoreList, %A_ScriptDir%\IgnoreList.txt
;make sure IgnoreList has at least one entry so that subsequent appends may be proceeded by a ","
If (IgnoreList=="")
IgnoreList:= "C:\Documents and Settings\%A_UserName%\Local Settings\Temp"
Loop,Parse,shotClean,`n,`r
{
If (A_LoopField == "")
Continue
If A_LoopField Not Contains %IgnoreList%
{ ;regshot marks sections heading with a series of dashes
If (A_LoopField == "----------------------------------")
matcher*= -1
Else If (matcher == -1)
{
StringLeft, section, A_LoopField, % InStr(A_LoopField,":")-1
StringReplace,section,section,[attributes?]%A_Space%
}
Else
{
If (section == "Folders added")
{
If FileExist(A_LoopField)
{
Loop, %A_LoopField%,1
created:= A_LoopFileTimeCreated
FilesX.= A_LoopField " (" created ")`n"
}
Else IgnoreList.= "," A_LoopField ;if key doesn't exist, ignore values for it
}
Else If (section == "Files added") && FileExist(A_LoopField)
{
Loop, %A_LoopField%,1
created:= A_LoopFileTimeCreated
FilesX.= A_LoopField " (" created ")`n"
}
Else If (section == "Files modified") && FileExist(A_LoopField)
FilesX.= A_LoopField " (modified)`n"
Else If (section == "Keys added")
{
RegExMatch(A_LoopField,"^(HKLM|HKCR|HKCU|HKU|HKCC)?\\(.*(?=\\(.*))|.*)", r)
created=
Loop,%r1%,%r2%,2
{
If (A_LoopRegName == r3)
{
created:= A_LoopRegTimeModified
Break
}
}
If !created
IgnoreList.= "," . A_LoopField ;if key doesn't exist, ignore values for it
Else RegX.= r1 "\" r2 " (" created ")`n"
}
Else If (section == "Values added")
{
If RegEntrySplit(A_LoopField) != 0
{
valNow:= RegValConvert(root,sub,vname)
If (vname == "") ;use '(Default)' notation for nameless values
vname:= "(Default)"
If (val == valNow)
RegX.= root . "\" . sub . "\" . vname ": " . val . "`n"
Else RegX.= root . "\" . sub . "\" . vname ": " . val . " (added)`t`t" . root . "\" . sub . "\" . vname ": " . valNow . " (current)`n"
}
}
Else If (section == "Values modified")
{
If RegEntrySplit(A_LoopField) != 0
{
If (vname == "")
vname:= "(Default)"
;for modified reg entries, regShot displays the new value after the old one
;tabs are used instead of newlines to separate before/after/current values
;in order to preserve their order during an alphabetaical sort later on
;after the sort, they will be replaced with newlines
If modOld
RegX.= root . "\" . sub . "\" . vname ": " . val . " (mod_before)`t`t", modOld:=0
Else
{
valNow:= RegValConvert(root,sub,vname)
If (val == valNow)
RegX.= root . "\" . sub . "\" . vname ": " . val . " (mod_after)`n"
Else If (val != valNow)
RegX.= root . "\" . sub . "\" . vname ": " . val . " (mod_after)`t`t" . root . "\" . sub . "\" . vname ": " . valNow . " (mod_current)`n", modOld:= 1
}
}
}
Else If (section == "Folder/key creation times")
{
cTimes.= A_LoopField "`n"
}
}
}
}
IgnoreList=
;The next two If statements are used to sort the the file and registry entries
If (FilesX != "")
{
StringTrimRight,FilesX,FilesX,1 ;remove last empty line
FilesX:= RegExReplace(FilesX, "(.*?);(\d+)(\n|$)", "$2;$1$3") ;swap number with path
Sort, FilesX ;sort list in reverse numeric order
FilesX:= RegExReplace(FilesX, "(\d+);(.*?)(\n|$)", "$2;$1$3") ;swap back
If (saveFileList == 1)
{
message1.= "File log saved to " . filename . "_Files.txt`n"
FileDelete, %filename%_Files.txt
FileAppend, %FilesX%, %filename%_Files.txt
}
}
Else message1.= "No leftover file enries detected`n"
If (RegX != "")
{
StringTrimRight,RegX,RegX,1 ;remove last empty line
RegX := RegExReplace(RegX, "(.*?);(\d+)(\n|$)", "$2;$1$3") ;swap number with path
Sort, RegX ;sort list in reverse numeric order
RegX := RegExReplace(RegX, "(\d+);(.*?)(\n|$)", "$2;$1$3") ;swap back
;Replace tabs used to separate before/after/current modified registry
;values (to preserve their order during sorting) with newlines
StringReplace, RegX, RegX,%A_Tab%%A_Tab%,`n,All
If (SubStr(RegX,0,1) == "`n")
StringTrimRight,RegX,RegX,1
If (saveRegList == 1)
{
message1.= "Registry log saved to " . filename . "_Reg.txt"
FileDelete, %filename%_Reg.txt
FileAppend, %RegX%, %filename%_Reg.txt
}
}
Else message1.= "No leftover reg entries detected"
;Checks the output that's left after cleaning
If (FilesX == "" && RegX == "")
{
MsgBox,4,No %filepath% entries found:,Either they have already been uninstalled/removed, or an error occurred.`nDo you wish to keep the script active?
IfMsgBox No
ExitApp
Return
}
Else TrayTip, RegShot cleaned, %message1%, 10, 1
;Entries on probably harmless list are displayed in regular font (as opposed to boldface)
;the list is intended to contain values that the user is either still evaluating (before
;adding them to the Ignore List, or that are frequently modified or added during reboots
;or otherwise as part of normal Windows XP operation, and should not be deleted unless
;user has special reason for doing so.
NoHarm=
FileRead, NoHarm, %A_ScriptDir%\ProbablyHarmless.txt
/*
kudos to hd0202 (Hubert) for the core treeview script here:
http://www.autohotkey.com/forum/viewtopic.php?p=264219#264219
*/
TreeViewWidth:= A_ScreenWidth/2
TreeViewHeight:= A_ScreenHeight*2/3
ListViewWidth:= TreeViewWidth*2
ListViewHeight:= TreeViewHeight/2
ButY:= TreeViewHeight+10
Gui, Add, TreeView, AltSubmit RightClick vFileTree h%TreeViewHeight% w%TreeViewWidth% gFileTree
Gui, Add, TreeView, AltSubmit RightClick vRegTree h%TreeViewHeight% w%TreeViewWidth% x+10 ym gRegTree
Gui +VScroll +HScroll
Gui, Font,cRed, Arial
Gui, Add, ListView, AltSubmit Checked vMyList h%ListViewHeight% w%ListViewWidth% x0 y+50 gMyList, Time|Folder or key
Gui +Resize
; Set the ListView's column widths (this is optional):
Col1Width = 250 ; Narrow to reveal only the YYYYMMDD part.
LV_ModifyCol(1, Col1Width) ; Allows room for vertical scrollbar.
LV_ModifyCol(2, ListViewWidth - Col1Width - 30)
Gui, Add, StatusBar
SB_SetParts(1.65*TreeViewWidth)
Gui, TreeView, SysTreeView321
AddBranchesToTree(FilesX) ;list needs to be sorted
Gui, TreeView, SysTreeView322
AddBranchesToTree(RegX,1) ;list needs to be sorted
OnMessage(0x203, "DOUBLECLICK") ; double-click opens file in new window
Gui, ListView, SysListView321
AddTimesToTree(cTimes)
cHeight:= TreeViewHeight-40
Gui, Add, Button, section +AltSubmit vFilter xm+10 ym+%cHeight% w60 h40 gFilter, Re-filter
Gui, font, s10 bold cBlack
Gui, Add, Text, +AltSubmit vTxtHeadingTH xm+80 ys w110 h40,Set seconds:`n(filer threshold)
Gui, font,s18
Gui, Add, Edit, +AltSubmit vEditTH xm+200 ys w70 h40 Right
Gui, Add, UpDown, +AltSubmit vThreshold Range1-999 gThreshold, 10.
Gui, font
Gui, Add, Text, vTxtBodyTH xm+290 ys w200 h40,Tree entries within set number of seconds of checked time entries below will be displayed in bold.
Gui, Show ;Show the window and its TreeView.
Return
GuiSize: ;Expand/shrink the ListView and TreeView in response to user's resizing of window.
If (A_EventInfo == 1) ;The window has been minimized. No action needed.
Return
;Otherwise, the window has been resized or maximized. Resize the controls to match.
GuiControl, Move, FileTree, % "H" . (A_GuiHeight*2/3-15) . " W" . (A_GuiWidth/2 - 15)
GuiControl, Move, RegTree, % "H" . (A_GuiHeight*2/3-15) . " W" . (A_GuiWidth/2 - 15) . " X" . (A_GuiWidth/2+10)
GuiControl, MoveDraw, MyList, % "H" . (A_GuiHeight*1/3-15) . " W" . (A_GuiWidth - 30) " Y" . (A_GuiHeight*2/3+50)
GuiControl, MoveDraw, Filter, % "Y" . (A_GuiHeight*2/3+5)
GuiControl, MoveDraw, TxtHeadingTH, % "Y" . (A_GuiHeight*2/3+5)
GuiControl, MoveDraw, EditTH, % "Y" . (A_GuiHeight*2/3+5)
GuiControl, MoveDraw, Threshold, % "Y" . (A_GuiHeight*2/3+5)
GuiControl, MoveDraw, TxtBodyTH, % "Y" . (A_GuiHeight*2/3+5)
Return
Threshold:
Return
Filter:
Gui, ListView, MyList
tList=
RowNumber = 0 ;This causes the first loop iteration to start the search at the top of the list.
Loop
{
RowNumber := LV_GetNext(RowNumber,"Checked")
if not RowNumber
break
LV_GetText(Text, RowNumber)
tList.= SubStr(Text, -14,14) ","
}
;add loop that checks entries in tree and highlights matches
If tList
{
StringTrimRight,tList,tList,1 ;remove empty line at end
; Causes the loop's first iteration to start the search at the top of the tree.
trees = FileTree,RegTree
Loop,Parse,trees,`,
{
Gui, TreeView, %A_LoopField%
ItemID = 0
rTree:= (A_LoopField == "RegTree") ? 1 : 0
Loop
{
ItemID := TV_GetNext(ItemID, "Full") ; Replace "Full" with "Checked" to find all checkmarked items.
If Not ItemID ; No more items in tree.
Break
;else check time stamp
If ct:= ct%ItemID%
{
Loop,parse,tList,`,
{
new:= A_LoopField
EnvSub,new,%ct%,seconds
If Abs(new) < threshold
{
TV_Modify(ItemID,"Bold")
If rTree
{
ChildID:= ItemID, parents:= ItemID
Loop
{
ChildID:= TV_GetNext(ChildID,"Full"), ParentID:= TV_GetParent(ChildID)
If ParentID Not In %parents%
Break
TV_Modify(ChildID,"Bold")
parents.= "," . ChildID
}
}
Break
}
Else
{
TV_Modify(ItemID,"-Bold")
If rTree
{
ChildID:= ItemID, parents:= ItemID
Loop
{
ChildID:= TV_GetNext(ChildID,"Full"), ParentID:= TV_GetParent(ChildID)
if ParentID Not In %parents%
Break
TV_Modify(ChildID,"-Bold")
parents.= "," . ChildID
}
}
}
}
}
}
}
}
Return
FileTree: ;This subroutine handles user actions (such as clicking).
If A_GuiEvent <> S ;i.e. an event other than "select new tree item".
Return ;Do nothing.
TV_GetText(SelectedItemText, A_EventInfo)
varname:= SelectedItemText
ParentID:= A_EventInfo
Loop ;Build the full path to the selected folder.
{
ParentID:= TV_GetParent(ParentID)
If not ParentID ;No more ancestors.
Break
TV_GetText(ParentText, ParentID)
SelectedItemText = %ParentText%\%SelectedItemText%
}
SelectedPath = %TreeRoot%\%SelectedItemText%
StringTrimLeft, SelectedPath, SelectedPath, 1
StringTrimRight, SelectedPath, SelectedPath, % StrLen(varname)+1
varname:= RegExReplace( varname, "i)\s\((added|current|modified)\)$","",mods)
SB_SetText(SelectedPath, 1)
if ct_selected:= ct%A_EventInfo%
FormatTime, ct_selected, %ct_selected%, MMM d, yyyy hh:mm:ss tt
SB_SetText(ct_selected, 2)
Return
RegTree: ;This subroutine handles user actions (such as clicking).
If A_GuiEvent <> S ;i.e. an event other than "select new tree item".
Return ;Do nothing.
TV_GetText(SelectedItemText, A_EventInfo)
varname:= SelectedItemText
ParentID := A_EventInfo
Loop ;Build the full path to the selected folder.
{
ParentID := TV_GetParent(ParentID)
If not ParentID ; No more ancestors.
break
TV_GetText(ParentText, ParentID)
SelectedItemText = %ParentText%\%SelectedItemText%
}
SelectedPath = %TreeRoot%\%SelectedItemText%
StringTrimLeft, SelectedPath, SelectedPath, 1
StringTrimRight, SelectedPath, SelectedPath, % StrLen(varname)+1
varname:= RegExReplace( varname, "\s\((added|current|modified|mod_after|mod_before|mod_current)\)$","",mods)
SB_SetText(SelectedPath, 1)
if ct_selected:= ct%A_EventInfo%
FormatTime, ct_selected, %ct_selected%, MMM d, yyyy hh:mm:ss tt
SB_SetText(ct_selected, 2)
Return
MyList:
Return
GuiContextMenu:
Menu, RegshotCleanerMenu, Add,
Menu, RegshotCleanerMenu, DeleteAll
If (A_GuiControl == "FileTree")
{
Gui, TreeView, FileTree
idd:= TV_GetSelection()
Menu, RegshotCleanerMenu, Add, Go to selected file entry, MenuHandler
Menu, RegshotCleanerMenu, Add, Delete file or folder, MenuHandler
Menu, RegshotCleanerMenu, Add, Add entry to Ignore List, MenuHandler
Menu, RegshotCleanerMenu, Add, Add entry to Probably Harmeless List, MenuHandler
}
Else If (A_GuiControl == "RegTree")
{
Gui, TreeView, RegTree
idd:= TV_GetSelection(), chid_idd:= TV_GetChild(idd)
Menu, RegshotCleanerMenu, Add, Go to selected reg entry, MenuHandler
Menu, RegshotCleanerMenu, Add, Delete registry entry, MenuHandler
If chid_idd
{
Menu, RegshotCleanerMenu, Add, Add entry to Ignore List, MenuHandler
Menu, RegshotCleanerMenu, Add, Add entry to Probably Harmeless List, MenuHandler
}
}
Menu, RegshotCleanerMenu, Show
Return
DOUBLECLICK()
{
global SelectedPath, varname
MouseGetPos,,,, control,1
If (control == "SysTreeView321")
Run %COMSPEC% /c explorer.exe /select`, %SelectedPath%\%varname%,, Hide
Else If (control == "SysTreeView322")
OpenWithRegEdit(SelectedPath . "\" . varname)
Else Return
}
MenuHandler:
If (A_ThisMenuItem == "Go to selected file entry")
Run %COMSPEC% /c explorer.exe /select`, %SelectedPath%\%varname%,, Hide
Else If (A_ThisMenuItem == "Go to selected reg entry")
OpenWithRegEdit(SelectedPath . "\" . varname)
Else If (A_ThisMenuItem == "Delete file or folder")
{
MsgBox,4,Confirm Deletetion,Are you sure you want to delete`n%SelectedPath%\%varname%?
IfMsgBox, Yes
FileDelete, %SelectedPath%\%varname%
If !ErrorLevel
TV_Delete(idd)
}
Else If (A_ThisMenuItem == "Delete registry entry")
{
MsgBox,4,Confirm Deletetion,Are you sure you want to delete`n%SelectedPath%\%varname%?
IfMsgBox, No
Return
bsDel:= InStr(SelectedPath,"\"), rootDel:= SubStr(SelectedPath,1,bsDel-1), subDel:= SubStr(SelectedPath, bsDel+1)
If colDel:= InStr(varname,":")
{
valDel:= SubStr(varname,1,colDel-1)
RegDelete,%rootDel%,%subDel%,%valDel%
}
Else RegDelete,%rootDel%,%subDel%\%varname%
If !ErrorLevel
TV_Delete(idd)
}
Else If (A_ThisMenuItem == "Add entry to Ignore List")
{
If FileExist(A_ScriptDir . "\IgnoreList.txt")
FileAppend, `,%SelectedPath%\%varname%, %A_ScriptDir%\IgnoreList.txt
Else FileAppend, %SelectedPath%\%varname%, %A_ScriptDir%\IgnoreList.txt
;TrayTip,Ignore List addition,`n%SelectedPath%\%varname% was added to`n%A_ScriptDir%\IgnoreList.txt,10
If !ErrorLevel
TV_Delete(idd)
}
Else If (A_ThisMenuItem == "Add entry to Probably Harmeless List")
{
If FileExist(A_ScriptDir . "\ProbablyHarmless.txt")
FileAppend, `,%SelectedPath%\%varname%, %A_ScriptDir%\ProbablyHarmless.txt
Else FileAppend, %SelectedPath%\%varname%, %A_ScriptDir%\ProbablyHarmless.txt
If !ErrorLevel
{
TV_Modify(idd,"-Bold -Expand")
ItemID:= idd, parents:= idd ; Causes the loop's first iteration to start the search at the top of the tree.
Loop
{
ItemID:= TV_GetNext(ItemID,"Full"), ParentID:= TV_GetParent(ItemID)
if ParentID Not In %parents%
break
TV_Modify(ItemID,"-Bold")
parents.= "," . ItemID
}
}
}
Return
GuiEscape:
GuiClose:
ExitApp
RegEntrySplit(RegString="")
{
global
RegExMatch(RegString,"i)^(HKLM|HKCR|HKCU|HKU|HKCC)\\(?:((.*)\\(.*?)(?::\s)(.*)|.*))", rPath)
root:= rPath1
If rPath3 <>
{
sub:= rPath3, vname:= rPath4, val:= rPath5
If SubStr(val,1,1) = """" && SubStr(val, 0,1) = """"
StringMid,val,val,2,% StrLen(val)-2 ;remove excess "
Else If SubStr(val,1,1) = "'" && SubStr(val, 0,1) = "'"
StringMid,val,val,2,% StrLen(val)-2 ;remove excess '
RegRead, valNow, %root%, %sub%, %vname%
If (valNow != "")
Return root "`n" sub "`n" vname "`n" val "`n" valNow
Else Return 0
}
Else
{
sub:= rPath2, keycount:= 0
Loop %root%, %sub%, 1 ;checks if key exists
keycount++
If (keycount > 0)
Return root "`n" sub
Else Return 0
}
}
;RegValConvert (tbe function below) converts AHK format of REG_DWORD and REG_BINARY
;values to the format used by RegShot. Other value types already use equivalent
;formats. The point is to enable the script to compare the current registry values
;to those recorded by RegShot
RegValConvert(root="",sub="",vname="")
{
Loop, %root%, %sub%
{
If (A_LoopRegName == vname)
{
VarSetCapacity(valNow,20)
If (A_LoopRegType == "REG_DWORD")
{
SetFormat, IntegerFast, H
RegRead, valNow, %root%, %sub%, %vname%
valNow:= % "0x" SubStr("00000000" SubStr(valNow+0, 3), -7)
SetFormat, IntegerFast, D
}
Else
{
RegRead, valNow, %root%, %sub%, %vname%
If (A_LoopRegType == "REG_BINARY")
valNow:= RegExReplace(valNow, "..(?=.)", "$0 ")
Else If (A_LoopRegType == "REG_MULTI_SZ")
StringTrimRight,valNow,valNow,1
}
Break
}
}
Return valNow
}
AddBranchesToTree(filelist,logtype=0)
{
global
local tOptions:= "bold expand", level:= 0, parent0:= 0
local bs,file,file0,file1,prev_file,parent1,pLev,prev_parent
Loop,Parse,filelist,`n
{
If A_LoopField =
Continue
If logtype = 0
stringsplit, parts, A_LoopField, \ ;drive + folders ( + file)
;remove time stamps
parts%parts0% := RegExReplace(parts%parts0%," \(\d{14}\)$","",replaced)
cTime:= replaced ? SubStr(A_LoopField,-14,14) : 0
If logtype = 1
{
If colon1:= InStr(A_LoopField,":")
{
regstr1:= SubStr(A_LoopField, 1, colon1), regstr2:= SubStr(A_LoopField, colon1+1)
stringsplit, parts, regstr1, \ ;drive + folders ( + file)
parts%parts0% .= regstr2
}
Else
{
stringsplit, parts, A_LoopField, \ ;drive + folders ( + file)
parts%parts0% := RegExReplace(parts%parts0%," \(\d{14}\)$","",replaced)
if replaced
cTime:= SubStr(A_LoopField,-14,14)
}
}
If (level == 0) ;first record, insert all parts
{
gosub build_tree
continue
}
IfInString, A_LoopField, %prev_file% ;sub folders or files
{
gosub build_tree
continue
}
line:= A_LoopField ;other drive or folder
If (parts0 > level) ;ignore parts > level
loop, % parts0 - level - 1
StringLeft, line, line, % InStr(line,"\",false,0)
Else level:= parts0 ;set level to no of parts
loop, % level
{
StringLeft, line, line, % InStr(line,"\",false,0)-1
level--
If (level == 0) ;other drive
prev_file:= "", bs:= ""
Else ;find corresponding level
{
prev_file:= file%level%, lineTmp:= line . "\"
IfNotInString, lineTmp, %prev_file%\
Continue
If (level == 0)
level++
}
gosub build_tree
Break
}
}
Return
build_tree:
loop, % parts0 - level
{
If (A_Index == 1)
{
tOptions:= "bold expand"
label:= SubStr(parts%parts0%,-10)
}
prev_parent = parent%level%
level++
if label In (mod_after),mod_before),od_current), (modified)
tOptions:= "expand"
parent%level% := tv_add(parts%level%, %prev_parent%, tOptions)
pLev:= parent%level%, ct%pLev%:= cTime
If (level <> 1)
bs = \
file%level%:= prev_file bs parts%level%, prev_file:= file%level%
}
Return
}
AddTimesToTree(timelist)
{
LV_Delete() ; Clear all rows.
GuiControl, -Redraw, MyListView ; Improve performance by disabling redrawing during load.
Loop, Parse, timelist, `n, `r
{
StringSplit, timeData,A_LoopField,`,
LV_Add("Check", timeData1, timeData2)
}
GuiControl, +Redraw, MyListView
}
;kudos to JBensimon from AHK forum for the 'LastKey' trick
OpenWithRegEdit(path="")
{
path:= "My Computer\" . path
StringReplace,path,path,HKCR,HKEY_CLASSES_ROOT
StringReplace,path,path,HKCU,HKEY_CURRENT_USER
StringReplace,path,path,HKLM,HKEY_LOCAL_MACHINE
StringReplace,path,path,HKU,HKEY_USERS
StringReplace,path,path,HKCC,HKEY_CURRENT_CONFIG
IfWinExist, Registry Editor ahk_class RegEdit_RegEdit
WinClose
RegWrite,REG_SZ,HKCU,Software\Microsoft\Windows\CurrentVersion\Applets\Regedit,LastKey,%path%
run regedit.exe
}
I also wrote an InCtrl5 launcher that includes the previous script (the original log is not deleted, the launcher simply automates a few steps, then converts the InCtrl5-log (CSV-format required) into RegShot format, and saves it under the original name, but with TXT extension:
Code:
/*
THIS SCRIPT HAS TO RESIDE IN THE SAME FOLDER AS InCtrl5.EXE
IN ORDER FOR THE SETTINGS IN InCtrl5.INI TO TAKE EFFECT
written on AutoHotkey v1.0.48.03 and tested only on Windows XP/SP3
Note: Since the user may wish to load or save snapshots prior to
creating a comparison report, all 'Save As' and 'Open' windows (of the
ahk_class #32770 variety) will have to be closed before the comparison
button click will be automated.
*/
#NoEnv
#SingleInstance force
#Persistent
SetWorkingDir % A_ScriptDir
SendMode Input
SetTitleMatchMode Regex
SetBatchLines -1
SetControlDelay -1
SetWinDelay -1
Process,Priority,,AboveNormal
OnExit, HouseKeep
Menu, tray, icon, InCtrl5.exe ;InCtrl5 tray icon
;specify location where shots and reports should be stored
shotsDir:= "Z:\_Backups\InCtrl5logs"
;set get_cTimes to 0 to not retrieve creation times for new folders and keys
get_cTimes:= 1
;to record additional info (default = files on C:\ only and boot.ini content)
;set recordExtraInfo:= 1 and specify a folder for AHK recorded shots.
recordExtraInfo:= 0
ahkShotsDir:= "Z:\_Backups\AhkShots"
;monitoredFiles =
IfWinExist, InCtrl5 - Install Control for Windows ahk_class TMainForm
ExitApp
;if specified folder does not exist, use the one from InCtrl5.ini
If !InStr(FileExist(shotsDir),"D")
IniRead,shotsDir,InCtrl5.ini,Settings,ReptPath
;if that folder doesn't exist either, use 'My Documents'
If !InStr(FileExist(shotsDir),"D")
shotsDir:= A_MyDocuments
InputBox, repName, InCtrl5 Launcher, Input a name for this shot:,,,130
;If ErrorLevel
; ExitApp
;Sleep, 50
WinWaitClose, InCtrl5 Launcher ahk_class #32770
If recordExtraInfo
{
;delete previous shots of same name
FileDelete,%ahkShotsDir%\%repName%_InCtrl1.ini
FileDelete,%ahkShotsDir%\%repName%_InCtrl2.ini
;record new shot
Gosub, RecordAhkShot
}
Process,Exist,InCtrl5.exe
If !pid:= ErrorLevel
Run,InCtrl5.exe,,,pid
PID = ahk_pid %pid%
WinWait,%PID%,,5
If ErrorLevel
ExitApp
;if the first shot has already been taken, click install complete
ControlGetText,buttext,TButton2,%PID%
If (buttext == "&Install complete")
ClickUntil("&Install complete",PID,"Enabled",0)
Else If (repName != "") ;set report name, take shot
{
ClickUntil("TButton3",PID,"WinWait","Choose Report Filename")
ControlSetText,Edit1,%shotsDir%\%repName%,Choose Report Filename
ClickUntil("&Save","Choose Report Filename","WinWaitClose","Choose Report Filename")
}
SetTimer, check, 250
check:
IfWinExist, InCtrl5 report preview ahk_class TReptForm
{
SetTimer, check, Off
ControlGetText,repPath,TPanel1,InCtrl5 report preview ahk_class TReptForm
If (repPath != shotsDir "\" repName ".CSV")
{
bs:= InStr(repPath,"\",False,0), repName2:= SubStr(repPath, bs+1), repDir2:= SubStr(repPath,1,bs-1)
StringTrimRight,repName2,repName2,4
MsgBox,4,Previous report name does not match the name specified by user
,Change report name to %repName2% in directory %repDir2%
IfMsgBox, No
ExitApp
Else shotsDir:=repDir2, repName:=repName2
}
ClickUntil("TButton2","InCtrl5 report preview ahk_class TReptForm","WinWaitClose","InCtrl5 report preview ahk_class TReptForm")
ClickUntil("TButton4",PID,"WinWaitClose",PID)
If ErrorLevel
Process, Close, InCtrl5.exe
If recordExtraInfo
Gosub, RecordAhkShot
;check for new folders and keys and append their creation times to the report
loop,
{
If FileExist(shotsDir . "\" . repName . ".CSV")
Break
Sleep, 250
If (A_Index > 40)
{
MsgBox,,Error, cannot find report
ExitApp
}
}
Gosub, trimReport
Run %shotsDir%\%repName%.TXT
ExitApp
}
IfWinNotExist %PID%
ExitApp
Return
trimReport:
FileRead,report,%shotsDir%\%repName%.CSV
reportClean:= "InCtrl5`nComments:`nDatetime:"
;folders matching RegEx criteria below will be dropped
pattern1 = iU)C:\\(Documents\sand\sSettings\\.*\\(Application\sData\\Rising\\common|Cookies|IETldCache|Local\sSettings\\(History\\History\.IE5|Temporary\sInternet\sFiles\\Content\.IE5))|WINDOWS\\(Prefetch|system32\\Returnil\\RVS3))\\
;keys matching the RegEx criteria below will be dropped (these are from InCtrl5)
pattern2 = iU)HKLM\\SYSTEM\\ControlSet002\\Control\\(Class\\\{(53D29EF7-377C-4D14-864B-EB3A85769359|7EBEFBC0-3200-11D2-B4C2-00A0C9697D07|C06FF265-AE09-48F0-812C-16753D7CBA83)}\\|MediaResources\\(icm|msacm)\\.*)
;convert to regshot format
Loop,Parse,report,`n,`r
{
If StrLen(A_LoopField) > 65534
Continue
Loop,Parse,A_LoopField,CSV
var0:= A_Index, var%A_Index%:= A_LoopField
If var1 In Type,Header
{
If (A_Index == 5)
reportClean.= var2 " " var3 "`nComputer:" A_ComputerName "`nUsername:" A_UserName
Continue
}
If var3 In ignored,tracked,Action,------------
Continue
If (var3 == "deleted" && SubStr(var1,-3) != "file")
Continue
StringReplace,var3,var3,changed,modified
section:= (var1 == "INI file" || var1 == "Text file") ? var1 " " var2 " changed" : var2 " " var3
If (section != prevsection)
{
If reportCleanTemp
{
Sort,reportCleanTemp,U
StringReplace,reportCleanTemp,reportCleanTemp,%A_Tab%%A_Tab%,`n,All
reportClean.= reportCleanTemp
reportCleanTemp=
}
reportClean.= "`n`n----------------------------------`n" section ":`n----------------------------------"
}
prevsection:= section
If (var1 == "Registry")
{
StringReplace,var4,var4,HKEY_CLASSES_ROOT,HKCR
StringReplace,var4,var4,HKEY_CURRENT_USER,HKCU
StringReplace,var4,var4,HKEY_LOCAL_MACHINE,HKLM
StringReplace,var4,var4,HKEY_USERS,HKU
StringReplace,var4,var4,HKEY_CURRENT_CONFIG,HKCC
StringReplace,var8,var8,`,,,All
StringReplace,var9,var9,`,,,All
If (var2 == "Keys")
{
If RegExMatch(var4,pattern2)
Continue
reportCleanTemp.= "`n" var4
If get_cTimes
{
created=
bs:= InStr(var4,"\"), root:= SubStr(var4,1,bs-1), sub:= SubStr(var4, bs+1), bs:= InStr(sub,"\",False,0), key:= SubStr(sub, bs+1), sub:= SubStr(sub,1,bs-1)
Loop,%root%,%sub%,2
{
If (A_LoopRegName == key)
{
created:= A_LoopRegTimeModified
Break
}
}
If created <>
cTimes.= created "," var4 "`n"
}
}
Else
{
reportCleanTemp.= "`n" var4 "\" var5 ": "
If (var3 == "added")
reportCleanTemp.= var7
Else If (var3 == "modified")
reportCleanTemp.= var8 "`t`t" var4 "\" var5 ": " var9
}
}
Else If (var1 == "Disk contents")
{
If RegExMatch(var4,pattern1)
Continue
If Var4 Contains c:\Documents and Settings\%A_UserName%\Local Settings\Temp
,c:\Documents and Settings\%A_UserName%\Recent
,%A_ProgramFiles%\Rising\Rav\
,%A_ProgramFiles%\Tall Emu\Online Armor\
,%A_WinDir%\Temp\
Continue
If Var5 In 0.log,catdb,desktop.ini,edb.chk,edb.log
,ntuser.dat,ntuser.dat.LOG,rvs3.log,software.LOG,system.LOG,tmp.edb
Continue
If (var2 == "Folders")
{
reportCleanTemp.= "`n" var4
If get_cTimes
{
created=
Loop, %var4%, 1
created:= A_LoopFileTimeCreated
If created <>
cTimes.= created "," var4 "`n"
}
}
Else reportCleanTemp.= "`n" var4 var5
}
Else If (var1 == "INI file")
{
reportCleanTemp.= "`n" var4 ": value '" var5 "' " var3
If (var3 == "modified")
reportCleanTemp.= " from " var6 " to " var7
}
Else If (var1 == "Text file")
tmp:= (var3 == "added") ? "to" : "from", reportCleanTemp.= (var5 == "") ? "`n" var4 ": new line " var3 " " tmp " line " var6 : "`n" var4 ": '" var5 "' " var3 " " tmp " line " var6
}
report=
If reportCleanTemp
{
Sort,reportCleanTemp,U
StringReplace,reportCleanTemp,reportCleanTemp,%A_Tab%%A_Tab%,`n,All
reportClean.= reportCleanTemp
}
;append times new folder and keys were created
If (get_cTimes && cTimes != "")
{
reportClean.= "`n`n----------------------------------`nFolder/key creation times:`n----------------------------------"
varOld:= "NoZeroLengthError", var1:= var2:= ""
;remove duplicates
Sort, cTimes, N U
StringTrimRight,cTimes,cTimes,1
Loop,Parse,cTimes,`n
{
;remove subfolders with same time stamps
lo:= StrLen(varOld), varNew:= SubStr(A_LoopField,1,lo)
If (varOld == varNew)
Continue
StringSplit,var,A_LoopField,`,
If (var1 == var1old)
reportClean.= "`t|`t" var2
Else
{
FormatTime, cTime, %var1%, M/d/yyyy hh:mm:ss tt
reportClean.= "`n" cTime " (" var1 "), " var2
}
var1old:= var1, var2old= var2, varOld:= A_LoopField
}
}
;remove emtry section headings
pattern3 = mU)-{34}\n[a-zA-Z: ]+\n-{34}\n(\n|$)
reportClean:= RegExReplace(reportClean,pattern3,"")
;delete previous copy (not original) if one exists
FileDelete, %shotsDir%\%repName%.TXT
FileAppend, %reportClean%,%shotsDir%\%repName%.TXT
Return
/*
the RecordAhkShot subroutine is a carry-on from my regshot launcher, which I added to
it to mimic InCtrl5's built-in tracking capability for user-specified ini and text files.
I left it in for users (maybe myself) who, for example, want to only track files added
to C:\ without the manadatory recursion into subfolders programmed into InCtrl5.
*/
RecordAhkShot:
sNum:= FileExist(ahkShotsDir . "\" . repName . "_InCtrl1.ini") ? 2 : 1, ahkShot:= "[MAIN]", contents:= ""
Loop, C:\*.*, 1, 0
{
ahkShot.= "`n" A_LoopFileName "=" A_LoopFileTimeCreated "," A_LoopFileTimeModified "," A_LoopFileAttrib
If A_LoopFileName In %monitoredFiles%
{
FileRead, fileContent, %A_LoopFileFullPath%
StringReplace,fPath,A_LoopFileFullPath,:
StringReplace,fPath,fPath,\,_,All
StringReplace,fileContent,fileContent,[,{{,All
StringReplace,fileContent,fileContent,],}},All
contents.= "[" . fPath . "]`n" . fileContent . "`n"
}
}
FileAppend,%ahkShot%`n`n%contents%,%ahkShotsDir%\%repName%_InCtrl%sNum%.ini
Return
HouseKeep:
If cTimes
{
;remove duplicates
Sort, cTimes, U
reportClean.= "`n`n----------------------------------`nFolder/key creation times:`n----------------------------------`n" cTimes
FileAppend, %reportClean%,%shotsDir%\%repName%.TXT
}
If (recordExtraInfo == 1 && sNum == 1)
FileAppend,%ahkShot%`n`n%contents%,%ahkShotsDir%\%repName%_InCtrl2.ini
ExitApp
ClickUntil(button="",window="",action="",waitFor="")
{
loop, 6
{
ControlClick,%button%,%window%
If (action == "WinWait")
{
WinWait,%waitFor%,,0.5
If !ErrorLevel
Break
}
Else If (action == "WinWaitClose")
{
WinWaitClose,%waitFor%,,0.5
If !ErrorLevel
Break
}
Else If (action = "Enabled")
{
controlget,state,%action%,,%button%,%window%
If (state == waitfor)
Break
Sleep, 500
}
}
}
disclaimer: use at your own risk... work in progress... customize the ignore lists... bla bla bla...