Page 1 sur 2

Extraction du chemin du programme d'un fichier lien (lnk)

Publié : ven. 27/nov./2015 17:34
par Marc56
Hello,

Pour mon programme, j'avais besoin d'extraire le chemin complet d'un programme depuis un lien (fichier .lnk)
Après une journée de recherche, je ne suis tombé que sur des exemples vieux de 10 ans (et qui ne fonctionnent plus), ou avec des messages d'erreur auquel je ne comprend rien :? (j'aime pas les pointeurs, et autre trucs corrosifs)

Donc, j'ai exploré "à l'ancienne" (= avec un éditeur hexa) des fichiers lien, puis une fois repéré que le chemin apparait d'une claire (tous les caractères sont contigus), j'ai sorti ma tronçonneuse automatique préférée: les expressions régulières.

Il suffit simplement de chercher ce qui commence par A à Z suivi de : puis \ puis tous les caractères autorisés

Petit exemple qui extrait tous les chemins complet des liens sur le bureau Windows

Code : Tout sélectionner

; Extraction du chemin programme d'un fichier .lnk
; (C)Marc56 - md.acme.software@gmail.com - 2015-11-27

RegEx.s = "^[A-Z]\:\\[\w\d\:\\\s\.()\-]+"
Source_Dir.s = GetHomeDirectory() + "Desktop\"

If Not CreateRegularExpression(1, RegEx)
    Debug "Expression régulière inutilisable. Bye."
EndIf

If ExamineDirectory(0, Source_Dir, "*.lnk")
    While NextDirectoryEntry(0)
        If DirectoryEntryType(0) =#PB_DirectoryEntry_File
            File_Name.s = DirectoryEntryName(0)
            If ReadFile(2, Source_Dir + File_Name)
                While Eof(2) = 0
                    Txt.s = ReadString(2)
                    If MatchRegularExpression(1, Txt)
                        Debug RSet(File_Name, 50, ".") + " > [" + Txt + "]"
                    EndIf
                Wend   
                CloseFile(2)    
            EndIf
        EndIf
    Wend
    FinishDirectory(0)
EndIf

Chez moi ça marche (mais je n'ai peut être pas tous les types de noms de fichier sur mon bureau)

Je vais intégrer ça dans la prochaine version de mon Desk pour pouvoir faire un DnD des liens.

:wink:

Re: Extraction du chemin du programme d'un fichier lien (lnk

Publié : ven. 27/nov./2015 19:25
par Ar-S
Feinteux :)

Attention cependant, pour ne pas louper de raccourcis qui peuvent faire parti du dossier "public" du bureau utilisateur, il convient d'ajouter ce dossier à tes recherches.
J'ai modifié un peut ton code pour remplacer la lecture d'un fichier par une liste

Code : Tout sélectionner

; Extraction du chemin programme d'un fichier .lnk
; (C)Marc56 - md.acme.software@gmail.com - 2015-11-27

Global NewList ShortCuts.s()

RegEx.s = "^[A-Z]\:\\[\w\d\:\\\s\.()\-]+"
Source_Dir.s = GetHomeDirectory() + "Desktop\"

Partition.s = Left(Source_Dir,1)
Source_Dir_Public.s = Partition.s + ":\Users\Public\Desktop\"

Procedure ExamineShortcut(Dir.s)
  If ExamineDirectory(0, Dir, "*.lnk")
    While NextDirectoryEntry(0)
      If DirectoryEntryType(0) =#PB_DirectoryEntry_File
        File_Name.s = DirectoryEntryName(0)
        AddElement (Shortcuts())
        Shortcuts() = Dir + File_Name
        If MatchRegularExpression(1, Shortcuts())
          Debug RSet(File_Name, 50, ".") + " > [" + Shortcuts() + "]"
        EndIf
        
      EndIf
    Wend  
    FinishDirectory(0)
  EndIf
EndProcedure

Debug Source_Dir

If Not CreateRegularExpression(1, RegEx)
  Debug "Expression régulière inutilisable. Bye."
EndIf

ExamineShortcut(Source_Dir)
ExamineShortcut(Source_Dir_Public)


   

Re: Extraction du chemin du programme d'un fichier lien (lnk

Publié : sam. 28/nov./2015 11:04
par Mesa
J'ai adapté le code à XP qui n'a pas les même dossiers.

Code : Tout sélectionner

; Extraction du chemin programme d'un fichier .lnk
; (C)Marc56 - md.acme.software@gmail.com - 2015-11-27

Global NewList ShortCuts.s()

RegEx.s = "^[A-Z]\:\\[\w\d\:\\\s\.()\-]+"


CompilerSelect #PB_Compiler_OS
    
  CompilerCase #PB_OS_Windows 
    If OSVersion() < #PB_OS_Windows_XP
      MessageRequester("Info", "version de Windows trop ancienne") 
      End
    EndIf
    
    Select OSVersion()
      Case #PB_OS_Windows_XP
        Source_Dir.s = GetHomeDirectory() + "Bureau\" 
        
        ; Ne pas oublier le dossier "All Users"
        pos=1
        c.s=""
        Repeat
          pos=pos+1
          c=Mid(ReverseString(GetHomeDirectory()),pos,1)   
        Until c="\"

        Source_Dir_Public.s=Left(GetHomeDirectory(),Len(GetHomeDirectory())-pos)+"\All Users\Bureau\"
        
      Default ; Autres Windows ultérieurs à XP
        Source_Dir.s = GetHomeDirectory() + "Desktop\" 
        Partition.s = Left(Source_Dir,1)
        Source_Dir_Public.s = Partition.s + ":\Users\Public\Desktop\";
    EndSelect
    
    ;   [CompilerElse]
    ;     ...
    ;   [CompilerDefault]
    ;     ...
CompilerEndSelect


Procedure ExamineShortcut(Dir.s)
  If ExamineDirectory(0, Dir, "*.lnk")
    While NextDirectoryEntry(0)
      If DirectoryEntryType(0) =#PB_DirectoryEntry_File
        File_Name.s = DirectoryEntryName(0)
        AddElement (Shortcuts())
        Shortcuts() = Dir + File_Name
        If MatchRegularExpression(1, Shortcuts())
          Debug RSet(File_Name, 50, ".") + " > [" + Shortcuts() + "]"
        EndIf
        
      EndIf
    Wend  
    FinishDirectory(0)
  EndIf
EndProcedure



If Not CreateRegularExpression(1, RegEx)
  Debug "Expression régulière inutilisable. Bye."
  End
EndIf

;Debug Source_Dir
ExamineShortcut(Source_Dir)

;Debug Source_Dir_Public
ExamineShortcut(Source_Dir_Public)

M.

Re: Extraction du chemin du programme d'un fichier lien (lnk

Publié : sam. 28/nov./2015 11:55
par Ar-S
Bien vu Mesa, j'avoue de plus en plus oublier ce bon vieux XP lorsque je code.

Re: Extraction du chemin du programme d'un fichier lien (lnk

Publié : sam. 28/nov./2015 15:39
par Marc56
Merci pour la continuation de l'exemple :D

En fait je n'ai pas besoin de ratisser tous les liens à dispo de l'utilisateur, je vais juste faire en sorte que quand on traine un lien, je puisse extraire l'exe vers lequel il pointe (car cela permet d'extraire l’icône avec l'API, car cette dernière ne sort pas l'icone d'un .lnk)

Dans mon exemple, j'avais oublié la possibilité de liens UNC (\\serveur\partage\chemin)
Voila donc un exemple rectifié (mais qui ne fonctionne pas complètement: il ne sorte que \\serveur\chemin mais je vais trouver)
(J'ai aussi mis le résultat en fenêtre Windows plutôt qu'en debug pour la lisibilité)

Code : Tout sélectionner

; Extraction du chemin programme d'un fichier .lnk
; (C)Marc56 - md.acme.software@gmail.com - 2015-11-22
; Version avec extraction ressources réseaux (mappées en UNC)

; RegEx.s = "^[A-Z]\:\\[\w\d\:\\\s\.()\-]+"         ; Standard
RegEx.s = "^([A-Z]\:\\|\\\\)[\w\d\:\\\s\.()\-]+"    ; avec UNC

Source_Dir.s = GetHomeDirectory() + "Desktop\"

If Not CreateRegularExpression(1, RegEx)
    Debug "Expression régulière inutilisable. Bye."
Else
    If OpenWindow(0, x, y, 800, 600, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) 
        ListIconGadget(1, 10, 10, 780, 580, "Fichier Lien", 280,  #PB_ListIcon_GridLines)
        AddGadgetColumn(1, 1, "Cible", 470)
        
        If ExamineDirectory(0, Source_Dir, "*.lnk")
            While NextDirectoryEntry(0)
                If DirectoryEntryType(0) =#PB_DirectoryEntry_File
                    File_Name.s = DirectoryEntryName(0)
                    If ReadFile(2, Source_Dir + File_Name)
                        While Eof(2) = 0
                            Txt.s = ReadString(2)
                            If MatchRegularExpression(1, Txt)
                                ; Debug RSet(File_Name, 50, ".") + " > [" + Txt + "]"
                                AddGadgetItem(1, -1, File_Name + Chr(10) + txt)
                            EndIf
                        Wend   
                        CloseFile(2)   
                    EndIf
                EndIf
            Wend
            FinishDirectory(0)
        EndIf
        
        Repeat : Until WaitWindowEvent(50) = #PB_Event_CloseWindow      
    EndIf
EndIf

Re: Extraction du chemin du programme d'un fichier lien (lnk

Publié : sam. 28/nov./2015 16:39
par Ar-S
Dans ma petite tête j'avais envisagé la possibilité d'ajouter une option à ton launcher,
"Transférer les raccourcis du bureau vers le launcher ?"
Vu qu'on met en général que les raccourcis dont on se sert le plus sur le bureau, ça ferait une nouveauté qu'on ne trouve pas ailleurs. (D’où le scan des 2 dossiers public et user). :wink:
Une fois listé, il te suffit de virer les .lnk
Rien ne t'empêche aussi de sauver la liste des lnk quelque part (dans ton pref ?) pour inverser le processus à la demande.

Re: Extraction du chemin du programme d'un fichier lien (lnk

Publié : sam. 28/nov./2015 16:57
par Marc56
Ar-S a écrit :Dans ma petite tête j'avais envisagé la possibilité d'ajouter une option à ton launcher,
"Transférer les raccourcis du bureau vers le launcher ?"
Vu qu'on met en général que les raccourcis dont on se sert le plus sur le bureau, ça ferait une nouveauté qu'on ne trouve pas ailleurs. (D’où le scan des 2 dossiers public et user). :wink:
Une fois listé, il te suffit de virer les .lnk
Rien ne t'empêche aussi de sauver la liste des lnk quelque part (dans ton pref ?) pour inverser le processus à la demande.
Idée intéressante 8)
Cela dit, la plupart des gens que je connais (moi compris) ont parfois plus d'une centaine d’icônes sur le bureau (dont une grande parties sont des "icônes/voitures ventouses abandonnées".)
Donc pour bien faire, il faudrait ramasser tout dans une liste avec des cases à cocher: beaucoup de boulot pour une fonction qui ne servirait qu'une seule fois, mais je retiens l'idée, je vais voir. Ça peut effectivement être un plus.
Merci :wink:

Re: Extraction du chemin du programme d'un fichier lien (lnk

Publié : sam. 28/nov./2015 19:43
par Micoute
Bonsoir,

Je ne comprend pas cette manie d'avoir des icônes qui trainent sur le bureau et qui défigurent le papier peint, mais je ne critique pas ceux qui le font, c'est une question de goût et de couleur et ça ne se discute pas.

Re: Extraction du chemin du programme d'un fichier lien (lnk

Publié : lun. 30/nov./2015 11:32
par Kwai chang caine
Sauf que moi ça m'est utile les icones sur le papier peint...car en général pour me sentir moins seul, tout mes fonds d'ecran sont des images de jolies filles un jour de grande chaleur... :mrgreen:
Donc un icone bien placé, évite parfois pas mal de mauvais regards, quoi que quand il faut lancer un programme, faut mettre le pointeur "dans le cambouis" :lol:

Ceci dit, merci à Marc56 et aux autres pour ces codes tres interessants 8)

Re: Extraction du chemin du programme d'un fichier lien (lnk

Publié : lun. 30/nov./2015 14:15
par Anonyme2
Micoute a écrit :Bonsoir,

Je ne comprend pas cette manie d'avoir des icônes qui trainent sur le bureau et qui défigurent le papier peint, mais je ne critique pas ceux qui le font, c'est une question de goût et de couleur et ça ne se discute pas.

J'ai 117 icônes sur le bureau et j'aime :wink:
et 18 sur la barre de tache :mrgreen:
Rien à foutre du papier peint, je ne passe pas mon temps à regarder la même image :mrgreen:

C'est comme ça que je travaille, bien ou pas bien peu importe...

Re: Extraction du chemin du programme d'un fichier lien (lnk

Publié : lun. 30/nov./2015 14:32
par falsam
Moi c'est plus simple, mon papier peint est un fond tramé noir sur lequel je n'ai rien.

Fond : http://falsam.com/Download/images/WallPaperHD---073.jpg

Ma barre de taches avec quelques applications les plus utilisés et depuis peu un launcher éphémère si besoin.

Je suis dans la sobriété ^^

Re: Extraction du chemin du programme d'un fichier lien (lnk

Publié : lun. 30/nov./2015 19:25
par Kwai chang caine
Denis a écrit :Rien à foutre du papier peint, je ne passe pas mon temps à regarder la même image
Falsam a écrit :Moi c'est plus simple, mon papier peint est un fond tramé noir sur lequel je n'ai rien.
Mooouaih ...bah moi je préfere regarder l'arriere train (Même si il sifflera pas 3 fois) d'une fille, que le fond de son jean noir usé, et tant pis si c'est toujours le même :mrgreen:
C'est comme les aquariums...ça a beau être toujours le mêmes "poissons"...les fruits de mer ça repose :D

Re: Extraction du chemin du programme d'un fichier lien (lnk

Publié : mar. 01/déc./2015 8:22
par Marc56
Micoute a écrit :Je ne comprend pas cette manie d'avoir des icônes qui trainent sur le bureau et qui défigurent le papier peint, ...
Le principal intérêt d'avoir des icônes sur le bureau est d'utiliser le drag'n'drop: J'ai en permanence des raccourcis vers un visualiseur d'image (irfanview), plusieurs éditeurs ascii (notepad++, metapad, Edipadpro: tous n'ont pas les mêmes fonctions), un lecteur PDF, un tableur (ouvrir les .csv) et surtout des raccourcis vers des dossiers temporaires.
L'association par défaut d'un programme n'est pas toujours celle que je souhaite et je n'aime pas utiliser le bouton droit de la souris pour aller dans plusieurs sous menu et faire "ouvrir avec"

Mais j'ai prévu de faire en sorte que mon lanceur puisse recevoir les documents sur des programmes (si on fait un d&d sur une case ayant déjà un programme, alors le programme est lancé avec le document reçu). Comme ça je pourrais supprimer la plupart de mes icônes du bureau. J'envisage même de faire certaines zones plus grandes pour les programmes les plus utilisés avec cette option.

:wink:

Re: Extraction du chemin du programme d'un fichier lien (lnk

Publié : mar. 01/déc./2015 9:09
par Droopy
ce petit code (pas de moi) permet de récupérer la cible d'un raccourcis

Code : Tout sélectionner

Procedure.s ShortcutTarget(ShortcutFile.s) 
  
  Result$ = ""
  CoInitialize_(0)
  If CoCreateInstance_(?CLSID_ShellLink, 0, 1,?IID_IShellLink, @ShellLink.IShellLinkA) = #S_OK
    If ShellLink\QueryInterface(?IID_IPersistFile, @LinkFile.IPersistFile) = #S_OK
      If LinkFile\Load(ShortcutFile, 0) = #S_OK
        If ShellLink\Resolve(0, 1) = #S_OK
          Result$ = Space(#MAX_PATH+1)
          ShellLink\GetPath(Result$, #MAX_PATH, 0, 0)
        EndIf
      EndIf
    EndIf
    LinkFile\Release()
  EndIf
  ShellLink\Release()
  CoUninitialize_()
  ProcedureReturn Result$
  
EndProcedure

Re: Extraction du chemin du programme d'un fichier lien (lnk

Publié : mar. 01/déc./2015 10:38
par Mesa
@Ars: :D

Un petit oubli dans le code de droopy

Code : Tout sélectionner

Procedure.s ShortcutTarget(ShortcutFile.s) 
	
	Result$ = ""
	CoInitialize_(0)
	If CoCreateInstance_(?CLSID_ShellLink, 0, 1,?IID_IShellLink, @ShellLink.IShellLinkA) = #S_OK
		If ShellLink\QueryInterface(?IID_IPersistFile, @LinkFile.IPersistFile) = #S_OK
			If LinkFile\Load(ShortcutFile, 0) = #S_OK
				If ShellLink\Resolve(0, 1) = #S_OK
					Result$ = Space(#MAX_PATH+1)
					ShellLink\GetPath(Result$, #MAX_PATH, 0, 0)
				EndIf
			EndIf
		EndIf
		LinkFile\Release()
	EndIf
	ShellLink\Release()
	CoUninitialize_()
	ProcedureReturn Result$
	
	DataSection
		CLSID_ShellLink:
			; 00021401-0000-0000-C000-000000000046
			Data.l $00021401
			Data.w $0000,$0000      
			Data.b $C0,$00,$00,$00,$00,$00,$00,$46
			
		IID_IShellLink:
			; DEFINE_SHLGUID(IID_IShellLinkA,         0x000214EEL, 0, 0);
			; C000-000000000046
			Data.l $000214EE
			Data.w $0000,$0000
			Data.b $C0,$00,$00,$00,$00,$00,$00,$46
			
		IID_IPersistFile:
			; 0000010b-0000-0000-C000-000000000046
			Data.l $0000010b
			Data.w $0000,$0000
			Data.b $C0,$00,$00,$00,$00,$00,$00,$46
	EndDataSection
EndProcedure

Debug ShortcutTarget("C:\xxx.lnk")
M.