[GetWindowsDirectory] Erreur exécution ntdll.dll.

Résolu
kinkey_wizard Messages postés 30 Date d'inscription dimanche 24 octobre 2004 Statut Membre Dernière intervention 4 juillet 2005 - 27 nov. 2004 à 22:44
kinkey_wizard Messages postés 30 Date d'inscription dimanche 24 octobre 2004 Statut Membre Dernière intervention 4 juillet 2005 - 28 nov. 2004 à 11:44
Bonsoir à tous,

Alors je doute que cette fois ci je trouve tout seul la solution à mon problème, je m'explique :

Que pensez-vous de ce code ?
procedure TForm1.Button1Click(Sender: TObject);
var
  NomWallpaper : string;
  WinDir : string;
begin
  Windir := 'C:\windows';
  GetWindowsDirectory(PChar(WinDir), 255);
  NomWallpaper := WinDir + '\Web\Wallpaper\fond1.jpg';
  if not FileExists(NomWallpaper)
  then CopyFile(PChar('C:\wallp.jpg'), PChar(NomWallpaper), false);
end;

Je ne sais pas vous mais moi il me parait on ne peut plus juste, à savoir que dès que l'on clique sur le bouton "Button1" il initialise "WinDir" à "c:\windows" puis il affecte à cette variable le nom du repertoire d'installation de Win.
WinDir est ensuite utilisée pour trouver le chemin de l'endroit où copier un *.jpg si celui ci n'y est pas.

Je pense donc que le code est correct, vu qu'à la compilation tout baigne... C'est à l'execution que tout disjoncte... En fait, dès que je clique sur le bouton voilà ce qu'il me met :
"Access violation at address 77F42C69 in module 'ntdll.dll. Write of address 00404551.' Avec une jolie croix blanche sur fond de rond rouge à côté...
Juste avant cela, lorsque je le teste avec Delphi il me renvoie ceci : http://gplechuck.free.fr/erreur.jpg

Voilà donc de quoi actuellement mon application souffre (**Snif, snif...**)... Je précise que l'erreur s'arrete toujours (avec Delphi) sur la ligne se trouvant tout de suite apres celle ci :
GetWindowsDirectory(PChar(WinDir), 255);

En l'occurence dans l'exemple il s'agit de cette ligne :
NomWallpaper := WinDir + '\Web\Wallpaper\fond1.jpg';
Mais je peux mettre n'importe quoi d'autre à la place il me fera l'erreur quand même...
De plus j'ai essayé en enlevant cette partie donc :
GetWindowsDirectory(PChar(WinDir), 255);
Et là plus une seule erreur, tout tourne à merveille, donc je pense que mon problème vient de là (quelle déduction^^!!).

Enfin bref, est-ce que s'il vous plait vous pourriez m'aider à resoudre ce problème ? Ou tout du moins me dire quelle en est la cause, que je sache où chercher ?

Je vous remercie d'avance...

2 réponses

cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
27 nov. 2004 à 23:16
Ce type de code fait partie des grands classiques. D'ailleurs, si tu avais fait une recherche sur GetWindowsDirectory, tu aurais déjà la réponse.

Néanmoins, on va décortiquer le problème et tenter d'expliquer où est ton erreur.

En fait, cette fonction attend, comme premier argument, un pointeur sur un buffer de caractères (suffisamment grand de préférence). Or, dans ton code, tu écris une chaine de 10 caractères "c:\windows".
Windir := 'C:\windows'; // <- 10 caractères

Ensuite tu transtypes cette chaine en un pointeur sur chaine AZT tout en disant à cette fonction qu'elle dispose d'un espace de 255 caractères pour écrire dedans :
GetWindowsDirectory(PChar(WinDir), 255);

Et là, patatras, tu as une chance sur deux d'écrire dans une zone mémoire utilisée pour autre chose, d'où la violation d'accès décrite.

La bonne vieille recette est :
procedure TForm1.Button1Click(Sender: TObject);
var
  NomWallpaper: string;
  WinDir: array[1..MAX_PATH] of char;
begin
  GetWindowsDirectory(WinDir, SizeOf(WinDir));
//  ShowMessage(Windir);
  NomWallpaper := WinDir + '\Web\Wallpaper\fond1.jpg';
  if not FileExists(NomWallpaper) then
    CopyFile('C:\wallp.jpg', PChar(NomWallpaper), false);
end;


Cette fois, l'espace est réservé (MAX_PATH caractères) et on transmet la bonne taille à GetWindowsDirectory en utilisant la fonction SizeOf.
Je te laisse le soin de vérifier le reste du code qui suit...

Ai-je été assez clair ?
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
May Delphi be with you
3
kinkey_wizard Messages postés 30 Date d'inscription dimanche 24 octobre 2004 Statut Membre Dernière intervention 4 juillet 2005
28 nov. 2004 à 11:44
Yeah!! Merci bien Delphiprog... Cela fonctionne à merveille.

procedure TForm1.Button1Click(Sender: TObject);
var
NomWallpaper: string;
WinDir: array[1..MAX_PATH] of char;
begin
GetWindowsDirectory(@WinDir, SizeOf(WinDir));
// ShowMessage(Windir);
NomWallpaper := WinDir + '\Web\Wallpaper\fond1.jpg';
if not FileExists(NomWallpaper) then
CopyFile('C:\wallp.jpg', PChar(NomWallpaper), false);
end;

(Pour ceux qui auraient eu des problèmes il faut rajouter le @. ;) )

Sinon je suis vraiment navré... Je vous assure que je cherche... Pas ce qu'il faut d'accord... Mais je cherche...
J'essayerai de mieux le faire la prochaine fois...
0
Rejoignez-nous