locked
Cancellazione automatica da Registro di Sistema in Windows 7 RRS feed

  • Domanda

  • Salve a tutti,

    Ho una domanda da porre alla vostra attenzione:

    Debbo cancellare una chiave di registro dal sistema Windows 7 in modo automatico,

    lanciando uno script, o, comunque tramite un eseguibile EXE creato in VB6.

    Avevo pensato di usare la tecnologia WMI, però mi sono accorto che funziona bene su Windows XP,

    ma non su Windows 7, credo per la storia UAC.Lo script che adopero è questo:

        If m_objReg Is Nothing Then
            'Creo l'istanza dell'oggetto Registro di Sistema
            Set m_objReg = GetObject("winmgmts:{impersonationLevel=impersonate, (Debug)}!\\" & m_sMyCOMPUTER & "\root\default:StdRegProv")
        End If

        m_objReg.CheckAccess nKEY, sPathChiave, KEY_DELETE, bHasAccessRight

        If bHasAccessRight Then
            Debug.Print "Hai il diritto DELETE sulla chiave!"
        Else
            Debug.Print "Non hai il diritto DELETE sulla chiave!"
        End If

        iRet = m_objReg.DeleteKey(nKEY, sPathChiave )

    NB:

    - Su XP funziona perfettamente

    - In Windows 7 riesco a cancellare la chiave solo manualmente aprendo il registro

    - La chiave non ha sottochiavi che potrebbero bloccare la cancellazione

    Avete consigli, saranno bene accetti

    grazie in anticipo

    • Modificato AngeloNew venerdì 20 luglio 2012 17:45
    • Modificato Anca Popa venerdì 31 agosto 2012 05:58 parole troncate
    venerdì 20 luglio 2012 17:44

Risposte

  • Finalmente dopo varie peripezie, sembra che qualcosa cominci a funzionare:

    Ho trovato che per utilizzare correttamente le classi di WMI per manipolare il registro,

    occorre settare delle proprietà e dei servizi della classe in oggetto, specifiche per i SO 64 bit,

    precisamente ecco qui i pezzo di codice che adopero io all'interno di una routine VB6 :

    Private Sub DelRegistry

        Dim objReg3264                  As Object
        Dim objLocator                      As Object
        Dim objServices                      As Object
        Dim objCtx                      As Object  
        
        'Costanti che definiscono le chiavi principali del Registro di Sistema
        Const HKEY_CLASSES_ROOT = &H80000000
        Const HKEY_CURRENT_USER = &H80000001
        Const HKEY_LOCAL_MACHINE = &H80000002
        Const HKEY_USERS = &H80000003
        Const HKEY_CURRENT_CONFIG = &H80000005

        'OS 64 e Appl a 64 bit
        iOS = 1: iAppl = 1

        'OS 32
        'iOS = 0: iArch = 1
        
        sPathChiave = "Software\Microsoft\Chiave"

        Set objCtx = CreateObject("WbemScripting.SWbemNamedValueSet")

        If iOS = 1 Then
            'Siamo in un SO 64 bit
            If iAppl = 0 Then
                'Applicazioni 32 bit(Andremo a manipolare il nodo HKLM\Software\Wow6432Node )
                objCtx.Add "__ProviderArchitecture", 32
                
            ElseIf iAppl = 1 Then
                'Applicazioni 64 bit
                objCtx.Add "__ProviderArchitecture", 64
                
            Else

            End If

            Set objLocator = CreateObject("Wbemscripting.SWbemLocator")
            Set objServices = objLocator.ConnectServer("", "root\default", "", "", , , , objCtx)
            Set objReg3264 = objServices.Get("StdRegProv")

        Else
            'Siamo in un SO 32 bit
            Set objReg3264 = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & "." & "\root\default:StdRegProv")

        End If

        iRet = objReg3264.DeleteKey(HKEY_LOCAL_MACHINE, sPathChiave )
        
    end sub

    Nasce solo un problema, quando la chiave presenta delle sottochiavi, in tal caso, occorre usare la funzione

    objReg3264.EnumKey HKEY_LOCAL_MACHINE, sPathChiave, arraySottochiavi

    che restituisce un array con le sottochiavi di sPathChiave,

    per cui occorre iterare il discorso della cancellazione(la precedente routine) per tutte le sottochiavi dell'array.


    Diciamo che il discorso è un pò tortuoso, ma funziona per adesso

    • Modificato AngeloNew mercoledì 25 luglio 2012 17:28
    • Contrassegnato come risposta AngeloNew mercoledì 1 agosto 2012 13:42
    mercoledì 25 luglio 2012 17:27

Tutte le risposte

  • Ciao, su Windows 7 il print di debug ti restituisce che non hai i privilegi di accesso sulla chiave oppure si blocca prima?

    Nel secondo caso ti consiglio la lettura di questo articolo:

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

    Ovviamente in questo caso anche un controllo di sicurezza sui firewall è dovuto.

    venerdì 20 luglio 2012 18:00
    Moderatore
  • Il print di debug non viene visualizzato dall'eseguibile, e l'ambiente di sviluppo non è installato sul 7,

    comunque leggerò l'articolo che mi hai suggerito, però lunedì, grazie per ora

    venerdì 20 luglio 2012 18:08
  • Potresti "postare" lo script completo e l'errore che viene visualizzato quando eseguito su w7 

    ( E perchè non cancellare la chiave direttamente da vb?  Immagino che l'applicazione VB sia a 32 bit e qui si complica ancora la cosa: vedi syswow64 )

    Mi chiedo, hai scelto wmi al posto di WshShell.RegDelete, WshShell.RegRead perchè devi cancellare delle chiavi remote? Ma se fosse così non ci sarebbero i problemi di UAC e non parleresti di apertura locale del registro... 

    Potresti usare anche reg.exe oppure powershell Remove-Item -Path 'hkcu:\key with spaces in the name'


    Gastone Canali >http://www.armadillo.it

    Se alcuni post rispondono al tuo quesito (non necessariamente i miei), ricorda di contrassegnarli come risposta e non dimenticare di contrassegnare anche i post utili . GRAZIE!

    sabato 21 luglio 2012 19:54
    Moderatore
  • Potresti usare anche reg.exe oppure powershell Remove-Item -Path 'hkcu:\key with spaces in the name'


    In effetti non è molto chiaro se questo EXE dovrà modificare la chiave su computer remoti o in locale, in quest'ultimo caso queste due soluzioni proposte da Gastone sono sicuramente più rapide ed efficaci rispetto a WMI e le puoi implementare comunque in VB6 senza problemi.
    domenica 22 luglio 2012 08:15
    Moderatore
  • La cancellazione della chiave riguarda computer in locale.

    Ho scelto WMI in quanto era un approccio che avevo già utilizzato in

    altre occasioni, ma comunque a me interessa utilizzare una soluzione funzionante,

    proverò le soluzioni consigliate da Gastone; vi farò sapere...

    lunedì 23 luglio 2012 08:10
  • Ho provato le soluzioni alternative che mi hai suggerito:

    - Testando WshShell.RegDelete, mi sono accorto che dà problemi nella cancellazione di una chiave

    che contiene un numero indefinito di sottochiavi e valori.Uso questo script in vb6:

    Private Sub Command1_Click()

        Dim WshShell        As Object

        Set WshShell = CreateObject("WScript.Shell")
       
        WshShell.RegDelete "HKLM\SOFTWARE\Microsoft\Chiave\"
        
        MsgBox ""
        
    End Sub

    - Testando Reg.exe (nella forma : REG DELETE HKLM\SOFTWARE\Microsoft\Chiave)direttamente dalla shell DOS,

    mi sono accorto che se non aprò la shell con diritti di amministratore il comando non funziona.Inoltre, io dovrei

    fare il tutto all'interno di una routine VB6, cioè, dovrei richiamare da VB6 una shell di DOS con diritti di amministratore, come fare ?

    - riguardo alla PowerShell, potrebbero insorgere altri problemi legati ai vari SO ai quali io mi riferisco,

    cioè l'EXE che sto cercando di creare, deve potere lavorare su qualsiasi SO windows (da win server 2000 a XP a 7 ecc.), e

    non è detto che ci sia la PowerShell installata.

    In ogni caso il comando che userò deve lavorare all'interno di VB6, per necessità.

    lunedì 23 luglio 2012 09:15
  • Ciao, credo sempre di più che la tua domanda andrebbe approfondita nei forum MSDN (dedicati alla programmazione) piuttosto che qui, comunque potresti inserire il manifest nell'exe per richiedere l'esecuzione come amministratore e poi utilizzare Shell http://www.developerfusion.com/article/9/shell-and-shellexecute-function/ per eseguire reg.exe con i parametri necessari.

    Ovviamente l'UAC richiederà l'esecuzione ad ogni avvio della tua applicazione, non so se la tua idea era di far eseguire l'applicazione senza l'intervento dell'utente....




    lunedì 23 luglio 2012 10:05
    Moderatore
  • Visto che parliamo di vb6, ecco come fare

    How to: Delete a Registry Key in Visual Basic
    Recursively delete any subkeys. Then use the RegDeleteKey API function to delete the key.

    http://www.vb-helper.com/howto_delete_registry_keys.html

    Working with Windows Registry using Visual Basic 6 - A complete Tutorial
    http://www.vbforums.com/showthread.php?t=563162

    (Come ha detto Fabrizio devi fare riferimento al forum VB di msdn)

    Gas


    Gastone Canali >http://www.armadillo.it

    Se alcuni post rispondono al tuo quesito (non necessariamente i miei), ricorda di contrassegnarli come risposta e non dimenticare di contrassegnare anche i post utili . GRAZIE!




    lunedì 23 luglio 2012 10:14
    Moderatore
  • Se non mi sbaglio,

    le API di sopra possono creare problemi con sistemi a 64 bit.

    lunedì 23 luglio 2012 18:15
  • Se non mi sbaglio,

    le API di sopra possono creare problemi con sistemi a 64 bit.

    Non è che le API creano dei problemi dei per se... di solito chi crea dei problemi è il programmatore :-)

    Per evitare malfunzionamenti devi sapere quali API  usare ed il loro comportamento a seconda dell'ambiente in cui operano (win2000/Xp x32/Xp x64/vista x32/vista x64/w7x32).

    RegDeleteKey 
    Deletes a subkey and its values. Note that key names are not case sensitive.

    64-bit Windows:  On WOW64, 32-bit applications view a registry tree that is separate from the registry tree that 64-bit applications view. To enable an application to delete an entry in the alternate registry view, use the RegDeleteKeyEx function.

    Purtroppo è il prezzo da pagare utilizzando un linguaggio di programmazione del 2006 a 32 bit, vb .NET ti avrebbe agevolato la vita vedi link sotto:

    http://msdn.microsoft.com/it-it/library/microsoft.win32.registry.aspx#Y2085 

    Ciao Gas


    Gastone Canali >http://www.armadillo.it

    Se alcuni post rispondono al tuo quesito (non necessariamente i miei), ricorda di contrassegnarli come risposta e non dimenticare di contrassegnare anche i post utili . GRAZIE!



    lunedì 23 luglio 2012 19:33
    Moderatore
  • Ho provato questo codice su Windows 7 64 bit, ma non funziona

    i = Shell("runas.exe /user:SERVER\administrator ""cmd.exe /c REG DELETE HKLM\SOFTWARE\Microsoft\Chiave\ /F > C:\Log.txt 2>&1 """, vbNormalFocus)

    non sto trovando altre soluzioni valide

    NB:

    Ho postato la questione anche su MSDN, senza risposta

    martedì 24 luglio 2012 16:34
  • Usa il codice VB6 nativo che trovi nei link precedentemente postati, adattandolo alle tue esigenze, non continuare a provare accrocchi su accrocchi!

    ------------

    Leggi il terzo link che trovi qui, ma solo soluzioni vb6 native come quelle precedenti.

    Ciao


    Gastone Canali >http://www.armadillo.it

    Se alcuni post rispondono al tuo quesito (non necessariamente i miei), ricorda di contrassegnarli come risposta e non dimenticare di contrassegnare anche i post utili . GRAZIE!


    martedì 24 luglio 2012 18:10
    Moderatore
  • Finalmente dopo varie peripezie, sembra che qualcosa cominci a funzionare:

    Ho trovato che per utilizzare correttamente le classi di WMI per manipolare il registro,

    occorre settare delle proprietà e dei servizi della classe in oggetto, specifiche per i SO 64 bit,

    precisamente ecco qui i pezzo di codice che adopero io all'interno di una routine VB6 :

    Private Sub DelRegistry

        Dim objReg3264                  As Object
        Dim objLocator                      As Object
        Dim objServices                      As Object
        Dim objCtx                      As Object  
        
        'Costanti che definiscono le chiavi principali del Registro di Sistema
        Const HKEY_CLASSES_ROOT = &H80000000
        Const HKEY_CURRENT_USER = &H80000001
        Const HKEY_LOCAL_MACHINE = &H80000002
        Const HKEY_USERS = &H80000003
        Const HKEY_CURRENT_CONFIG = &H80000005

        'OS 64 e Appl a 64 bit
        iOS = 1: iAppl = 1

        'OS 32
        'iOS = 0: iArch = 1
        
        sPathChiave = "Software\Microsoft\Chiave"

        Set objCtx = CreateObject("WbemScripting.SWbemNamedValueSet")

        If iOS = 1 Then
            'Siamo in un SO 64 bit
            If iAppl = 0 Then
                'Applicazioni 32 bit(Andremo a manipolare il nodo HKLM\Software\Wow6432Node )
                objCtx.Add "__ProviderArchitecture", 32
                
            ElseIf iAppl = 1 Then
                'Applicazioni 64 bit
                objCtx.Add "__ProviderArchitecture", 64
                
            Else

            End If

            Set objLocator = CreateObject("Wbemscripting.SWbemLocator")
            Set objServices = objLocator.ConnectServer("", "root\default", "", "", , , , objCtx)
            Set objReg3264 = objServices.Get("StdRegProv")

        Else
            'Siamo in un SO 32 bit
            Set objReg3264 = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & "." & "\root\default:StdRegProv")

        End If

        iRet = objReg3264.DeleteKey(HKEY_LOCAL_MACHINE, sPathChiave )
        
    end sub

    Nasce solo un problema, quando la chiave presenta delle sottochiavi, in tal caso, occorre usare la funzione

    objReg3264.EnumKey HKEY_LOCAL_MACHINE, sPathChiave, arraySottochiavi

    che restituisce un array con le sottochiavi di sPathChiave,

    per cui occorre iterare il discorso della cancellazione(la precedente routine) per tutte le sottochiavi dell'array.


    Diciamo che il discorso è un pò tortuoso, ma funziona per adesso

    • Modificato AngeloNew mercoledì 25 luglio 2012 17:28
    • Contrassegnato come risposta AngeloNew mercoledì 1 agosto 2012 13:42
    mercoledì 25 luglio 2012 17:27
  • Ciao Angelo,

    Grazie di aver condiviso la soluzione con gli altri membri della community!

    Saluti,


    Anca Popa Follow ForumTechNetIt on Twitter

    Microsoft offre questo servizio gratuitamente, per aiutare gli utenti e aumentare il database dei prodotti e delle tecnologie. Il contenuto viene fornito “così come è” e non comporta alcuna responsabilità da parte dell'azienda. 

    venerdì 31 agosto 2012 05:57