Jump to content

Exporting HKCU registry entries from a MSI file using Script


Recommended Posts

Hello Guys, 
 
Am working on a scenario, 
Read all the HKCU Registry keys present in a MSI file(Windows Installer File, will provide you an example if required for reference), and Exporting them to a any output folder. 
 
MSi File (Windows Installer File, will provide you an example if required for reference)
 
I tried with many scripts, C#, autoit ... I can go up to reading the HKCU files only. 
Not able to export them to a output folder. 
Please help me in doing this successfully, Am hitting my head against wall 
 
Can you please help in logic for the same. 
 
Please Help 
 
Cheers, 
Link to comment
Share on other sites

Example http://msdn.microsoft.com/en-us/library/aa372865(v=vs.85).aspx

#include <Array.au3>

Global Const $msiOpenDatabaseModeReadOnly     = 0  ;; Opens a database read-only, no persistent changes.
Global Static $oInstaller, $oDatabase, $oView, $oRecord, $sFilePath, $aRegistry[101][4] = [[0,100]]

$sFilePath = FileOpenDialog("Select a MSI file...", @ScriptDir, "MSI (*.msi)") ;;"MSI (*.msi;*.msp)"
If Not @Error Then
    $oInstaller = ObjCreate("WindowsInstaller.Installer")
    If IsObj($oInstaller) Then
        $oDatabase = $oInstaller.OpenDatabase($sFilePath, $msiOpenDatabaseModeReadOnly)
        If IsObj($oDatabase) Then
            $oView = $oDatabase.OpenView("SELECT `Registry`.`Key`, `Registry`.`Name`, `Registry`.`Value` FROM `Registry` WHERE `Registry`.`Root`=0 ORDER BY `Registry`.`Root`")
            If IsObj($oView) Then
                $oView.Execute()
                While 1
                    $oRecord = $oView.Fetch
                    If Not IsObj($oRecord) Then ExitLoop
                    $aRegistry[0][0] += 1
                    If $aRegistry[0][0] = $aRegistry[0][1] Then
                        $aRegistry[0][1] *= 2
                        ReDim $aRegistry[$aRegistry[0][1] + 1][4]
                    EndIf
                    $aRegistry[$aRegistry[0][0]][0] = "HKCR"
                    For $i = 1 To 3
                        $aRegistry[$aRegistry[0][0]][$i] = $oRecord.StringData($i)
                    Next
                WEnd
                $oView.Close
                ReDim $aRegistry[$aRegistry[0][0] + 1][4]
            Else
                MsgBox(0, "Error", 4)
            EndIf
        Else
            MsgBox(0, "Error", 3)
        EndIf
    Else
        MsgBox(0, "Error", 2)
    EndIf
Else
    MsgBox(0, "Error", 1)
EndIf
$oView = ""
$oDatabase = ""
_ArrayDisplay($aRegistry)
#include <Array.au3>
 
Global Const $msiOpenDatabaseModeReadOnly     = 0  ;; Opens a database read-only, no persistent changes.
Global Static $oInstaller, $oDatabase, $oView, $oRecord, $sFilePath, $aRegistry[101][4] = [[0,100]]
 
$sFilePath = FileOpenDialog("Select a MSI file...", @ScriptDir, "MSI (*.msi)") ;;"MSI (*.msi;*.msp)"
If Not @Error Then
    $oInstaller = ObjCreate("WindowsInstaller.Installer")
    If IsObj($oInstaller) Then
        $oDatabase = $oInstaller.OpenDatabase($sFilePath, $msiOpenDatabaseModeReadOnly)
        If IsObj($oDatabase) Then
            $oView = $oDatabase.OpenView("SELECT `Registry`.`Key`, `Registry`.`Name`, `Registry`.`Value` FROM `Registry` WHERE `Registry`.`Root`=1 ORDER BY `Registry`.`Root`")
            If IsObj($oView) Then
                $oView.Execute()
                While 1
                    $oRecord = $oView.Fetch
                    If Not IsObj($oRecord) Then ExitLoop
                    $aRegistry[0][0] += 1
                    If $aRegistry[0][0] = $aRegistry[0][1] Then
                        $aRegistry[0][1] *= 2
                        ReDim $aRegistry[$aRegistry[0][1] + 1][4]
                    EndIf
                    $aRegistry[$aRegistry[0][0]][0] = "HKCU"
                    For $i = 1 To 3
                        $aRegistry[$aRegistry[0][0]][$i] = $oRecord.StringData($i)
                    Next
                WEnd
                $oView.Close
                ReDim $aRegistry[$aRegistry[0][0] + 1][4]
            Else
                MsgBox(0, "Error", 4)
            EndIf
        Else
            MsgBox(0, "Error", 3)
        EndIf
    Else
        MsgBox(0, "Error", 2)
    EndIf
Else
    MsgBox(0, "Error", 1)
EndIf
$oView = ""
$oDatabase = ""
_ArrayDisplay($aRegistry)
Ciao. Edited by DXRW4E

apps-odrive.pngdrive_app_badge.png box-logo.png new_logo.png MEGA_Logo.png

Link to comment
Share on other sites

Or ALL

#include <Array.au3>
#include <Array.au3>

Global Const $msiOpenDatabaseModeReadOnly     = 0  ;; Opens a database read-only, no persistent changes.
Global Const $msidbComponentAttributes64bit   = 0x00000100 ;; designates a 64-bit component; 32-bit if missing.
Global Static $iMSIArchX64 = 1
Global Static $oInstaller, $oDatabase, $oView, $oRecord, $sFilePath, $aRegistry[101][4] = [[0,100]]

$sFilePath = FileOpenDialog("Select a MSI file...", @ScriptDir, "MSI (*.msi)") ;;"MSI (*.msi;*.msp)"
If Not @Error Then
    $oInstaller = ObjCreate("WindowsInstaller.Installer")
    If IsObj($oInstaller) Then
        $oDatabase = $oInstaller.OpenDatabase($sFilePath, $msiOpenDatabaseModeReadOnly)
        If IsObj($oDatabase) Then
            $oView = $oDatabase.OpenView("SELECT `Registry`.`Key`, `Registry`.`Name`, `Registry`.`Value`, `Registry`.`Root`, `Component`.`Attributes`  FROM `Registry`, `Component` WHERE `Component`.`Component`=`Registry`.`Component_` ORDER BY `Registry`.`Root`")
            If IsObj($oView) Then
                $oView.Execute()
                While 1
                    $oRecord = $oView.Fetch
                    If Not IsObj($oRecord) Then ExitLoop
                    $aRegistry[0][0] += 1
                    If $aRegistry[0][0] = $aRegistry[0][1] Then
                        $aRegistry[0][1] *= 2
                        ReDim $aRegistry[$aRegistry[0][1] + 1][4]
                    EndIf
                    Switch $oRecord.StringData(4)
                        Case 0    ;; $msidbRegistryRootClassesRoot
                            $aRegistry[$aRegistry[0][0]][0] = "HKCR"
                        Case 1  ;;,-1    ;; $msidbRegistryRootCurrentUser
                            $aRegistry[$aRegistry[0][0]][0] = "HKCU"
                        Case 2, -1    ;; $msidbRegistryRootLocalMachine
                            $aRegistry[$aRegistry[0][0]][0] = "HKLM"
                        Case 3    ;; $msidbRegistryRootUsers
                            $aRegistry[$aRegistry[0][0]][0] = "HKU"
                        Case 4    ;; $msidbRegistryRootPerformanceData - unknown - not supported ???
                            $aRegistry[$aRegistry[0][0]][0] = "HKPD"
                        Case 5    ;; $msidbRegistryRootCurrentConfig - unknown - not supported ???
                            ;$aRegistry[$aRegistry[0][0]][0] = "HKCC"
                            $aRegistry[$aRegistry[0][0]][0] = "HKLM"
                            $aRegistry[$aRegistry[0][0]][1] = "SYSTEM\CurrentControlSet\Hardware Profiles\Current\"
                        Case 6    ;; $msidbRegistryRootDynData - unknown - not supported ???
                            $aRegistry[$aRegistry[0][0]][0] = "HKDD"
                        Case 7    ;; $msidbRegistryRootCurrentUserLocalSettings - unknown - not supported ???
                            ;$aRegistry[$aRegistry[0][0]][0] = "HKLS"
                            $aRegistry[$aRegistry[0][0]][0] = "HKCU"
                            $aRegistry[$aRegistry[0][0]][1] = "Software\Classes\Local Settings\"
                        Case 80    ;; $msidbRegistryRootPerformanceText - unknown - not supported ???
                            $aRegistry[$aRegistry[0][0]][0] = "HKPT"
                        Case 96    ;; $msidbRegistryRootPerformanceNlsText - unknown - not supported ???
                            $aRegistry[$aRegistry[0][0]][0] = "HKPN"
                        Case Else
                            $aRegistry[$aRegistry[0][0]][0] = "    ;;;; Error unknown Reg-Root "
                    EndSwitch
                    For $i = 1 To 3
                        $aRegistry[$aRegistry[0][0]][$i] &= $oRecord.StringData($i)
                    Next
                    If $iMSIArchX64 And Not BitAND($oRecord.StringData(5), $msidbComponentAttributes64bit) Then
                        If $aRegistry[$aRegistry[0][0]][0] = "HKCR" Then
                            $aRegistry[$aRegistry[0][0]][1] = StringRegExpReplace($aRegistry[$aRegistry[0][0]][1], "^(?i:CLSID|DirectShow|Interface|Media Type|MediaFoundation|VRFAUTO\.AppVerifierManager|VRFAUTO\.AppVerifierManager\.1)(?=\\|$)", "Wow6432Node\\$0")
                        ElseIf $aRegistry[$aRegistry[0][0]][0] = "HKCU" Then
                            $aRegistry[$aRegistry[0][0]][1] = StringRegExpReplace(StringRegExpReplace($aRegistry[$aRegistry[0][0]][1], "^(?i)Software\K\\Microsoft\\Active Setup(?:\\|$)", "\\Wow6432Node$0"), "^(?i)SOFTWARE\\Classes\\\K(?:CLSID|DirectShow|Interface|Media Type|MediaFoundation|VRFAUTO\.AppVerifierManager|VRFAUTO\.AppVerifierManager\.1)(?=\\|$)", "Wow6432Node\\$0")
                        ElseIf $aRegistry[$aRegistry[0][0]][0] = "HKLM" Then
                            $aRegistry[$aRegistry[0][0]][1] = StringRegExpReplace(StringRegExpReplace($aRegistry[$aRegistry[0][0]][1], "^(?i)SOFTWARE\K(?!\\Classes(?:\\|$))(?=\\|$)", "\\Wow6432Node"), "^(?i)SOFTWARE\\Classes\\\K(?:CLSID|DirectShow|Interface|Media Type|MediaFoundation|VRFAUTO\.AppVerifierManager|VRFAUTO\.AppVerifierManager\.1)(?=\\|$)", "Wow6432Node\\$0")
                        EndIf
                    EndIf
                WEnd
                $oView.Close
                ReDim $aRegistry[$aRegistry[0][0] + 1][4]
            Else
                MsgBox(0, "Error", 4)
            EndIf
        Else
            MsgBox(0, "Error", 3)
        EndIf
    Else
        MsgBox(0, "Error", 2)
    EndIf
Else
    MsgBox(0, "Error", 1)
EndIf
$oView = ""
$oDatabase = ""
_ArrayDisplay($aRegistry)
Ciao. Edited by DXRW4E

apps-odrive.pngdrive_app_badge.png box-logo.png new_logo.png MEGA_Logo.png

Link to comment
Share on other sites

DXRW4E,

 

Thanks for your reply. 

The second code is related to my requirement. 

We have crossed half way of reading the HKCU keys, But am trying to export the HKCU keys which we have read and save that into a valid .reg file on my local drive

Could you please, guide me. 

Cheers,

Link to comment
Share on other sites

Write registry from Array ($aRegistry), afer export it

#RequireAdmin

RegWrite("HKCR\...XXXXX\HKEY_CURRENT_USER\Software\Test", "TestKey", "REG_SZ", "Hello this is a test")
RunWait('REG.exe Export "' & "HKCR\...XXXXX" & '" "' & @DesktopDir & "\test.reg" & '"', "", @SW_HIDE)

Local $hFile, $iEncoding = FileGetEncoding(@DesktopDir & "\test.reg"), $sData = FileRead(@DesktopDir & "\test.reg")
$hFile = FileOpen(@DesktopDir & "\test.reg", $iEncoding + 10)
If $hFile = -1 Then
    ;; error etc etc
Else
    ;$sData = StringRegExpReplace($sData, '\n\K\Q" & "[HKEY_CLASSES_ROOT\...XXXXX\" & "\E", "\[")
    $sData = StringReplace(StringReplace($sData, "[HKEY_CLASSES_ROOT\...XXXXX]", "", 1), "[HKEY_CLASSES_ROOT\...XXXXX\", "[")
    FileWrite($hFile, $sData)
    FileClose($hFile)
EndIf

however Windows Installer (MSI) is createddesigned to work in RunTimeOnLine Mod, to work in OffLine mod is much more complicated, is almost impossible (you'll never be sure) that they will all be OK 100% (because even Microsoft or InstallShield are not able to readinterpret (in OffLine mod) the CustomAction ehh)

Ciao.

Edited by DXRW4E

apps-odrive.pngdrive_app_badge.png box-logo.png new_logo.png MEGA_Logo.png

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...