Page 1 sur 2

[R] Chemin complet d'un fichier texte déjà ouvert

Posté : mer. 04 avr. 2018 07:16
par A2Energie
Bonjour a tous amis Autoitiens, :D

Je suis actuellement bloqué depuis quelques jours sur un problème qui me semblait pourtant tellement simple.
J'ai un fichier texte déjà ouvert par l'utilisateur.
Mon but est de récupérer les données de ce fichier, puis d’enregistrer un autre fichier au même emplacement que le fichier précédemment ouvert.

J'ai donc besoin de connaitre le chemin (path) du fichier texte précédemment ouvert.
Mais c'est là ou les choses ce corses, étrangement ça semble très difficile.
If WinExists("[CLASS:Notepad]", "") Then
     $hTexte = WinGetHandle("[CLASS:Notepad]")
     $tTexte = WinGetTitle($hTexte )

     $lTexte = "Lien du fichier texte :  une sorte de FileGetPath($hTexte)"

; [..]

EndIf
Auriez vous une idée ?
En vous remerciant pour votre aide, :bisou:

Re: [..] Chemin complet d'un fichier texte déjà ouvert

Posté : mer. 04 avr. 2018 09:54
par walkson
Bonjour,
WinExists("[CLASS:Notepad]", "") vous renvoie à l'adresse du programme notepad.exe
Il y a https://www.autoitscript.com/forum/topi ... a-process/
mais ce n'est pas précis (renvoie tous les TXT ouverts)

Re: [..] Chemin complet d'un fichier texte déjà ouvert

Posté : mer. 04 avr. 2018 10:11
par jchd
Une autre possibilité, bien plus simple, est d'automatiser la sauvegarde du fichier ouvert par Notepad sous un autre nom. Il faut bloquer la saisie pendant le temps de l'opération.
Après ça on a tout le loisir de lire ce nouveau fichier et de procéder à tout traitement nécessaire.

Re: [..] Chemin complet d'un fichier texte déjà ouvert

Posté : mer. 04 avr. 2018 12:33
par A2Energie
Bonjour,

Merci pour vos réponses. :D

Walkson : Le problème de cette solution (si je ne me trompe pas :roll: ), c'est qu'en partant sur le PID (processus), cela renvoi le chemin du processus. DOnc pour Notepad, c'est genre "c:/programmefiles/notepad.exe", mais ce n'est pas le chemin du fichier actuellement ouvert.
Il suffirait de convertir le Handle en PID avec : WinGetProcess($hTexte). Mais après avoir essayé, en effet cela ne retourne que le chemin du .exe

jchd : Ca revient au même, il faut connaitre le chemin du fichier actuellement ouvert pour pouvoir le sauvegarder. (de manière propre).
Car c'est vraiment cradouille d'ouvrir la boite de dialogue save as et de modifier le contenu. Comme ca va être utilisé par des utilisateurs, ca me semble pas la bonne méthode. :|

Re: [..] Chemin complet d'un fichier texte déjà ouvert

Posté : mer. 04 avr. 2018 13:08
par walkson
Est ce que vous connaissez le non du fichier txt ?

Re: [..] Chemin complet d'un fichier texte déjà ouvert

Posté : mer. 04 avr. 2018 13:22
par A2Energie
Bonjour, merci pour ce retour,

Oui, je connais le nom du fichier.
Grace à son Handle :

$tTexte = WinGetTitle($hTexte )

Re: [..] Chemin complet d'un fichier texte déjà ouvert

Posté : mer. 04 avr. 2018 13:38
par walkson
Comme ceci ?
#include <WinAPIFiles.au3>
Local Const $sPath1 = 'monfichier.txt'
$path = _WinAPI_GetFullPathName($sPath1)
If WinGetHandle ( "monfichier.txt" , "" ) > 0 Then ;si handle => fichier ouvert
MsgBox(0,"",$path)
EndIf

Re: [..] Chemin complet d'un fichier texte déjà ouvert

Posté : mer. 04 avr. 2018 13:53
par A2Energie
Salut,

Merci pour ta nouvelle réponse. :D

Pour le coup : _WinAPI_GetFullPathName($sPath1)
Semble retourner le chemin du fichier Autoit (du programme autoit en cours d'execution) suivi du nom du fichier.
C'est un peut étrange.
J'vais creuser un peu plus mais je ne crois pas que ce soit la bonne fonction.

Re: [..] Chemin complet d'un fichier texte déjà ouvert

Posté : mer. 04 avr. 2018 15:29
par mikell
ça va être compliqué ton affaire :?
Notepad ouvre le fichier en lecture, affiche le contenu dans son edit, et le referme. Ensuite à l'enregistrement, Notepad ouvre le fichier en écriture, le modifie ou le crée, et le referme
Donc les méthodes habituelles pour récupérer le chemin d'un fichier "ouvert dans un processus" ne vont pas fonctionner puisque le fichier n'est pas en cours d'utilisation

Re: [..] Chemin complet d'un fichier texte déjà ouvert

Posté : mer. 04 avr. 2018 15:37
par A2Energie
Salut Mikell,

Merci pour ta réponse.
Vu comme ça, en effet ça risque d'être compliqué. Sans doute la raison pour laquelle aucune information à ce sujet.

Notepad conserve forcément le chemin du fichier car lorsque l'on souhaite l'enregistrer, il est obligé de ressortir le chemin du fichier pour pouvoir l'enregistrer au bon endroit.

Autrement, une autre solution serait peut être d'essayer avec un autre éditeur ? Genre WordPad ça fonctionnerais ? J'vais éviter Word parce que tous les utilisateurs n'ont pas Word, mais WordPad je peux demander à le mettre par défaut (si ca règle le problème).

Re: [..] Chemin complet d'un fichier texte déjà ouvert

Posté : mer. 04 avr. 2018 16:46
par mikell
Notepad conserve forcément le chemin du fichier
Bien sûr, suffit de trouver où... en mémoire ? dans une MRU List ? le registre, avec adresse variable suivant l'OS ?

Mais l'éditeur .txt par défaut des utilisateurs peut être n'importe quoi. Plutôt que de leur en imposer un, pourquoi ne pas faire ouvrir le .txt directement dans ton programme ? après tout Notepad c'est rien de plus qu'une Edit :roll:
Et là plus de problème pour l'adresse du fichier :mrgreen:

Re: [..] Chemin complet d'un fichier texte déjà ouvert

Posté : mer. 04 avr. 2018 19:17
par A2Energie
Salut Mikell,

Ben oui, mais si je pouvais leurs faire ouvrir avec le programme, ca m'aurait fait gagné une bonne semaine de travail.
Malheureusement, pas possible, le programme doit être lancé bien après l'ouverture de ce fameux (ou foutu :twisted: ) fichier. :D
Je cherche avec WordPad et je pense que ca peut le faire avec pas mal de persévérance. Ca a l'aire d'utiliser le système microsoft msdn comme office.
Si c'est le cas, je devrais trouver rapidement. Sinon... (je verrais).

Re: [..] Chemin complet d'un fichier texte déjà ouvert

Posté : mer. 04 avr. 2018 23:42
par Tlem
Après lecture des différents messages et des informations apportées :
Vous voulez "dupliquer" un fichier (a priori txt), qui peux se trouver n'importe ou et qui à été ouvert par un éditeur de texte inconnu !!!

Je ne vois qu'une solution : La boule de cristal. ^^

Plus sérieusement, il faut cadrer au moins un ou deux éléments :
1 - Est-ce que l'utilisateur est limité sur l'utilisation de l'éditeur ( voir 2 ou 3 éditeurs max). Si oui, alors il faudrait surveiller le lancement des processus "éditeur". Une fois le processus détecté, on récupère les infos (PID ou handle) et de là on recherche le document ouvert par ce processus.
2 - Autre solution, le/les fichiers qui seront édités se trouve dans un dossier spécifique. Alors on surveille les changements des fichiers du dossier.
3 - Vous créez un outils qui va demander de chercher le fichier à ouvrir, ensuite cet outil ouvre l'éditeur souhaité, puis lors de la fermeture du PID de l'éditeur, vous réalisez votre backup.
4 - Il y a surement d'autre solution qui ne me vienne pas à l'esprit en cette heure tardive. ^^

Re: [..] Chemin complet d'un fichier texte déjà ouvert

Posté : jeu. 05 avr. 2018 00:25
par orax
Quand j'ouvre un .txt en double-cliquant dessus, je peux retrouver le chemin complet du fichier. Pour l'exemple de la capture d'écran du gestionnaire de tâches, j'ai double-cliqué sur a.txt qui est enregistré sur le bureau.

Re: [..] Chemin complet d'un fichier texte déjà ouvert

Posté : jeu. 05 avr. 2018 06:47
par A2Energie
Renfort de la cavalerie :lol:
Salut a vous deux et merci pour votre intervention. :D

Tlem : Nan, l'éditeur est connu (actuellement Bloc Note) mais pour réussir à contourner mon problème actuel, je peux les forcer ou leur demander d'utiliser par exemple WordPad (car il est fourni par défaut, un peu comme bloc note). Pour ce qui est le Handle, le titre et le Pid. Ca c'est bon j'ai, le plus dure est d'ensuite s'en servir pour trouver le chemin de ce fichier.
Pour le point 2, ca peut peut être fonctionner mais avec des risques, j'explique : grâce à WinGetTitle, je peux retrouver le nom du fichier, il me reste donc à scanner les dossiers clients (car les fichiers textes viennent de là) et je vais pouvoir retrouver une correspondance. Le problème dans cette solution, c'est que s'il y a plusieurs clients avec le même nom, il peut y avoir conflit et le chemin sera donc erroné. C'est ma solution de secoure si je ne trouve pas d'autres solutions.

Orax : Ah ah, bien vu, me reste à savoir comment aller chercher cette info sans avoir à ouvrir le gestionnaire des taches (si possible).
Un peu dans le même genre, il y a ouvrir la boite de dialogue enregistrer sous et dans la barre de navigation, le lien y est. Mais je préfère ne pas utiliser cette méthode car elle est trop visible pour l'utilisateur.


Merci a vous tous pour votre interet, :bisou:

Re: [..] Chemin complet d'un fichier texte déjà ouvert

Posté : jeu. 05 avr. 2018 09:02
par A2Energie
Pfff, je n'aurais jamais pensé me prendre autant la tête sur un truc aussi bête. :roll:
J'ai trouvé une discussion qui est vraiment proche de la notre. https://autohotkey.com/board/topic/5967 ... r-wordpad/

Dans cette discussion, ils se demandent également quel est la clé de registre. Mais là c'est trop compliqué pour moi,
La solution retenue dans ce forum, est l'utilisation de Notepad ++ car avec un simple Wingettitle, le chemin peut être retourné.
Ci dessous la solution pour une utilisation de Notepad++ :
If WinExists("[CLASS:Notepad++]", "") Then
     $hTexte = WinGetHandle("[CLASS:Notepad++]") ; Handle
     $tTexte = WinGetTitle($hTexte) ; Titre
     $pTexte = WinGetProcess($hTexte) ; Pid
     $lTexte = $tTexte ; Lien
     If StringRight($lTexte, 12) = " - Notepad++" Then $lTexte = StringTrimRight($lTexte, 12)
     If StringLeft($lTexte, 1) = "*" Then $lTexte = StringTrimLeft($lTexte, 1)
EndIf
Pour essayer de résoudre le problème avec NotePad ou avec WordPad, je vais creuser du coté des registres (comprendre comment ca fonctionne et essayer de trouver la clés) ou du coté du gestionnaire des taches.

Re: [..] Chemin complet d'un fichier texte déjà ouvert

Posté : jeu. 05 avr. 2018 09:49
par A2Energie
Un peut de nouvelles : :P

Concernant la clé de registre de WordPad,
Le chemin se trouve a l'emplacement suivant :
- Ordinateur\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Search\RecentApps\{05331780-0168-4547-8496-15F9CF3A6473}\RecentItems\{4D780F3E-A988-48B7-9FF6-773D270226AF}\Path
- Ordinateur\HKEY_USERS\S-1-5-21-1998409549-2349022658-115222859-1001\Software\Microsoft\Windows\CurrentVersion\Search\RecentApps\{05331780-0168-4547-8496-15F9CF3A6473}\RecentItems\{4D780F3E-A988-48B7-9FF6-773D270226AF}\Path

Concernant la clé de regictre de Bloc Note,
Le chemin se trouve a l'emplacement suivant :
- Ordinateur\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Search\RecentApps\{1A15C3EB-650B-420C-AA3F-24B743818C53}\RecentItems\{934C49C3-E724-4A86-895A-DC8F3A2092CF}\Path
- Ordinateur\HKEY_USERS\S-1-5-21-1998409549-2349022658-115222859-1001\Software\Microsoft\Windows\CurrentVersion\Search\RecentApps\{1A15C3EB-650B-420C-AA3F-24B743818C53}\RecentItems\{934C49C3-E724-4A86-895A-DC8F3A2092CF}\Path

Voila voila, me reste à comprendre comment aller chercher cela. :mrgreen:

Re: [..] Chemin complet d'un fichier texte déjà ouvert  

Posté : jeu. 05 avr. 2018 14:55
par ZDS
Bonjour A2Energie,

La suggestion d'Orax est sans doute la meilleure, et la plus accessible dans le cas où tu n'as à récupérer le chemin en question que depuis des fenêtres où les fichiers ont été ouverts directement (et pas celles où tu es passé par "Fichier">"Ouvrir..."). Sinon, je pense que tu l'as dans l'os ^^

Si c'est bien le cas, tu peux utiliser le code suivant :
Func ProcessGetFullpath($PID)
   Local $object = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2")
   If @error Then Return SetError(1)
   Local $results = $object.ExecQuery("SELECT * FROM Win32_Process", "WQL", 0x30)
   If @error Then SetError(2)
   For $item In $results
      If $item.ProcessId = $PID Then Return $item.CommandLine
   Next
   Return SetError(3)
EndFunc
Dans mon souvenir, une bonne partie de ce code vient de Markus23 ou bien UEZ sur le forum anglophone il y a un bail... Ca te permettra de chopper le chemin d'appel du process (le chemin complet de ton éditeur) ainsi que les paramètres d'appel de ce process (dont le chemin complet du fichier texte que tu as ouvert).

A bientôt !

Re: [..] Chemin complet d'un fichier texte déjà ouvert

Posté : jeu. 05 avr. 2018 15:25
par A2Energie
Wahooo, :shock:

Ca fonctionne parfaitement,
Un grand merci a toi et à Orax pour l'idée.
:bisou: :bisou: :mrgreen: :mrgreen:

J'remet en forme pour que ca corresponde à l'exemple du début.

Merci a tous, vous êtes vraiment au top. :bisou:
If WinExists("[CLASS:Notepad]", "") Then
          $hTexte = WinGetHandle("[CLASS:Notepad]") ; Handle
          $tTexte = WinGetTitle($hTexte) ; Titre
          $pTexte = WinGetProcess($hTexte) ; Pid
          $lTexte = ProcessGetFullpath($pTexte) ; Lien
          Msgbox(0, "Le lien du fichier texte ouvert", $lTexte)
ElseIf WinExists("[CLASS:WordPadClass]", "") Then
          $hTexte = WinGetHandle("[CLASS:WordPadClass]") ; Handle
          $tTexte = WinGetTitle($hTexte) ; Titre
          $pTexte = WinGetProcess($hTexte) ; Pid
          $lTexte = ProcessGetFullpath($pTexte) ; Lien
          Msgbox(0, "Le lien du fichier texte ouvert", $lTexte)
ElseIf WinExists("[CLASS:Notepad++]", "") Then
          $hTexte = WinGetHandle("[CLASS:Notepad++]") ; Handle
          $tTexte = WinGetTitle($hTexte) ; Titre
          $pTexte = WinGetProcess($hTexte) ; Pid
          $lTexte = $tTexte ; Lien
          If StringRight($lTexte, 12) = " - Notepad++" Then $lTexte = StringTrimRight($lTexte, 12)
     If StringLeft($lTexte, 1) = "*" Then $lTexte = StringTrimLeft($lTexte, 1)
          Msgbox(0, "Le lien du fichier texte ouvert", $lTexte)
EndIf
Func ProcessGetFullpath($PID)
        Local $object = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2")
        If @error Then Return SetError(1)
        Local $results = $object.ExecQuery("SELECT * FROM Win32_Process", "WQL", 0x30)
        If @error Then SetError(2)
        For $item In $results
                If $item.ProcessId = $PID Then
                $lien = $item.CommandLine
                $lien = StringTrimLeft($lien, StringInStr($lien, '" ', 0, 1, 2)+1)
                Return $lien
            EndIf
        Next
        Return SetError(3)
EndFunc

Re: [..] Chemin complet d'un fichier texte déjà ouvert

Posté : jeu. 05 avr. 2018 16:13
par Tlem
Bonjour.
Les solutions proposées sont intéressantes, mais elle présentent comme l'ont souligné Orax et ZDS un sérieux problème : Si le fichier n'a pas été ouvert par un double clic, vous n'aurez pas la bonne information !

D'après moi, la seule et unique solution fiable consisterait à lire l'information dans la base de registre.
Comme vous, j'ai trouvé toutes les données dans [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Search\RecentApps\] mais concernant les IDs je n'ai pas la même chose que vous !

Voici ce que j'arrive à trouver pour l'ouverture d'un fichier avec NotePad :

Code : Tout sélectionner

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Search\RecentApps\{5A960CD7-7B76-46A8-8922-426564C9FC3C}]
"LastAccessedTime"=hex(b):b0,3c,84,0a,e2,cc,d3,01
"AppId"="{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\\NOTEPAD.EXE"
"LaunchCount"=dword:00000023
"AppPath"="C:\\WINDOWS\\system32\\notepad.exe"

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Search\RecentApps\{5A960CD7-7B76-46A8-8922-426564C9FC3C}\RecentItems]

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Search\RecentApps\{5A960CD7-7B76-46A8-8922-426564C9FC3C}\RecentItems\{0FE3B63B-3563-49EB-B478-8F17067B58AE}]
"Type"=dword:00000000
"Path"="D:\\Nouveau document texte.txt"
"DisplayName"="Nouveau document texte.txt"
"LastAccessedTime"=hex(b):0c,20,5b,38,db,cc,d3,01
"Points"=hex:00,00,40,40
L'idée serait de "scanner" [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Search\RecentApps] pour rechercher la clé qui contient les informations d'ID pour Notepad.
Ce qui dans mon cas correspond à [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Search\RecentApps\{5A960CD7-7B76-46A8-8922-426564C9FC3C}]
Du coup il suffit de lire les différentes entrées de : [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Search\RecentApps\{5A960CD7-7B76-46A8-8922-426564C9FC3C}\RecentItems], de récupérer chaque clé "LastAccessedTime" pour connaitre le dernier fichier ouvert et enfin dans "Path" de récupérer le nom et chemin du dernier fichier ouvert.

C'est effectivement plus complexe que ce qui a été proposé, mais hautement plus fiable. ^^