mehrere Registry Werte(deren Daten) lesen+ausgeben
-
hi Swordfish, danke für deine hilfe.
ja, das kommt davon, wenn man spät abends noch mit sowas (für mich recht anspruchsvollem) anfängt. heute morgen hab ich erst ma selbst über den code gelacht.
ich hatte keine lust mehr auf die ganzen fehlermeldungen und habe so lange (recht kurz) mit * und & ausprobiert, bis keine mehr kamen.naja, ich finds toll, dass du mir hier eine fertige lösung vorgibst, aber ich mach das ja grad, um nicht auf copy&paste zurückgreifen zu müssen, ich würd den code auch gern verstehen.
beim größten teil komm ich auch mit, aber könntest du mir vielleicht nochmal
get_errmsg() und reinterpret_cast<>() erklären?
ich habe schon danach gegoogelt, aber nichts wirklich gut verständliches gefunden.
wär echt nett von dir.
außerdemverstehe ich das hierif( ( result = RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 0, KEY_READ, ®_key ) ) ) { cout << "RegOpenKeyEx() failed:" << endl; cout << get_errmsg( result ) << endl; wait( ); return EXIT_FAILURE; }nicht ganz (wann ist if(true), wann if(false)?), wäre nett, auch das nochmal zu erläutern. danke.
mfg, julian
-
Lass dich von diesem groben Unfug nicht verwirren. reinterpret_cast< char* > ist im Prinzip das gleiche wie (char*) also ein reiner Cast. Ich verstehe auch nicht warum Swordfish seinen Code immer unnötig kompliziert machen muss, damit Neulinge wie du ihn dann eh nicht verstehen.
Zu deiner anderen Frage: Schau doch mal hier http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/regopenkeyex.asp
Wenn alles klappt liefert RegOpenKeyEx ERROR_SUCCESS zurück. ERROR_SUCCESS ist als 0 definiert, deshalb klappt das. Ob ERROR_SUCCESS allerdings für immer garantiert ist 0 zurückzugeben, ist eine andere Frage. Wenn nicht, dann ist Swordfishs code auch in dieser Hinsicht grob fahrlässig.
MfG,
:schland: *Ranner* :schland:
-
{ Ranner | Ranner | Real_Ranner } schrieb:
Lass dich von diesem groben Unfug nicht verwirren.
Kannst du mir bitte mal erklären, was an meinem Code "grober Unfug" ist!?
{ Ranner | Ranner | Real_Ranner } schrieb:
reinterpret_cast< char* > ist im Prinzip das gleiche wie (char*) also ein reiner Cast.
Nein ist es nicht. Was soll ein "reiner Cast" sein!?
{ Ranner | Ranner | Real_Ranner } schrieb:
Ich verstehe auch nicht warum Swordfish seinen Code immer unnötig kompliziert machen muss, damit Neulinge wie du ihn dann eh nicht verstehen.
Ich schreibe meinen Code sicherlich nicht "unnötig kompiziert", sondern tu was notwendig ist.
{ Ranner | Ranner | Real_Ranner } schrieb:
Wenn nicht, dann ist Swordfishs code auch in dieser Hinsicht grob fahrlässig.
Ich trau' mich die Hand dafür in's Feuer legen, das ERROR_SUCCESS bis in alle Ewigkeit (oder, falls das früher eintritt: bis es diese Konstante nicht mehr gibt) 0 (in Worten: Null) sein und bleiben wird.
Greetz, Swordfish
-
du nutzt zum beispiel nicht std::vector. das macht den code bisschen komplizierter
-
ok, danke an swordfish für den code.
ich glaub, jetzt hab ich ihn auch verstanden, zumindest funktioniert er.anstatt reinterpret_cast<char>* kann ich auch die normale explizite typumwandlung (char)* benutzen, das hab ich ausprobiert.
wo der unterschied zu reinterpret_cast<char*> liegt, weiß ich allerdings immer noch nicht.
-
@*vector*: Ok, 1:0 für dich

ein reinterpret_cast< type >( var ) sorgt dafür, das der Speicher, auf welchen var Zeigt wie type interpretiert wird. Hätte wir zum Beispiel
#include <iostream> using namespace std; int main( ) { // einen float f = 2.345f; // dann könnten wir mit einem unsigned char *p = reinterpret_cast< unsigned char* >( &f ); // an das erste Byte von f kommen und so for( size_t i = 0; i < sizeof( float ); ++i ) { cout << "0x"; cout.width( 2 ); cout.fill( '0' ); cout << hex << p[ i ] << " "; } // alle Bytes nacheinander ausgeben.Der Unterschied zu einem C-Style Cast ist, daß man mit ihm keine consts "wegcasten" kann:
int main( ) { const char str[ ] = "Hello"; char *p = reinterpret_cast< char* >( str ); // <- *) }
wird zu einem Compilerfehler ähnlich dem Wortlaut "'reinterpret_cast' : 'const char [6]' kann nicht in 'char *' konvertiert werden" führen. Mit einem C-Style Cast ist dies möglich:int main( ) { const char str[ ] = "Hello"; char *p = ( char* ) str; cout << "Before: \"" << str << "\"" << endl; p[ 1 ] = 'a'; // wir schreiben munter in konstanten Speicher! cout << "After: \"" << str << "\"" << endl; }Ausgabe:
Before: "Hello" After: "Hallo"Mit C++ Casts wäre dazu explizit ein const_cast nötig:
#include <iostream> using namespace std; int main( ) { const char str[ ] = "Hello"; char *p = const_cast< char* >( str ); cout << "Before: \"" << str << "\"" << endl; p[ 1 ] = 'a'; cout << "After: \"" << str << "\"" << endl; }Somit kann es mit C++ Casts nicht passieren, das man sich "aus versehen" in's Bein schießt.
Greetz, Swordfish
-
ok, danke swordfish.
nachdem ich mir deinen code durchgelesen und (glaube ich) auch verstanden habe, habe ich es nochmal selbst probiert, um zu sehen, ob ich es jetzt selbst hinbekommen würde (dabei habe ich zwar für mich nicht notwendige teile deines codes weggelassen, jedoch habe ich mich, wie du sehen wirst, sehr an deinem orientiert.). anscheinend ist das nicht der fall, denn bei folgendem code kommt mal wieder nicht die richtige ausgabe.
bitte korrigieren, wenn ich irgendwas falsch sehe (siehe kommentare)!code:
#include <iostream> #include <string> #include <windows.h> using namespace std; #define cls system("cls") #define wait system ("pause>nul") void color(string pColor) { string cmdstr = "color " + pColor; system(cmdstr.c_str()); } typedef unsigned long ulong; typedef unsigned char uchar; bool RegReadValueString( string &value_data, const HKEY &hkey, const char* value) { ulong val_type; // Typ des Wertes prüfen RegQueryValueEx( hkey, // Schlüssel -ein value, // Wert -ein 0, // immer NULL -ein &val_type, // Typ des Wertes -aus 0, // Puffer für Daten des Wertes -ein 0 // Größe des Puffers -aus ); if( val_type != REG_SZ ) return false; // falls Werte-Typ != String // Daten lesen ulong result; ulong size = 1; // Größe des Daten-Puffers uchar *data = new uchar[1]; // Daten-Puffer ( Platz für 1 Zeichen => \0 ) if( result = RegQueryValueEx( hkey, value, 0, 0, data, &size ) ) { delete [] data; if( result != ERROR_MORE_DATA ) return false; // Falls Daten = "\0" try { data = new uchar[size]; // Puffer auf die richtige Größe bringen } catch( bad_alloc ) { return false; // falls Vergrößern des Puffers fehlschlägt } if( RegQueryValueEx( hkey, value, 0, 0, data, &size ) ) return false; // falls weitere Fehler auftreten } value_data = (char*) data; // Daten in C-String-Parameter schreiben delete [] data; // Daten-Array leeren return true; // bei Erfolg } // RegDataToStr int main() { HKEY hkey; string status, name, domain, password; // Schlüssel öffnen if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, // Host-Key "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", // Unerschlüssel 0, // immer NULL KEY_READ, // Zugriffsberechtigungen zum öffnen &hkey // HKEY-Handle ) ) { cls; color("c"); cout << "Fehler: HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\" << "CurrentVersion\\Winlogon konnte nicht geoeffnet werden.\n" << "beliebige Taste zum Beenden ...\n"; wait; exit(-1); } // Daten lesen // Status lesen if( !RegReadValueString( status, hkey, "AutoAdminLogon" ) ) { cls; color("c"); cout << "Fehler: AutoAdminLogon konnte nicht gelesen werden.\n"; cout << "name"; wait; exit(-1); } else { if( status == "1" ) status = "AKTIVIERT"; else status = "DEAKTIVIERT"; } // Namen lesen if( !RegReadValueString( name, hkey, "DefaultUserName" ) ) { cls; color("c"); cout << "Fehler: DefaultUserName konnte nicht gelesen werden.\n"; wait; exit(-1); } // Domain lesen if( !RegReadValueString( domain, hkey, "DefaultDomain" ) ) { cls; color("c"); cout << "Fehler: DefaultDomain konnte nicht gelesen werden.\n"; wait; exit(-1); } // Passwort lesen if( !RegReadValueString( password, hkey, "DefaultPassword" ) ) { cls; color("c"); cout << "Fehler: DefaultPassword konnte nicht gelesen werden.\n"; wait; exit(-1); } // Hauptmenü ausgeben hm: int choice; cls; cout << "\t\tautomatischer Login ist " << status << endl << "\t\tBenutzername: " << name << endl << "\t\tDomain: " << domain << endl << "\t\tPasswort: " << password << endl; return 0; }ausgabe:
Fehler: DefaultDomain konnte nicht gelesen werden.
-
Ok, hab's mir angesehen. Der Code tut genau das, was er tun soll. Haste gut gemacht *tätschel*

Julian__ schrieb:
ausgabe:
Fehler: DefaultDomain konnte nicht gelesen werden.Ich nehme mal an, das SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoAdminLogon bei dir (wie auch bei mir) schlichtweg nicht existiert. Du könntest jeden Wert auf Existenz prüfen, bevor du versuchst ihn zu lesen und wenn ein Wert nicht existiert mit dem nächsten weitermachen. Testen kannst du das zB. mit:
bool reg_value_exists( HKEY reg_key, const string value ) { char value_name[ 256 ]; unsigned long size = 256; long result = 0; if( ( result = RegEnumValue( reg_key, 0, value_name, &size, 0, 0, 0, 0 ) ) ) return false; if( value.compare( value_name ) == 0 ) return true; for( unsigned long i = 1; true; ++i ) { size = 256; if( ( result = RegEnumValue( reg_key, i, value_name, &size, 0, 0, 0, 0 ) ) ) return false; if( value.compare( value_name ) == 0 ) return true; ++i; } while( true ); return false; }Achja, noch was zu deinem Code:
// ... #define cls system("cls") // 1) #define wait system ("pause>nul") // 2) void color(string pColor) // 3) { string cmdstr = "color " + pColor; system(cmdstr.c_str()); } // ... exit(-1); // 4) // ... hm: // nicht benutzt int choice; // ebenfalls- wenn du einen Makro als einen Funktionsersatz verwendest, solltest du im á la
#define cls() system("cls") // Aufruf: cls();Klammern verpassen, damit man nicht in Versuchung kommt, ihn für einen Variablenamen zu halten.
-
schau dir mal
DOS und Win32-Konsole :: Automatisches Schließen verhindern an. -
zum Löschen des Bildschirms und farbiger Ausgabe solltest du die
Improved Console ansehen. -
bei exit( int code ) verwendet man als Parameter üblicherweise EXIT_SUCCESS bzw. EXIT_FAILURE. Ein einfaches return( 0 ) tuts in den meisten fällen genauso gut.
Hoff' ich konnt' helfen.
Greetz, Swordfish
-
ooh danke!
naja, mit deiner vermutung lagst du fast richtig.
ich überleg den ganzen verdammten tag, woran das liegen könnte und eben fällt mir auf, dass der key ja nicht "DefaultDomain", sondern "DefaultDomainName" heißt.
schön blöd...
ja, lacht ruhig, hab ich auch gemacht.

und danke für die links!
aber: ich habe den C++BuilderX (borland), der war bei einem anfängerbuch dabei und gefällt mir sehr gur, ist halt nur keine RAD, aber ich schreib ja (noch) nur konsolenprogramme. und der C++BuilderX ist nicht unter den unterstützten compilern bei Improved Console aufgeführt. sollte das trotzdem klappen?
-
Julian__ schrieb:
[...] der C++BuilderX ist nicht unter den unterstützten compilern bei Improved Console aufgeführt. sollte das trotzdem klappen?
Entweder probierst du's einfach aus oder du fragst hier:
Improved ConsoleGreetz, Swordfish
-
yo hab ich schon gemacht. funktioniert auch alles, bis auf die dropdown-menüs mit den möglichen methoden, aber das lässt sich verkraften.
ok, nochmal danke swordfish für deine hilfe hier bei meinen (meist durch eigene dummheit entstandenen) problemen.
euer forum werd ich mir merken, ist, wirklich gut hier, hab schon viel schlechteres erlebt.
mfg, julian
-
eigentlich wollt ich nur kurz den post editieren, aba dann hab ich gemerkt: das geht nicht!
yo hab ich schon gemacht. funktioniert auch alles, bis auf die dropdown-menüs mit den möglichen methoden, aber das liegt ja am compiler (an der IDE).
ok, nochmal danke swordfish für deine hilfe hier bei meinen (meist durch eigene dummheit entstandenen) problemen.
euer forum werd ich mir merken, ist, wirklich gut hier, hab schon viel schlechteres erlebt.
mfg, julian
-
-
<= und? wie steht mir das?

ich find's irgendwie stylish.