02/10/14 14:46
Una cosa di cui mi capita spesso d'aver bisogno è il percorso della cartella del Desktop di Windows. Ho provato a elaborare una via per ricavarla "leggendo" il registro di sistema che vorrei proporre alla vostra attenzione.
Sul Windows 7 sul quale ho testato il metodo la soluzione funziona, ma mi chiedo se sia un metodo affidabile o se possa essere fonte di disguidi. Chi volesse darci un'occhiata tenga presente che son solito chiamare la funzione una sola volta al momento dell'avvio del programma e memorizzare il percorso del Desktop in una variabile globale per usi futuri.
Posso migliorare qualcosa? Conviene cambiare completamente approccio? Che ne dite?
P.S. xPiero: E' abbastanza spaghettico?
// le variabili globali nelle quali immazzino il percorso del Desktop DWORD gDPd = MAX_PATH; // [g]lobale [D]imensioni [P]ercorso [d]esktop BYTE gPd[MAX_PATH] = ""; // [g]lobale [P]ercorso [d]esktop // il prototipo della funzione che "legge" il registro di sistema LONG RicavaPercorsoShell( const char *nomeEl, HKEY chiave = HKEY_CURRENT_USER, int nLiv = 0 ); // una funzione per segnalare gli eventuali errori void DescriviErroreRegistro( LONG id ) { char msg[128]; FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, id, 0, msg, 127, NULL ); MessageBox( NULL, msg, "Errore", MB_OK ); } // l'implementazione delle funzione che "legge" il registro di sistema LONG RicavaPercorsoShell( const char *nomeEl, HKEY chiave, int nLiv ) { static const int kTotLiv = 6; static const char *kNomiLiv[kTotLiv] = { "Software", "Microsoft", "Windows", "CurrentVersion", "Explorer", "Shell Folders" }; static char buff[MAX_PATH]; static DWORD dimBuff; LONG esito = ERROR_SUCCESS; int i; for( i=0; esito!=ERROR_NO_MORE_ITEMS && esito!=-1; ++i ) { dimBuff = MAX_PATH; esito = RegEnumKeyEx( chiave, i, buff, &dimBuff, 0, NULL, NULL, NULL ); if( esito!=ERROR_SUCCESS && esito!=ERROR_NO_MORE_ITEMS ) goto uscita; if( lstrcmp(buff,kNomiLiv[nLiv]) == 0 ) { esito = RegOpenKeyEx( chiave, buff, 0, KEY_EXECUTE, &chiave ); if( esito != ERROR_SUCCESS ) goto uscita; if( ++nLiv < kTotLiv ) { // chiama ricorsivamente se stessa esito = RicavaPercorsoShell( nomeEl, chiave, nLiv ); } else { // ora e' aperta la chiave che contiene il percorso richiesto for( i=0, dimBuff=MAX_PATH; esito!=ERROR_NO_MORE_ITEMS && esito!=-1; ++i, dimBuff=MAX_PATH ) { esito = RegEnumValue( chiave, i, buff, &dimBuff, 0, NULL, gPd, &gDPd ); if( esito != ERROR_SUCCESS && esito != ERROR_MORE_DATA && esito != ERROR_NO_MORE_ITEMS ) { *gPd = 'Una cosa di cui mi capita spesso d'aver bisogno è il percorso della cartella del Desktop di Windows. Ho provato a elaborare una via per ricavarla "leggendo" il registro di sistema che vorrei proporre alla vostra attenzione.
// le variabili globali nelle quali immazzino il percorso del Desktop DWORD gDPd = MAX_PATH; // [g]lobale [D]imensioni [P]ercorso [d]esktop BYTE gPd[MAX_PATH] = ""; // [g]lobale [P]ercorso [d]esktop // il prototipo della funzione che "legge" il registro di sistema LONG RicavaPercorsoShell( const char *nomeEl, HKEY chiave = HKEY_CURRENT_USER, int nLiv = 0 ); // una funzione per segnalare gli eventuali errori void DescriviErroreRegistro( LONG id ) { char msg[128]; FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, id, 0, msg, 127, NULL ); MessageBox( NULL, msg, "Errore", MB_OK ); } // l'implementazione delle funzione che "legge" il registro di sistema LONG RicavaPercorsoShell( const char *nomeEl, HKEY chiave, int nLiv ) { static const int kTotLiv = 6; static const char *kNomiLiv[kTotLiv] = { "Software", "Microsoft", "Windows", "CurrentVersion", "Explorer", "Shell Folders" }; static char buff[MAX_PATH]; static DWORD dimBuff; LONG esito = ERROR_SUCCESS; int i; for( i=0; esito!=ERROR_NO_MORE_ITEMS && esito!=-1; ++i ) { dimBuff = MAX_PATH; esito = RegEnumKeyEx( chiave, i, buff, &dimBuff, 0, NULL, NULL, NULL ); if( esito!=ERROR_SUCCESS && esito!=ERROR_NO_MORE_ITEMS ) goto uscita; if( lstrcmp(buff,kNomiLiv[nLiv]) == 0 ) { esito = RegOpenKeyEx( chiave, buff, 0, KEY_EXECUTE, &chiave ); if( esito != ERROR_SUCCESS ) goto uscita; if( ++nLiv < kTotLiv ) { // chiama ricorsivamente se stessa esito = RicavaPercorsoShell( nomeEl, chiave, nLiv ); } else { // ora e' aperta la chiave che contiene il percorso richiesto for( i=0, dimBuff=MAX_PATH; esito!=ERROR_NO_MORE_ITEMS && esito!=-1; ++i, dimBuff=MAX_PATH ) { esito = RegEnumValue( chiave, i, buff, &dimBuff, 0, NULL, gPd, &gDPd ); if( esito != ERROR_SUCCESS && esito != ERROR_MORE_DATA && esito != ERROR_NO_MORE_ITEMS ) { *gPd = '{parsed_message}'; goto uscita; } if( lstrcmp(buff,nomeEl)==0 ) esito = -1; } } } } uscita: if( chiave != 0 ) { RegCloseKey( chiave ); chiave = 0; } return esito; }
Sul Windows 7 sul quale ho testato il metodo la soluzione funziona, ma mi chiedo se sia un metodo affidabile o se possa essere fonte di disguidi. Chi volesse darci un'occhiata tenga presente che son solito chiamare la funzione una sola volta al momento dell'avvio del programma e memorizzare il percorso del Desktop in una variabile globale per usi futuri.
Posso migliorare qualcosa? Conviene cambiare completamente approccio? Che ne dite?
P.S. xPiero: E' abbastanza spaghettico? '; goto uscita; } if( lstrcmp(buff,nomeEl)==0 ) esito = -1; } } } } uscita: if( chiave != 0 ) { RegCloseKey( chiave ); chiave = 0; } return esito; }
Sul Windows 7 sul quale ho testato il metodo la soluzione funziona, ma mi chiedo se sia un metodo affidabile o se possa essere fonte di disguidi. Chi volesse darci un'occhiata tenga presente che son solito chiamare la funzione una sola volta al momento dell'avvio del programma e memorizzare il percorso del Desktop in una variabile globale per usi futuri.
Posso migliorare qualcosa? Conviene cambiare completamente approccio? Che ne dite?
P.S. xPiero: E' abbastanza spaghettico?