Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2301 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Problème avec la fonction MoveFile [Résolu]

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Problème avec la fonction MoveFile [Résolu]

n°883650
Alkor2001
Posté le 27-10-2004 à 08:47:14  profilanswer
 

Bonjour, je programme sous Visual C++ 6, et dans une fenêtre (MFC) j'ai toute une série de boutons permettant de modifier le nom d'un répertoire, ce qui se fait à l'aide du code ci-dessous.
 

Code :
  1. char repertoire1[1024];
  2. strcpy(repertoire1,repertoire_saga);
  3. construire_chemin(repertoire1,0);
  4. char repertoire2[1024];
  5. strcpy(repertoire2,repertoire_saga);
  6. c_saisir.type_saisie = 2;
  7. m_liste_clients.GetText(m_liste_clients.GetCurSel(),c_saisir.valeur_a_modifier);
  8. c_saisir.DoModal();
  9. strcat(repertoire2,c_saisir.m_nouvelle_valeur);
  10. strcat(repertoire2,"\\" );
  11. if(MoveFile(repertoire1,repertoire2))
  12. {
  13.  lister_clients();
  14.  m_liste_clients.SetCurSel(m_liste_clients.FindStringExact(0,c_saisir.m_nouvelle_valeur));
  15.  OnSelchangeListeClients();
  16.  GetDlgItem(IDC_LISTE_VILLES)->SetFocus();
  17. }
  18. else
  19. {
  20.  MessageBox("Le client n'a pas pu être renommé","Erreur",MB_ICONSTOP);
  21. }


 
Le problème qui se pose est que celà fonctionne très bien sous Windows98, mais que sous XP j'ai toujours le message "Le client n'a pas pu être renommé". Donc il semble que ça bloque au niveau du MoveFile, mais je n'arrive pas à trouver pourquoi (j'ai vérifié, les répertoires ne sont pas en lecture seule)...


Message édité par Alkor2001 le 29-10-2004 à 10:34:31

---------------
J'aime pas Apple...
mood
Publicité
Posté le 27-10-2004 à 08:47:14  profilanswer
 

n°883655
Lam's
Profil: bas.
Posté le 27-10-2004 à 09:01:45  profilanswer
 

Si:
1. tu nous donnais le contenu de repertoire1 et repertoire2 tel que passé à MoveFile.
2. Tu récupérais GetLastError pour nous dire ce qui coince.
3. Tu utilisais std::string ou CString pour gérer tes chaînes de caractères, parce les char toto[1024], ça fait quelques années qu'on en fait plus...
 
Ca serait plus simple à voir...


Message édité par Lam's le 27-10-2004 à 09:02:47
n°883686
Alkor2001
Posté le 27-10-2004 à 09:50:08  profilanswer
 

Lam's a écrit :

Si:
1. tu nous donnais le contenu de repertoire1 et repertoire2 tel que passé à MoveFile.
2. Tu récupérais GetLastError pour nous dire ce qui coince.
3. Tu utilisais std::string ou CString pour gérer tes chaînes de caractères, parce les char toto[1024], ça fait quelques années qu'on en fait plus...
 
Ca serait plus simple à voir...


 
Alors:
1. repertoire1: "c:\Saga\Donnees\ancient nom client", repertoire2: "c:\Saga\Donnees\nouveau nom client"
2. J'ai honte, je n'avais pas pensé au GetLastError...  :pfff:  Donc l'erreur est: "Error 32: Le processus ne peut pas accéder au fichier car ce fichier est utilisé par un autre processus". Ce qui est emmerdant c'est qu'il n'y a pas d'autre processus accédant à ce répertoire en même temps, et que le problème n'intervient pas sous 98...
3. Je suis passé au CString depuis quelque temps déjà, mais cette partie du programme est assez ancienne et je n'ai pas eu le temps de modifier les char[] pour les remplacer par des CString...


---------------
J'aime pas Apple...
n°883753
antp
Super Administrateur
Champion des excuses bidons
Posté le 27-10-2004 à 11:07:16  profilanswer
 

Alkor2001 a écrit :

Ce qui est emmerdant c'est qu'il n'y a pas d'autre processus accédant à ce répertoire en même temps, et que le problème n'intervient pas sous 98...


 
Dans Windows 2000/XP un dossier est considéré comme utilisé par une application son "dossier en cours" pointe dessus (par ex si tu as ouvert un fichier dans ce dossier, il faut que tu quittes l'application qui a ouvert le fichier, que l'application fasse un SetCurrentDirectory sur un autre dossier, ou que tu ouvres un autre fichie).
C'est assez lourd :o


Message édité par antp le 27-10-2004 à 11:07:22
n°883775
Alkor2001
Posté le 27-10-2004 à 11:31:52  profilanswer
 

antp a écrit :

Dans Windows 2000/XP un dossier est considéré comme utilisé par une application son "dossier en cours" pointe dessus (par ex si tu as ouvert un fichier dans ce dossier, il faut que tu quittes l'application qui a ouvert le fichier, que l'application fasse un SetCurrentDirectory sur un autre dossier, ou que tu ouvres un autre fichie).
C'est assez lourd :o


 
 :ouch: Ah ok!
Merci beaucoup, je j'avais pas pensé à un truc aussi lourd! Je regardais plutôt du côté de la lecture seule... Et en effet, le dossier en cours pointe directement sur le répertoire que je veux modifier, donc maintenant je sais ce qu'il me reste à faire!


---------------
J'aime pas Apple...
n°884054
Alkor2001
Posté le 27-10-2004 à 16:17:06  profilanswer
 

Bon bah, j'avais mis "Résolu" dans le titre, mais je le retire...
 
J'ai essayé plusieurs trucs à base de SetCurrentDirectory pointant sur d'autres répertoires (même un SetCurrentDirectory("c:\\" ), j'ai essayé d'ouvrir un autre fichier, mais rien n'y fait, je me retrouve toujours avec cette saloperie d'erreur32 en cas de MoveFile...


---------------
J'aime pas Apple...
n°884061
Lam's
Profil: bas.
Posté le 27-10-2004 à 16:23:18  profilanswer
 

Tu es 100% sûr que tu n'as pas de fichier ouvert dedans (via ton appli), ou l'exploreur qui pointe dessus, ou même un contrôle qui t'affiche le contenu du répertoire ?
 
D'autre part, Win98 avait une gestion plus "légère" des accès concurrents, donc le fait que ça fonctionne dessous ne veut rien dire...

n°884101
antp
Super Administrateur
Champion des excuses bidons
Posté le 27-10-2004 à 16:54:30  profilanswer
 

Alkor2001 a écrit :

Bon bah, j'avais mis "Résolu" dans le titre, mais je le retire...


 
les trucs entre crochets faut pas les mettre en début de titre, sinon le nom de la sous-catégorie ne s'ajoute plus automatiquement :o


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
n°884144
Alkor2001
Posté le 27-10-2004 à 17:19:09  profilanswer
 

antp a écrit :

les trucs entre crochets faut pas les mettre en début de titre, sinon le nom de la sous-catégorie ne s'ajoute plus automatiquement :o


 
Oups, désolé...  :sweat:  
 
Et sinon, un conseil pour corriger mon problème?  :ange:  
(j'ai mis en place un truc bourrin qui passe par du CreateDirectory et du CopyFile, mais ça ne me plait pas du tout...)


---------------
J'aime pas Apple...
n°884150
HelloWorld
Salut tout le monde!
Posté le 27-10-2004 à 17:23:00  profilanswer
 

T'es sûr que t'as pas un chti handle qui traine sur ton fichier dans ton rep ?
Ou simplement que tu as les droits ?
Lance ton exe mais sans tenter de changer le dir. Pendant qu'il tourne, avec explorer, essaye de changer le nom du dir, pour voir...


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
mood
Publicité
Posté le 27-10-2004 à 17:23:00  profilanswer
 

n°884773
Alkor2001
Posté le 28-10-2004 à 12:12:22  profilanswer
 

HelloWorld a écrit :

T'es sûr que t'as pas un chti handle qui traine sur ton fichier dans ton rep ?
Ou simplement que tu as les droits ?
Lance ton exe mais sans tenter de changer le dir. Pendant qu'il tourne, avec explorer, essaye de changer le nom du dir, pour voir...


 
Pour le handle, je ne crois pas, et j'ai tous les droits nécessaires, mon programme est exécuté soit sur des ordinateurs en local, soit sur un serveur avec les droits complets sur son répertoire.
 
Je vais expliquer de mieux expliquer mon bordel:
J'ai une CListBox que je remplis avec les noms des clients (correspondant chacun à un répertoire) avec la fonction:
 

Code :
  1. void CGestionFichiers::lister_clients()
  2. {
  3. WIN32_FIND_DATA fd;
  4. HANDLE handle;
  5. char repertoire[1024];
  6. strcpy(repertoire,repertoire_saga);
  7. SetCurrentDirectory(repertoire);
  8. effacer_clients();
  9. handle=FindFirstFile("*.*",&fd);
  10. while(handle!=INVALID_HANDLE_VALUE)
  11. {
  12.  if(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
  13.  {
  14.   if(fd.cFileName[0]!='.')
  15.   {
  16.    m_liste_clients.AddString(fd.cFileName);
  17.   }
  18.  }
  19.  if(!FindNextFile(handle,&fd))
  20.   handle=INVALID_HANDLE_VALUE;
  21. }
  22. FindClose(handle);
  23. SetDlgItemText(IDC_NB_MATS,"" );
  24. }


 
Ensuite, j'ai une fonction OnSelChangeClient() qui affiche les sous-répertoires de ce client et qui est activée dès qu'on clique sur un nom de client dans la CListBox.
 

Code :
  1. void CGestionFichiers::OnSelchangeListeClients()
  2. {
  3. char repertoire[1024];
  4. strcpy(repertoire,repertoire_saga);
  5. construire_chemin(repertoire,0);
  6. SetCurrentDirectory(repertoire);
  7. lister_villes();
  8. char tmp[128];
  9. m_liste_clients.GetText(m_liste_clients.GetCurSel(),tmp);
  10. strcpy(back_client,tmp);
  11. activer_boutons(0);
  12. }
  13. void CGestionFichiers::construire_chemin(char *chemin,int progression)
  14. {
  15. char tmp[128];
  16. m_liste_clients.GetText(m_liste_clients.GetCurSel(),tmp);
  17. strcat(chemin,tmp);
  18. strcat(chemin,"\\" );
  19. if(progression>=1)
  20. {
  21.  m_liste_villes.GetText(m_liste_villes.GetCurSel(),tmp);
  22.  strcat(chemin,tmp);
  23.  strcat(chemin,"\\" );
  24. }
  25. }


 
(lister_villes() est comme lister_clients(), sauf qu'on remplit une autre CListBox)
 
A côté de ça, j'ai un bouton permettant de modifier le nom du client sélectionné, dont le code est donné dans mon 1er post.
 
J'ai testé sous l'explorateur, je peux modifier le nom d'un client manuellement, sauf si je le sélectionne au préalable dans la CListBox...
 
J'ai essayé plein de trucs différents, du style faire un SetCurSel(-1) suivi d'un OnSelChangeListeClient() sur la liste des clients juste avant de tenter le MoveFile, ce qui devrait mettre le "focus" de Windows sur un autre répertoire client, mais non, même comme ça il continue de m'afficher que celui que je veux renommer est en cours d'utilisation...
 
Sinon, il y a d'autres fonctions permettant de renommer un répertoire? (enfin à mon avis ça ne fonctionnerait pas mieux, mais on ne sait jamais...)
 
 


---------------
J'aime pas Apple...
n°884791
antp
Super Administrateur
Champion des excuses bidons
Posté le 28-10-2004 à 13:15:02  profilanswer
 

Dans mon soft qui renomme des fichiers & dossiers (Ant Renamer) j'utilise MoveFile et je n'ai jamais eu de problème de ce genre...


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
n°884920
HelloWorld
Salut tout le monde!
Posté le 28-10-2004 à 15:06:50  profilanswer
 

As tu tester de renommer depuis l'explorer alors que ton soft tourne ?
Sinon lance filemon pour traquer les accès aux fichiers, et process explorer pour lister les handles détenus par ton appli.
http://www.sysinternals.com/ntw2k/source/filemon.shtml
http://www.sysinternals.com/ntw2k/ [...] cexp.shtml


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°885009
Alkor2001
Posté le 28-10-2004 à 16:03:00  profilanswer
 

HelloWorld a écrit :

As tu tester de renommer depuis l'explorer alors que ton soft tourne ?
Sinon lance filemon pour traquer les accès aux fichiers, et process explorer pour lister les handles détenus par ton appli.
http://www.sysinternals.com/ntw2k/source/filemon.shtml
http://www.sysinternals.com/ntw2k/ [...] cexp.shtml


 
Oui j'ai testé, et ça ne fonctionne pas si le client que je veux renommer dans l'explorer est sélectionné dans la CListBox de mon programme.
 
Je vais essayer filemon et process explorer pour voir, merci  :hello: !


---------------
J'aime pas Apple...
n°885155
HelloWorld
Salut tout le monde!
Posté le 28-10-2004 à 17:55:26  profilanswer
 

Donc c'est bien un probleme dans ton code...


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°885529
Alkor2001
Posté le 29-10-2004 à 09:07:04  profilanswer
 

HelloWorld a écrit :

Donc c'est bien un probleme dans ton code...


 
Ca je m'en doute!   :D  
 
Y a un truc bizarre que je vois apparaître avec Filemon, c'est que j'ai des FindOpen quand je clique sur un nom de client dans la liste (ça c'est normal), mais aucun FindClose! Ce n'est qu'à l'extinction du programme que j'ai une série de Kernel32:FindClose qui apparaît...
C'est bizarre, parce que les seuls accès que je fais aux répertoires se font par "SetCurrentDirectory(repertoire);" ou "handle=FindFirstFile("*.*",&fd);" toujours suivi d'un "FindClose(handle);" ...
 
C'est de là que vient mon problème, non?
 
EDIT: Bon ok, en fait c'est ma fonction de parcours du contenu d'un répertoire qui est mal foutue, il semble que ne je puisse pas faire de FindClose sur un handle qui a pour valeur INVALID_HANDLE_VALUE...  :sweat: (dit comme ça ça parait logique, mais je n'y avais pas du tout fait attention, surtout que ça paraissait fonctionner)


Message édité par Alkor2001 le 29-10-2004 à 09:21:59

---------------
J'aime pas Apple...
n°885590
Alkor2001
Posté le 29-10-2004 à 10:35:54  profilanswer
 

Bon bah c'était bien ça le problème!
En utilisant le FindFirstFile et le FindClose comme la MSDN le préconise, je n'ai plus ce problème, merci pour votre aide!  :hello:


---------------
J'aime pas Apple...

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Problème avec la fonction MoveFile [Résolu]

 

Sujets relatifs
[C] Probleme de conversion char -> intfonction exponentielle par developement limité
Question sur switch qui deconne !! RESOLU[Ada] exploiter une fonction mathematique saisie
Problème de transfert de Paradox vers MSSQL[Résolu]SocketServer : Paramétrer la request handler
Questions sur la fonction includeProbleme avec une requête
[C] [ résolu]pbm pointeur et tableau de structuresProbleme de complilation
Plus de sujets relatifs à : Problème avec la fonction MoveFile [Résolu]


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR