2017-10-03 4 views
-2

Je dois pouvoir obtenir une liste de tous les programmes installés sur les ordinateurs au travail et savoir si les correctifs sont à jour. Le code ci-dessous fonctionne très bien à l'exception de la section 'trouver des correctifs' où strSub = keyPath.GetSubKeyNames me donne un NullReferenceException. J'ai réussi à explorer d'autres parties du registre avec succès, mais pour une raison quelconque, la zone HKLM\Software\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products ne joue pas bien. Si quelqu'un pouvait me dire comment percer dans cette section ou me diriger vers une meilleure partie du registre, ce serait grandement apprécié, merci.vb.net clé de registre pour correctifs référence null

Imports Microsoft.Win32 
Imports System.IO 
Imports System.Threading 

Public Class frmMain 




    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 

     'create thread to run subroutine as seperate process to not effect speed of other apps 
     Dim thdGetInstalledApps As New Thread(AddressOf GetInstalledApps) 
     thdGetInstalledApps.Start() 

    End Sub 

    Private Sub GetInstalledApps() 

     'variables 
     Dim strOldCSV As String 
     Dim strComputerName As String = My.Computer.Name 
     Dim strAppName As String 
     Dim strPublisher As String 
     Dim strVersion As String 
     Dim strInstallDate As String 
     Dim strSub() As String 
     Dim strSubPatches() As String 
     Dim strProperty As String() = New String(4) {} 
     Dim isUpdate As Boolean = False 
     Dim isComponent As Boolean = False 
     Dim isUnknown As Boolean = False 
     Dim isUnique As Boolean = True 
     Dim keyPath As RegistryKey 
     Dim keySub As RegistryKey 
     Dim keySubProducts As RegistryKey 
     Dim keySubPatches As RegistryKey 
     Dim lviProperty As ListViewItem 
     Dim lvwApps As New List(Of ListViewItem) 
     Dim lvwUpdates As New List(Of ListViewItem) 
     Dim lvwComponents As New List(Of ListViewItem) 
     Dim lvwUnknowns As New List(Of ListViewItem) 

     'registry paths 
     Dim strRegistryStandard As String = "Software\Microsoft\Windows\CurrentVersion\Uninstall" 
     Dim strRegistryWow6432Node As String = "Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" 
     Dim strRegistryProducts As String = "SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products" 
     Dim strRegistryUser As String = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" 

     'combine paths for loop 
     Dim lstRegistryPaths As New List(Of String) 
     lstRegistryPaths.Add(strRegistryStandard) 
     lstRegistryPaths.Add(strRegistryWow6432Node) 
     lstRegistryPaths.Add(strRegistryUser) 

     'find apps 
     For Each Path As String In lstRegistryPaths 
      If Path <> strRegistryUser Then 
       keyPath = My.Computer.Registry.LocalMachine.OpenSubKey(Path) 
      Else 
       keyPath = My.Computer.Registry.CurrentUser.OpenSubKey(Path) 
      End If 
      strSub = keyPath.GetSubKeyNames 
      For Each Key As String In strSub 
       keySub = keyPath.OpenSubKey(Key) 
       'check if patch/update 
       If keySub.GetValue("ParentKeyName", "") <> "" And keySub.GetValue("SystemComponent", "") <> "1" Then 
        isUpdate = True 
       End If 
       'check if component of main app 
       If keySub.GetValue("SystemComponent", "") = "1" Then 
        isComponent = True 
       End If 
       'check if there's discernable metadata 
       If keySub.GetValue("DisplayName", "") = "" And keySub.GetValue("ProductName", "") = "" Then 
        isUnknown = True 
       End If 
       'get the app name "display" for uninstallers, "product" for products 
       If keySub.GetValue("DisplayName", "") <> "" Then 
        strAppName = keySub.GetValue("DisplayName", "") 
       Else 
        strAppName = keySub.GetValue("ProductName", "") 
       End If 
       'get the rest of the properties 
       strPublisher = keySub.GetValue("Publisher", "") 
       If isUpdate = True Then 
        strVersion = keySub.GetValue("ParentDisplayName", "") 
       Else 
        strVersion = keySub.GetValue("DisplayVersion", "") 
       End If 
       strInstallDate = keySub.GetValue("InstallDate", "") 
       'combine properties into listviewitem 
       strProperty(0) = strAppName 
       strProperty(1) = strPublisher 
       strProperty(2) = strVersion 
       strProperty(3) = strInstallDate 
       lviProperty = New ListViewItem(strProperty) 
       'add listviewitem to appropriate list if not a duplicate entry 
       If isUpdate = True Then 
        For Each item As ListViewItem In lvwUpdates 
         If strAppName = item.SubItems(0).Text Then 
          isUnique = False 
         End If 
        Next 
        If isUnique = True Then 
         lvwUpdates.Add(lviProperty) 
        End If 
       ElseIf isComponent = True Then 
        For Each item As ListViewItem In lvwComponents 
         If strAppName = item.SubItems(0).Text Then 
          isUnique = False 
         End If 
        Next 
        If isUnique = True Then 
         lvwComponents.Add(lviProperty) 
        End If 
       ElseIf isUnknown = True Then 
        For Each item As ListViewItem In lvwUnknowns 
         If strAppName = item.SubItems(0).Text Then 
          isUnique = False 
         End If 
        Next 
        If isUnique = True Then 
         lvwUnknowns.Add(lviProperty) 
        End If 
       Else 
        For Each item As ListViewItem In lvwApps 
         If strAppName = item.SubItems(0).Text Then 
          isUnique = False 
         End If 
        Next 
        If isUnique = True Then 
         lvwApps.Add(lviProperty) 
        End If 
       End If 
       'reset booleans 
       isUpdate = False 
       isComponent = False 
       isUnknown = False 
       isUnique = True 
      Next 
     Next 

     'find patches 
     keyPath = My.Computer.Registry.LocalMachine.OpenSubKey(strRegistryProducts) 
     strSub = keyPath.GetSubKeyNames 
     For Each Key In keyPath.GetSubKeyNames() 
      'Get Parent App Name and Publisher from InstallProperties registry folder 
      keySub = keyPath.OpenSubKey(Key) 
      keySubProducts = keySub.OpenSubKey("InstallProperties") 
      strAppName = keySubProducts.GetValue("DisplayName", "") 
      strPublisher = keySubProducts.GetValue("Publisher") 
      keySubProducts = keySub.OpenSubKey("Patches") 
      strSubPatches = keySubProducts.GetSubKeyNames 
      'add values to listviewitem 
      strProperty(0) = strAppName 
      strProperty(1) = strPublisher 
      For Each Patch As String In strSubPatches 
       'Get Patches 
       keySubPatches = keySubProducts.OpenSubKey(Patch) 
       strVersion = keySubPatches.GetValue("DisplayName", "") 
       strInstallDate = keySubPatches.GetValue("Installed", "") 
       'add values into listviewitem 
       strProperty(2) = strVersion 
       strProperty(3) = strInstallDate 
      Next 
      'add to update list 
      lviProperty = New ListViewItem(strProperty) 
      lvwUpdates.Add(lviProperty) 
     Next 

     'export each list as csv 
     '***** TO DO ***** csv's are temporary to get software management program started, eventually have exports go to SQL 

     'check if apps file already exists and delete 
     strOldCSV = "\\wstf-fs01\RE-Environmental\ADMINISTRATION\Software_Inventory\" & My.Computer.Name & "_Apps.csv" 
     If System.IO.File.Exists(strOldCSV) = True Then 
      System.IO.File.Delete(strOldCSV) 
     End If 
     'export apps list to new file 
     Using csv As New System.IO.StreamWriter("\\wstf-fs01\RE-Environmental\ADMINISTRATION\Software_Inventory\" & My.Computer.Name & "_Apps.csv", True) 
      For Each item As ListViewItem In lvwApps 
       csv.WriteLine(String.Format("""{0}"",""{1}"",""{2}"",""{3}""", _ 
              item.SubItems(0).Text, _ 
              item.SubItems(1).Text, _ 
              item.SubItems(2).Text, _ 
              item.SubItems(3).Text) _ 
          ) 
      Next 
     End Using 

     'check if components file already exists and delete 
     strOldCSV = "\\wstf-fs01\RE-Environmental\ADMINISTRATION\Software_Inventory\" & My.Computer.Name & "_Components.csv" 
     If System.IO.File.Exists(strOldCSV) = True Then 
      System.IO.File.Delete(strOldCSV) 
     End If 
     'export components list to new file 
     Using csv As New System.IO.StreamWriter("\\wstf-fs01\RE-Environmental\ADMINISTRATION\Software_Inventory\" & My.Computer.Name & "_Components.csv", True) 
      For Each item As ListViewItem In lvwComponents 
       csv.WriteLine(String.Format("""{0}"",""{1}"",""{2}"",""{3}""", _ 
              item.SubItems(0).Text, _ 
              item.SubItems(1).Text, _ 
              item.SubItems(2).Text, _ 
              item.SubItems(3).Text) _ 
          ) 
      Next 
     End Using 

     'check if updates file already exists and delete 
     strOldCSV = "\\wstf-fs01\RE-Environmental\ADMINISTRATION\Software_Inventory\" & My.Computer.Name & "_Updates.csv" 
     If System.IO.File.Exists(strOldCSV) = True Then 
      System.IO.File.Delete(strOldCSV) 
     End If 
     'export updates list to new file 
     Using csv As New System.IO.StreamWriter("\\wstf-fs01\RE-Environmental\ADMINISTRATION\Software_Inventory\" & My.Computer.Name & "_Updates.csv", True) 
      For Each item As ListViewItem In lvwUpdates 
       csv.WriteLine(String.Format("""{0}"",""{1}"",""{2}"",""{3}""", _ 
              item.SubItems(0).Text, _ 
              item.SubItems(1).Text, _ 
              item.SubItems(2).Text, _ 
              item.SubItems(3).Text) _ 
          ) 
      Next 
     End Using 

     'check if unknowns file already exists and delete 
     strOldCSV = "\\wstf-fs01\RE-Environmental\ADMINISTRATION\Software_Inventory\" & My.Computer.Name & "_Unknowns.csv" 
     If System.IO.File.Exists(strOldCSV) = True Then 
      System.IO.File.Delete(strOldCSV) 
     End If 
     'export updates list to new file 
     Using csv As New System.IO.StreamWriter("\\wstf-fs01\RE-Environmental\ADMINISTRATION\Software_Inventory\" & My.Computer.Name & "_Unknowns.csv", True) 
      For Each item As ListViewItem In lvwUnknowns 
       csv.WriteLine(String.Format("""{0}"",""{1}"",""{2}"",""{3}""", _ 
              item.SubItems(0).Text, _ 
              item.SubItems(1).Text, _ 
              item.SubItems(2).Text, _ 
              item.SubItems(3).Text) _ 
          ) 
      Next 
     End Using 

     Application.Exit() 

    End Sub 

    End Class 
+3

double possible de [Qu'est-ce qu'un NullReferenceException, et comment puis-je résoudre il?] (https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Blackwood

+0

Copie possible de [Impossible de lire la valeur de la clé de Registre - VB. NET - HKLM] (https://stackoverflow.com/questions/37802919/cannot-read-value-of-registry-key-vb-net-hklm) – Ibo

Répondre

0

Merci à ceux qui m'ont pointé dans la bonne direction avec des liens vers d'autres publications. Aucun d'entre eux ne l'a résolu directement mais a fait remuer mon cerveau et un peu plus de recherche a trouvé 2 problèmes.

1er je devais changer les clés de Registre pour registryview 64 2 je devais ajouter une instruction Si pour vous assurer que les sous-clés existaient ou se déplacent sur