Per ora ho messo insieme quel che serve per identificare il PC e rimandare a un file di testo dal quale ricavare i dati per gli ulteriori lanci e aperture:
file identificazione_pc.h
#ifndef IDENTIFICAZIONE_PC_H_INCLUDED
#define IDENTIFICAZIONE_PC_H_INCLUDED
#include <windows.h>
// nome del file dal quale ricavare i dati sull'autoapertura abbinata al PC
extern const char *kStrFileAbbinamentoDati;
// nome della cartella che contiene i file dei dati per l'autoapertura
extern const char *kStrCartellaAutoaperturaFile;
// estensione usata per i file
extern const char *kStrEstFileDati;
/*==============================================================================
Questa funzione esegue queste operazioni:
1) tenta di rilevare il numero di serie del volume C:\ del PC dal quale viene
eseguito il programma
2) se il numero di serie e' stato rilevato, cerca nella cartella identificata
dalla stringa kStrCartellaAutoaperturaFile un file di testo di nome
kStrFileAbbinamentoDati che si presume contenga una o piu' righe, ciascuna
delle quali costituita da un codice numerico a otto cifre esadecimali seguito
da uno spazio e da una stringa che identifichi il nome di un ulteriore file
con estensione (non espressa nella stringa) kStrEstFileDati, dal quale il
programma potra' ricavare i riferimenti a ulteriori programmi e documenti da
aprire in automatico
un esempio del contenuto del file kStrFileAbbinamentoDati puo' essere:
D230A6CF Lezione classe 2B
315D51AA Apri questo se sei in 3F
B55AF624 Lezione classe 1C
se chiamata con kStrCartellaAutoaperturaFile uguale a "Autoapertura (file)"
da un programma lanciato sul computer con numero di serie del volume C:\
D230A6CF, la funzione restituisce in nfd questo percorso (relativo) e nome di
file:
"Autoapertura (file)\\Lezione classe 2B.txt"
se il numero di serie e' 315D51AA, sullo stesso computer restituisce in nfd:
"Autoapertura (file)\\Apri questo se sei in 3F.txt"
3) in caso non sia possibile leggere dal file kStrFileAbbinamentoDati o qualora
in quel file non sia riconoscibile un id corrispondente a quello del drive C,
la funzione tenta di usare il nome del file dell'eseguibile dal quale e'
stato lanciato il programma
4) se riesce a portare a termine uno di questi compiti, la funzione restituisce
TRUE e in nfd si trova il percorso relativo del file dei dati dal quale
rilevare i percorsi dei programmi da lanciare e dei file da aprire in
automatico
se nessuno dei compiti puo' essere portato a termine, la funzione restituisce
FALSE e la memoria puntata da nfd non viene modificata
N.B. l'irreperibilita' del file kStrFileAbbinamentoDati potrebbe essere un modo
per ottenere INTENZIONALMENTE il caricamento di un file di dati con lo stesso
nome del file dell'eseguibile .exe, al fine di aggirare il meccanismo che
vincola un certo file dei dati ad un particolare PC
PARAMETRI
nfd: nome del file dei dati (out); la funzione fa affidamento sul fatto che
lo spazio di memoria puntato possa contenere almeno _MAX_PATH char
==============================================================================*/
BOOL trova_nome_file_dati( char *nfd );
#endif // IDENTIFICAZIONE_PC_H_INCLUDED
file identificazione_pc.c
#include "identificazione_pc.h"
#include <stdio.h>
#include <ctype.h>
enum {
kCodErrNoErr,
kCodErrNullPtr,
kCodErrExtraCar,
kCodErrNoFileDatiPC,
kCodErrNoVolInfo,
kCodErrPCIgnoto,
kCodErrNoHModule,
kCodeErrNoModuleName
};
// nome del file dal quale ricavare il nome del file dei dati abbinato al PC
const char *kStrFileAbbinamentoDati = "abbin_id";
// nome della cartella che contiene i file dei dati per l'autoapertura
const char *kStrCartellaAutoaperturaFile = "Autoapertura (file)";
// estensione usata per i file nella cartella kStrFileAbbinamentoDati
const char *kStrEstFileDati = ".txt";
/*==============================================================================
// Preimpostato, in previsione di un'eventuale modifica al programma per avere
// la segnalazione "incorporataPIP_ADAPTER_INFO" dell'errore...
// Al momento e' inutile e quindi disattivata.
static const char *kStrErr[] = {
"",
"Puntatore NULL. ",
"Troppi caratteri nel percorso del file. ",
"File di abbinamento dati/PC non aperto. ",
"ID volume C:\\ non rilevato. ",
"Non riconosco questo PC. ",
"Handle del programma non rilevato. ",
"Nome del file del programma non rilevato. "
};
static int gCodErr = 0; // kCodErrNoErr
==============================================================================*/
// PROTOTIPI
static int nome_file_dati_da_nome_programma( char *nfd );
static int identifica_id_volume_c_pc( DWORD *idPc );
static int identifica_file_dei_dati( char *nfd, DWORD idPc );
/*==============================================================================
nfd: nome del file dei dati (out) la funzione fa affidamento sul fatto che
lo spazio di memoria puntato possa contenere almeno _MAX_PATH char
==============================================================================*/
BOOL trova_nome_file_dati( char *nfd ) {
int esito = kCodErrNullPtr;
if( NULL!=nfd ) {
DWORD idPc;
// per prima cosa, vediamo qual e' l'id del drive C
esito = identifica_id_volume_c_pc( &idPc );
// se abbiamo l'id, cerchiamo di leggere in kStrFileAbbinamentoDati
if( kCodErrNoErr==esito ) esito = identifica_file_dei_dati( nfd, idPc );
// se non abbiamo l'id o se non siamo riusciti a leggere i dati nel file
// kStrFileAbbinamentoDati, basiamoci sul nome del file eseguibile .exe
if( kCodErrNoErr!=esito ) esito = nome_file_dati_da_nome_programma( nfd );
}
// hai visto mai che, in futuro, uno voglia che l'errore venga segnalato...
// if( kCodErrNoErr != esito )
// MessageBox( NULL, kStrErr[gCodErr], "Errore", MB_ICONHAND );
return kCodErrNoErr == esito;
}
/*==============================================================================
Ricava il nome del file dei dati a partire dal nome del file eseguibile .exe del
programma
nfd: nome del file dei dati (out) la funzione fa affidamento sul fatto che
lo spazio di memoria puntato possa contenere almeno _MAX_PATH char
==============================================================================*/
static int nome_file_dati_da_nome_programma( char *nfd ) {
const char *nca = kStrCartellaAutoaperturaFile;
HMODULE hcm = GetModuleHandle( NULL );
char mfn[_MAX_PATH], nf[_MAX_FNAME];
DWORD lMfn, lDir, lNome, lEst;
if( NULL==hcm ) return kCodErrNoHModule;
lMfn = GetModuleFileName( hcm, mfn, _MAX_PATH );
if( 0==lMfn ) return kCodeErrNoModuleName;
_splitpath( mfn, NULL, NULL, nf, NULL );
lDir = lstrlen( nca );
lNome = lstrlen( nf );
lEst = lstrlen( kStrEstFileDati );
if( lDir+1+lNome+lEst+1 > _MAX_PATH )
return kCodErrExtraCar;
_makepath( nfd, NULL, nca, nf, kStrEstFileDati );
return kCodErrNoErr;
}
/*==============================================================================
idPc: codice identificativo del volume C nel PC (out)
==============================================================================*/
static int identifica_id_volume_c_pc( DWORD *idPc ) {
int esito = kCodErrNullPtr;
if( NULL != idPc ) {
BOOL ok = 0 != GetVolumeInformation(
"C:\\", // address of root directory of the file system
NULL, // address of name of the volume
0, // length of lpVolumeNameBuffer
idPc, // address of volume serial number
NULL, // address of system's maximum filename length
NULL, // address of file system flags
NULL, // address of name of file system
0 // length of lpFileSystemNameBuffer
);
esito = ok ? kCodErrNoErr : kCodErrNoVolInfo;
}
return esito;
}
/*==============================================================================
Tenta di leggere il file kStrFileAbbinamentoDati per trovare il nome del file
dei dati abbinato al PC il cui drive C ha l'id idPc
idPc: codice identificativo del volume C nel PC (in)
nfd: nome del file dei dati (out) la funzione fa affidamento sul fatto che
lo spazio di memoria puntato possa contenere almeno _MAX_PATH char
==============================================================================*/
static int identifica_file_dei_dati( char *nfd, DWORD idPc ) {
const char *nca = kStrCartellaAutoaperturaFile;
const char *nfa = kStrFileAbbinamentoDati;
DWORD lNca, lNfa, lEst;
char nfId[_MAX_PATH]; // nome del file con l'elenco degli identificatori
FILE *fId = NULL; // lo stream del file con l'elenco degli identificatori
int esito = kCodErrNoFileDatiPC;
// non serve controllare la validita' dei puntatori passati,
// e' gia' stato fatto in trova_nome_file_dati_abbinato_a_pc()
lNca = lstrlen( nca );
lNfa = lstrlen( nfa );
lEst = lstrlen( kStrEstFileDati );
if( lNca+1+lNfa+lEst+1 > _MAX_PATH )
return kCodErrExtraCar;
_makepath( nfId, NULL, nca, nfa, kStrEstFileDati );
fId = fopen( nfId, "r" ); // apre il file con l'elenco degli identificatori
if( NULL != fId ) { // file aperto
while( kCodErrNoErr != esito ) {
char idStr[16]; // l'identificativo del PC, come letto dal file
char nfStr[_MAX_PATH]; // la stringa abbinata all'identificativo
int i, j, c; // contatori e variabili temporanee
while( '\n'==(c=fgetc(fId)) ); // elimina le eventuali righe vuote
for( j=0, i=0; i<8&&EOF!=c; ++i, c=fgetc(fId) ) // carica l'ID
idStr[j++] = c;
if( 8==i && (' '==c||'\t'==c) ) { // 8 caratteri letti
DWORD idTmp; // prima dello spazio
char *fine;
idStr[i] = '\0'; // non e' detta che sia gia' terminata
idTmp = strtoul( idStr, &fine, 16 ); // da stringa a valore
if( fine != idStr ) { // strtoul ha trovato un valore
if( idTmp == idPc ) { // il valore corrisponde all'id del PC
while( isspace(c=fgetc(fId)) ); // salta gli spazi di troppo
fseek( fId, -1, SEEK_CUR ); // torna indietro di un caratt.
// fgets() legge la riga
if( NULL!=fgets(nfStr,_MAX_PATH-6-lNca-1,fId) ) {
size_t l = lstrlen(nfStr); // la lunghezza della riga
if( '\n'==nfStr[l-1] || feof(fId) ) {
if('\n'==nfStr[l-1] ) nfStr[--l] = '\0';
if( 0==lstrlen(nfStr) ) continue; // nessun dato
_makepath( nfd, NULL, nca, nfStr, kStrEstFileDati );
esito = kCodErrNoErr; // trovato!
}
}
}
else {
// salta quel che avanza sulla riga
for( c=fgetc(fId); '\n'!=c&&EOF!=c; c=fgetc(fId) );
if( EOF==c ) break; // siamo in fondo al file?
}
}
}
}
fclose( fId );
if( kCodErrNoErr != esito ) esito = kCodErrPCIgnoto;
}
return esito;
}
Sembra funzionare come si deve...
Quel che più conta, mi sto divertendo un sacco.