Avatar billede somaliomar Praktikant
04. juni 2003 - 21:20 Der er 48 kommentarer og
3 løsninger

Slette filer og registry-keys vha. C++

Hej

Så er det blevet tid til at dele lidt points :)

Jeg har et mindre problem. Jeg vil gerne lave et program, der kan slette nogle keys i registreringsdatabasen + nogle filer på harddisken. Programmet skal kunne køre i Windows NT, 2000 og XP.

Efter 2 timers søgen har bikset flg. kode sammen, som selvfølgelig ikke virker:

#define WIN32_LEAN_AND_MEAN
#include "stdafx.h"
#include <windows.h>
#include <winreg.h>

int main(int argc, char* argv[])
{
    RegUnLoadKey(HKEY_CURRENT_CONFIG,"myKey");
    DeleteFile("C:\\test.txt");
    printf("Hello World!\n");
    return 0;
}

Hvad jeg gør forkert? Jeg skal lige sige, at jeg er lige startet med at kode i Visual C++ 6.0 i dag. Nogle af jer der kan anbefale nogle gode bøger eller evt. tutorials om VC++?
Avatar billede arne_v Ekspert
04. juni 2003 - 21:43 #1
DeleteFile burde virke !

Gør den ikke ?
Avatar billede arne_v Ekspert
04. juni 2003 - 21:46 #2
Avatar billede somaliomar Praktikant
04. juni 2003 - 21:54 #3
DeleteFile virker ikke :(

Jeg har kigget på dokumentation til RegUnLoadKey. Problemet er, at jeg ikke kan læse dokumentationen. Jeg forstår simpelthen ikke en dyt! Kan du forklare, hvad det er jeg skal gøre?
Avatar billede arne_v Ekspert
04. juni 2003 - 21:59 #4
Eksisterer filen ? Og den er ikke skrive-beskyttet eller i brug af andet program ?
Avatar billede somaliomar Praktikant
04. juni 2003 - 22:02 #5
Filen eksister og den er ikke skrivebeskyttet. Får jeg ikke nogle exceptions eller en fejl-meddelelse hvis filen ikke eksisterer?
Avatar billede arne_v Ekspert
04. juni 2003 - 22:04 #6
Nej.
Avatar billede arne_v Ekspert
04. juni 2003 - 22:05 #7
Avatar billede somaliomar Praktikant
04. juni 2003 - 22:15 #8
Fedt. Nu kan jeg slette filen sådan her:

    if (DeleteFile("C:\\test.txt")) {
        printf("File deleted!\n");
    } else {
        printf("File not deleted!\n");
    }

men jeg kan stadig ikke få denne linje til at virke:

    RegUnLoadKey(HKEY_CURRENT_CONFIG,"myKey");

Any ideas?
Avatar billede arne_v Ekspert
04. juni 2003 - 22:21 #9
Ligger mykey helt ude i roden af HKEY_CURRENT_CONFIG ?

Hvilken Windows version bruger du ?
Avatar billede somaliomar Praktikant
04. juni 2003 - 22:22 #10
Jep. Windows 20000.
Avatar billede somaliomar Praktikant
04. juni 2003 - 22:22 #11
Jeg mener Windows 2000 :)
Avatar billede arne_v Ekspert
04. juni 2003 - 22:24 #12
Det var ikke dårligt t få fat i et eksemplar af Windows 20000 !

:-)

Well - måske ikke den vil sikkert kræver 10000 TB RAM at boote.

:-)
Avatar billede arne_v Ekspert
04. juni 2003 - 22:25 #13
Hm.

Jeg havde noget gammelt kode der modificerede registry og som
virkede fint på Win95, men som på Win2000 ikke virker.

Så jeg tror der er et eller andet som jeg ikke ved.

:-(
Avatar billede somaliomar Praktikant
04. juni 2003 - 22:30 #14
Nedtur :(

Jeg har også prøvet at slette alle keys under myKey for at se om det var problemet. Men det var det ikke. Nu har jeg en kode der ser sådan ud:

#include "stdafx.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winreg.h>

int main(int argc, char* argv[])
{
    if (DeleteFile("C:\\test.txt"))
    {
        printf("File deleted!\n");
    }
    else
    {
        printf("File not deleted!\n");
    }
   
    if (RegUnLoadKey(HKEY_CURRENT_CONFIG,"myKey") == ERROR_SUCCESS)
    {
        printf("Key deleted!\n");
    }
    else
    {
        printf("Key not deleted!\n");
    }
    printf("Hello World!\n");
    retur
Avatar billede somaliomar Praktikant
04. juni 2003 - 22:32 #15
n 0;
}
Avatar billede arne_v Ekspert
04. juni 2003 - 22:34 #16
RegUnloadKey returnerer ikke en boolean men en integer og det er en
fejl kode så prøv og skriv værdien ud !
Avatar billede somaliomar Praktikant
04. juni 2003 - 22:35 #17
Hvordan skal jeg gøre det?
Avatar billede arne_v Ekspert
04. juni 2003 - 22:35 #18
Iøvrigt siger docs:

The calling process must have the SE_RESTORE_NAME and SE_BACKUP_NAME privileges on the computer in which the registry resides.
Avatar billede somaliomar Praktikant
04. juni 2003 - 22:36 #19
Og det betyder på dansk?
Avatar billede arne_v Ekspert
04. juni 2003 - 22:37 #20
At dit brugernavn skal have privs for at kunne gøre den slags.
Avatar billede somaliomar Praktikant
04. juni 2003 - 22:37 #21
Jeg er logget på som administrator.
Avatar billede arne_v Ekspert
04. juni 2003 - 22:38 #22
printf("RegUnLoadKey returns %d\n",RegUnLoadKey(HKEY_CURRENT_CONFIG,"myKey"));
Avatar billede arne_v Ekspert
04. juni 2003 - 22:38 #23
Jeg vil formode at administrator har de priviligier.
Avatar billede somaliomar Praktikant
04. juni 2003 - 22:39 #24
Den printer det her ud: RegUnLoadKey returns 1314
Avatar billede arne_v Ekspert
04. juni 2003 - 22:43 #25
Fra WINERROR.H:

//
// MessageId: ERROR_PRIVILEGE_NOT_HELD
//
// MessageText:
//
//  A required privilege is not held by the client.
//
#define ERROR_PRIVILEGE_NOT_HELD        1314L
Avatar billede arne_v Ekspert
04. juni 2003 - 22:43 #26
Mistanken om at det er et priviligie problem lyder ikke helt fjollet længere !
Avatar billede arne_v Ekspert
04. juni 2003 - 22:45 #27
Avatar billede somaliomar Praktikant
04. juni 2003 - 22:50 #28
Nu er jeg lost :( Hvordan skal jeg kalde funktionen?
Avatar billede somaliomar Praktikant
04. juni 2003 - 22:59 #29
Nu har jeg prøvet med:
    printf("RegDeleteKey returns %d\n",RegDeleteKey(HKEY_CURRENT_CONFIG,"myKey"));

Det virker, når myKey ikke indeholder andre keys under sig. Når der er ngole keys under myKey får jeg

RegDeleteKey returns 5

I WINERROR.H står der
//
// MessageId: ERROR_ACCESS_DENIED
//
// MessageText:
//
//  Access is denied.
//
#define ERROR_ACCESS_DENIED              5L
Avatar billede arne_v Ekspert
04. juni 2003 - 23:02 #30
Du kopierer den kode ind og kalder den som beskrivet i kommentaren i toppen.
Avatar billede somaliomar Praktikant
04. juni 2003 - 23:15 #31
Hehehe... Læste ikke lige kommentaren i toppen :)

int main(int argc, char* argv[])
{
ModifyPrivilege(SE_BACKUP_NAME, TRUE);
ModifyPrivilege(SE_RESTORE_NAME, TRUE);
printf("RegUnLoadKey returns %d\n",RegUnLoadKey(HKEY_CURRENT_CONFIG,"myKey"));
return 0;
}

Den udskriver:
RegUnLoadKey returns 87
Avatar billede arne_v Ekspert
04. juni 2003 - 23:29 #32
//
// MessageId: ERROR_INVALID_PARAMETER
//
// MessageText:
//
//  The parameter is incorrect.
//
#define ERROR_INVALID_PARAMETER          87L    // dderror
Avatar billede somaliomar Praktikant
04. juni 2003 - 23:30 #33
Jep, det ser ikke godt ud :(
Avatar billede arne_v Ekspert
04. juni 2003 - 23:30 #34
Som jeg læser docs:

hKey
    [in] Handle to the key to be unloaded. This parameter can be a handle returned by a call to RegConnectRegistry function or one of the following predefined handles:

    HKEY_LOCAL_MACHINE
    HKEY_USERS

så kan du kun bruge de 2 og ikke HKEY_CURRENT_CONFIG !
Avatar billede arne_v Ekspert
04. juni 2003 - 23:30 #35
og skal vi kalde noget af det for et svar
Avatar billede arne_v Ekspert
04. juni 2003 - 23:33 #36
Prøv og se om du kan slette i HKEY_LOCAL_MACHINE eller HKEY_USERS
Avatar billede somaliomar Praktikant
04. juni 2003 - 23:43 #37
Jeg har prøvet

    printf("RegUnLoadKey returns %d\n",RegUnLoadKey(HKEY_LOCAL_MACHINE,"SOFTWARE\\myApp"));
    printf("RegUnLoadKey returns %d\n",RegUnLoadKey(HKEY_USERS,".Default\\test"));

Får stadig RegUnLoadKey returns 87 på dem begge.
Avatar billede tam Nybegynder
05. juni 2003 - 00:20 #38
Ahaem....
RegUnloadKey() sletter ikke en key. Den er beregnet til, i samarbejde med RegLoadKey() at loade en key for den aktuelle user, eller et controlset.
Det er IKKE funktioner man normalt har brug for...

For at slette en key, skal den åbnes med RegOpenKeyEx() og derefter slettes med RegDeleteKey()
Avatar billede somaliomar Praktikant
05. juni 2003 - 00:22 #39
Et eksempel tak :)
Avatar billede arne_v Ekspert
05. juni 2003 - 02:24 #40
Avatar billede arne_v Ekspert
05. juni 2003 - 02:25 #41
Avatar billede arne_v Ekspert
05. juni 2003 - 02:28 #42
Du kan selv finde masser af andre eksempler.
Avatar billede somaliomar Praktikant
05. juni 2003 - 09:45 #43
Min kode ser sådan ud nu:

int main(int argc, char* argv[])
{
    HKEY hkeyMyApp;

    if( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
        "Software\\myApp",
        0,
        KEY_WRITE,
        &hkeyMyApp) == ERROR_SUCCESS )
    {
        printf("RegDeleteKey returns %d\n",RegDeleteKey(hkeyMyApp,"test"));
        printf("RegCloseKey returns %d\n",RegCloseKey(hkeyMyApp));
    }
    else
    {
        printf("Failed to open registry \n");
    }

    return 0;
}

Software\myApp\test bliver kun slettet, hvis der ikke er andre keys under test. Hvordan kan jeg gøre sådan, at den sletter "test"-nøglen uanset om der ligger andre nøgler under "test" eller ej?
Avatar billede arne_v Ekspert
05. juni 2003 - 11:19 #44
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/regunloadkey.asp

siger:

The subkey to be deleted must not have subkeys. To delete a key and all its subkeys, you need to recursively enumerate the subkeys and delete them individually. To recursively delete keys, use the SHDeleteKey function.

Windows Me/98/95:  The function also deletes all subkeys and values. To delete a key only if the key has no subkeys or values, use the SHDeleteEmptyKey function.
Avatar billede somaliomar Praktikant
05. juni 2003 - 11:29 #46
Min kode nu:

#define WIN32_LEAN_AND_MEAN
#include "stdafx.h"
#include <windows.h>
#include <winreg.h>
#include <winerror.h>
#include <shlwapi.h>


int main(int argc, char* argv[])
{
    HKEY hkeyMyApp;

    if( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
        "Software\\myApp",       
        0,
        KEY_WRITE,
        &hkeyMyApp) == ERROR_SUCCESS )
    {
        printf("SHDeleteKey returns %d\n",SHDeleteKey(hkeyMyApp,"test"));
        printf("RegCloseKey returns %d\n",RegCloseKey(hkeyMyApp));
    }
    else
    {
        printf("Failed to open registry \n");
    }

    return 0;
}


Jeg får en
myApp.obj : error LNK2001: unresolved external symbol __imp__SHDeleteKeyA@8

Når jeg Build'er programmet. Ved du hvorfor?
Avatar billede tam Nybegynder
05. juni 2003 - 11:46 #47
Du skal linke med shlwapi.lib

Kan gøres ved at skrive

#pragma comment(lib, "shlwapi.lib")

i starten af din cpp-fil...
Avatar billede somaliomar Praktikant
05. juni 2003 - 11:48 #48
Det hjælper ikke :(
Avatar billede somaliomar Praktikant
05. juni 2003 - 11:49 #49
myCode


#pragma comment(lib, "shlwapi.lib")
#define WIN32_LEAN_AND_MEAN

#include "stdafx.h"
#include <windows.h>
#include <winreg.h>
#include <winerror.h>
#include <shlwapi.h>


int main(int argc, char* argv[])
{
    /*if (DeleteFile("C:\\test.txt"))
    {
        printf("File deleted!\n");
    }
    else
    {
        printf("File not deleted!\n");
    }*/

    HKEY hkeyMyApp;

    if( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
        "Software\\myApp",       
        0,
        KEY_WRITE,
        &hkeyMyApp) == ERROR_SUCCESS )
    {
        printf("SHDeleteKey returns %d\n",SHDeleteKey(hkeyMyApp,"test"));
        printf("RegCloseKey returns %d\n",RegCloseKey(hkeyMyApp));
    }
    else
    {
        printf("Failed to open registry \n");
    }

    return 0;
}
Avatar billede somaliomar Praktikant
05. juni 2003 - 12:10 #50
Jeg har droppet projektet i VC++. Jeg er endt med at lave det i WSH. Det er ikke super-hurtigt men det virker :)



Option Explicit
Const HKEY_LOCAL_MACHINE = &H80000002
Dim strText
Dim arrKeys()
Dim intArrayCounter
Dim i
Dim objDelReg


strText = ""
intArrayCounter = 0
GetSubKeys "Software\myApp\asds"


Set objDelReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
For i = UBound(arrKeys) To 0 Step -1
    If Not IsEmpty(arrKeys(i)) Then
        objDelReg.DeleteKey HKEY_LOCAL_MACHINE, arrKeys(i)
    End If
Next


Sub GetSubKeys(strKeyPath)
    Dim arrSubKeys
    Dim objRegistry
    Dim strSubKey

    If intArrayCounter = 0 Then
        ReDim Preserve arrKeys(1)
    Else
        ReDim Preserve arrKeys(intArrayCounter)
    End If
   
    Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
    objRegistry.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys
   
    If Not IsNull(arrSubKeys) Then
        For Each strSubKey In arrSubKeys
            arrKeys(intArrayCounter) = strKeyPath & "\" & strSubKey
            intArrayCounter = intArrayCounter + 1
            GetSubKeys strKeyPath & "\" & strSubKey
        Next
    End If
   
    Set objRegistry = Nothing
End Sub
Avatar billede somaliomar Praktikant
05. juni 2003 - 12:12 #51
Jeg takker for hjælpen og håber I er tilfredse med points.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester