Informations sur la corbeille Windows

Codes specifiques à Windows
thierryd44
Messages : 8
Inscription : sam. 30/avr./2016 17:53

Informations sur la corbeille Windows

Message par thierryd44 »

Bonjour.
Je galère pour utiliser SHQueryRecycleBin de l'API Windows non implémentée directement dans Purebasic.
https://docs.microsoft.com/en-us/window ... ecyclebinw
Je passe donc par un prototype. Je pense que mon codage est correct, mais j'ai toujours un retour #E_INVALIDARG (argument invalide, mais lequel ???), que je lance avec une chaine vide (pour obtenir la corbeille complète) ou un disque ("C:\" par exemple, pour obtenir les infos sur ce disque uniquement.

Mon code est plutôt simple.

Code : Tout sélectionner

Structure Struct_SHQUERYRBINFO ; Structure de l'API windows non déclarée
  taille_Structure.l
  taille_corbeille.q
  nbItem_corbeille.q
EndStructure

Prototype.i Proto_SHQueryRecycleBinW(rep.s,*ptr_struct)
Define adresse_fonction.Proto_SHQueryRecycleBinW
Define retour.i,
       info_corbeille.Struct_SHQUERYRBINFO

Define rep$=""; "C:\"

info_corbeille\taille_Structure=SizeOf(Struct_SHQUERYRBINFO)

If OpenLibrary(0, "shell32.dll") 
  adresse_fonction = GetFunction(0,"SHQueryRecycleBinW")
  If adresse_fonction
    retour=adresse_fonction(rep$, @info_corbeille)
    If retour <> #S_OK
      Debug "Erreur fonction SHQueryRecycleBinW "+FormatNumber(retour,0,""," ") ; #E_INVALIDARG : 2 147 942 487
    Else
      Debug "Taille corbeille : "+Str(info_corbeille\taille_corbeille)+"   Nb élements : "+Str(info_corbeille\nbItem_corbeille)
    EndIf 
    
  Else
    Debug "SHQueryRecycleBinW non trouvé dans shell32.dll"
  EndIf
  
Else
  Debug "Erreur OpenLibrary"
EndIf
Je m'interroge en particulier sur la chaine de caractères à passer. Ici, j'utilise la version unicode de la fonction, et je compile en version 5.73. La doc Purebasic précise que l'encodage UNICODE est le même que celui de Windows. Pourtant, je ne vois que là où pourrait se trouver un problème.
La structure me semble conforme a la demande de l'API...
Bref, je sèche !
Si quelqu'un a une idée, je suis preneur...
Avec mes remerciements par avance.
Thierry
Avatar de l’utilisateur
kernadec
Messages : 1606
Inscription : ven. 25/avr./2008 11:14

Re: Informations sur la corbeille Windows

Message par kernadec »

bjr thierryd44
Dans la compile Code Archive http://purearea.net/pb/CodeArchiv/CodeArchiv.html
il y a cet exemple:

Code : Tout sélectionner

; English forum: http://www.purebasic.fr/english/viewtopic.php?t=8607&highlight=
; Author: PB (updated for PB4.00 by blbltheworm)
; Date: 04. December 2003
; OS: Windows
; Demo: Yes

; PureBasic doesn't (yet) support the SHEmptyRecycleBin() API (probably 
; due to Windows 95/NT not supporting it). However, using the OpenLibrary 
; functions you can pretty much use any API you want (even if PureBasic 
; doesn't support it), so here's an example of emptying the Recycle Bin: 

Procedure EmptyTrash(confirm) 
  ;confirm = 1 > vide la corbeille avec confirmation
  ;confirm = 0 > vide la corbeille sans confirmation
  If OpenLibrary(0,"shell32.dll") And GetFunction(0,"SHEmptyRecycleBinA") 
    ;CallFunction(0,"SHEmptyRecycleBinA",0,"",1-confirm) ; dans code archive erreur du paramètre 4 mettre  0  à la place de ""
    CallFunction(0,"SHEmptyRecycleBinA",0,0,1-confirm) 
    CloseLibrary(0) 
  EndIf 
EndProcedure
EmptyTrash(1) ; 1 = confirm with user first, 0 = don't confirm. 
Cordialement
thierryd44
Messages : 8
Inscription : sam. 30/avr./2016 17:53

Re: Informations sur la corbeille Windows

Message par thierryd44 »

Bonjour Kernadec.
Merci pour cette réponse.
Effectivement, cet appel fonctionne, mais les paramètres sont uniquement numériques... et donc CallFunction marche.
dans mon cas, les paramètres sont : un chaine de caractères et un pointeur sur une structure.
A noter que les exemples trouvés (en C principalement) montre bien que le 1er paramètre est la chaine et non l'adresse de la chaine comme on pourrait le penser en regardant la doc de l'API...
Avatar de l’utilisateur
kernadec
Messages : 1606
Inscription : ven. 25/avr./2008 11:14

Re: Informations sur la corbeille Windows

Message par kernadec »

Au sujet de la corbeille il y a ce lien et ces codes qui devraient être facile a adaptés sous PureBasic
https://www.dreamincode.net/forums/topi ... n-with-c#/
Cordialement
thierryd44
Messages : 8
Inscription : sam. 30/avr./2016 17:53

Re: Informations sur la corbeille Windows

Message par thierryd44 »

Merci Kernadec.
Mais je ne comprends pas vraiment tout ce code...
J'ai fait un essai avec une autre fonction de l'API qui utilise le même type de paramètres. Et là ça fonctionne parfaitement !

Code : Tout sélectionner

Define type$=""
Define adresse_fonction.i, retour.i, i.i
Define InfoFichier.SHFILEINFO
Define fichier$="c:\"
Prototype.i Proto_SHGetFileInfoW(a.s,b.l,*c,d.l,e.l)
Define adresse_fonction.Proto_SHGetFileInfoW
If OpenLibrary(0, "shell32.dll") 
  adresse_fonction = GetFunction(0,"SHGetFileInfoW")
  If adresse_fonction
    retour=adresse_fonction(fichier$,0,@InfoFichier,SizeOf(SHFILEINFO),#SHGFI_TYPENAME) 
    If Not retour
      Debug "Erreur fonction SHGetFileInfoW "+Str(GetLastError_())
    Else
      For i = 0 To 79
        If InfoFichier\szTypeName[i]<>0
          type$+Chr(InfoFichier\szTypeName[i])
        EndIf
      Next
      Debug "!"+type$+"!"
    EndIf 
  Else
    Debug "SHGetFileInfoW non trouvé dans shell32.dll"
  EndIf
Else
  Debug "Erreur OpenLibrary"
EndIf

CloseLibrary(0)
Cette fonction renvoie des informations sur un fichier ou un répertoire passé en paramètre, en l'occurrence, le type.

Décidément, c'est incompréhensible...
Je crois que je vais mettre ce point en attente d'inspiration ...
Merci pour ton aide.
Avatar de l’utilisateur
Pierre Bellisle
Messages : 25
Inscription : jeu. 21/juin/2018 6:01

Re: Informations sur la corbeille Windows

Message par Pierre Bellisle »

Le problème venait de l'alignement de la structure SHQUERYRBINFO.
En 32 bit, tous les éléments de la structure sont aligné sur 4 octets, donc consécutif.
En 64 bit, l'alignement se fait sur 8 octets, cbSize.l ne mesurant que 4 octets,
l'élément le suivant doit donc être décalé de 4 octets pour respecter l'alignement demandé.
c'est comme si un élément invisible de 4 octets devait être ajouté après cbSize.l.
Conséquemment, en 32 bit SHQUERYRBINFO mesure 20 octets, en 64 bit il menure 24 octets.
Pour que le tout se fasse via le compilateur, il faut ajouter "Align SizeOf(INTEGER)" à la définition de cette structure.

Code : Tout sélectionner

Structure SHQUERYRBINFO Align SizeOf(INTEGER) ;Alignement sur 4 octets en 32 bit et de 8 octets en 64 bits
  cbSize.l 
  ;Ici, décalage de 4 octets en 64 bit
  i64Size.q 
  i64NumItems.q 
EndStructure

Define Disque.s = "C:\" ;Pour un disque spécifique
;Disque.s = "" ;Pour un total de tous les disque
Define AdresseFonction.i ;Define AdresseFonction.i
Define HResult.l ;Define HResult.l
Prototype Proto_SHQueryRecycleBinW(Disque.s, *info.SHQUERYRBINFO) ;Prototype.i Proto_SHQueryRecycleBinW(Disque.s, *info.SHQUERYRBINFO)
Define AdresseFonction.Proto_SHQueryRecycleBinW
Define shInfo.SHQUERYRBINFO 
Define sMessage.s

If OpenLibrary(0, "Shell32.dll") 
  AdresseFonction = GetFunction(0, "SHQueryRecycleBinW")
  If AdresseFonction
    shInfo\cbSize = SizeOf(SHQUERYRBINFO)
    HResult = AdresseFonction(Disque, @shInfo) 
    If HResult = S_OK 
      sMessage = "SHQueryRecycleBinW " + #CRLF$ + "Diques " + Disque + #CRLF$ + 
                 "Nombre de fichiers " + FormatNumber(shInfo\i64NumItems, 0) + #CRLF$ + 
                 "Nombre d'octets "    + FormatNumber(shInfo\i64Size, 0)
    Else
      sMessage = "L'appel à SHQueryRecycleBinW a donné cette erreur: " + Hex(HResult) + " (" + Str(HResult) + ")"
    EndIf 
  Else
    sMessage = "SHQueryRecycleBinW n'a pas été trouvé dans Shell32.dll !"
  EndIf
  CloseLibrary(0)
Else
  sMessage = "OpenLibrary() n'a pas fontionné !"
EndIf
MessageBox_(#HWND_DESKTOP, sMessage, "SHQueryRecycleBinW", #MB_OK | #MB_TOPMOST)
thierryd44
Messages : 8
Inscription : sam. 30/avr./2016 17:53

Re: Informations sur la corbeille Windows

Message par thierryd44 »

Bonsoir à tous.
Merci beaucoup Pierre. C'était effectivement la solution, et le fonctionnement est nickel
A noter qu'on peut aussi aligner avec la constante #PB_Structure_AlignC
On pouvait aussi tout simplement définir cbSize.i puisque l'integer respecte ce dimensionnement variable...
En tout état de cause, j'ai compris mon erreur, et c'est bien l'essentiel.
Avatar de l’utilisateur
Pierre Bellisle
Messages : 25
Inscription : jeu. 21/juin/2018 6:01

Re: Informations sur la corbeille Windows

Message par Pierre Bellisle »

Salut Thierry,

#PB_Structure_AlignC ne fait pas le même boulot, cela donneras des résultats non fiable sous 32 bit.
Sans Align, PB aligne à l'octet. Avec "Align #PB_Structure_AlignC", la structure sera alignée sur 8 octets,
ce qui fonctionneras sous 64 bit mais pas sous 32 bit ou nous avons besoin d'un alignement de 4 octets.

Comme tu le fais remarquer, dans le cas présent, déclarer cbSize.i vas fonctionner...
De mon coté, puisque "Align" fait ce qu'il faut, pour garder de bonnes habitudes, je préfère ne pas dénaturer un élément d'une structure, passer de 4 octets à 8 octets peut avoir des inconvénients... Un exemple... Si on désire transmettre ce même élément a un autre api, il sera désormais incompatible...
thierryd44
Messages : 8
Inscription : sam. 30/avr./2016 17:53

Re: Informations sur la corbeille Windows

Message par thierryd44 »

Merci pour toutes ces explications. Je comprends mieux le fonctionnement du coup.
Répondre