Question [Résolu] : Appel d'API Windows

Plus d'informations
il y a 13 ans 8 mois #7455 par POLICE Stéphane
Bonjour,

je cherche à connaître les informations de cluster sur un volume disque. Pour ce faire, je dois faire appel à une fonction dans une DLL de Windows (Kernel32.dll).

J'ai testé un code trouvé sur le Web qui fonctionne (GetDiskFreeSpaceEx.ps1) mais celui-ci ne fait pas ce que je veux. En effet il ne fait pas appel à la fonction voulue (GetDiskFreeSpace), mais une à une similaire (GetDiskFreeSpaceEx), je l'ai donc modifié pour qu'il fasse le bon appel (GetDiskClusterInfo.ps1).

Et c'est là que le problème commence : la définition de la fonction que j'ai saisie semble être incorrecte.

Merci à toutes et tous pour votre aide.

Et que la PowerForce soit avec vous.


Ci-joint fichier texte Kernel32.txt qui contient les deux scripts reproduits ci-dessous.


Script qui donne les infos d'espace disque sur C:\ - FONCTIONNE
GetDiskFreeSpaceEx.ps1 :
****************************************

<#
BOOL WINAPI GetDiskFreeSpaceEx(
__in_opt LPCTSTR lpDirectoryName,
__out_opt PULARGE_INTEGER lpFreeBytesAvailable,
__out_opt PULARGE_INTEGER lpTotalNumberOfBytes,
__out_opt PULARGE_INTEGER lpTotalNumberOfFreeBytes
);
#>

# Just declare Win32 API...
$a = Add-Type -memberDefinition @\"
[DllImport(\"Kernel32.dll\")]
public static extern bool GetDiskFreeSpaceEx(
string lpDirectoryName,
IntPtr lpFreeBytesAvailable,
IntPtr lpTotalNumberOfBytes,
IntPtr lpTotalNumberOfFreeBytes
);
\"@ -passthru -name MyGetDiskFreeSpaceEx

# Alloc some memory ...
$fba = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(20);
$tnb = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(20);
$nfb = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(20);

# Call 'GetDiskFreeSpaceEx' ...
$a::GetDiskFreeSpaceEx(\"C:\\", $fba, $tnb, $nfb)

# Get the Value storing in the memory pointed by $fba...
$x = [System.Runtime.InteropServices.Marshal]::ReadInt64($fba)
$y = [System.Runtime.InteropServices.Marshal]::ReadInt64($tnb)
$z = [System.Runtime.InteropServices.Marshal]::ReadInt64($nfb)

# Display the result ...
\"FreeBytesAvailable: $($x)\"
\"TotalNumberOfBytes: $($y)\"
\"TotalNumberOfFreeBytes: $($z)\"

# !! Free the memory ASAP....
[System.Runtime.InteropServices.Marshal]::FreeHGlobal($fba);
[System.Runtime.InteropServices.Marshal]::FreeHGlobal($tnb);
[System.Runtime.InteropServices.Marshal]::FreeHGlobal($nfb);
****************************************

Script qui donne les infos de cluster sur C:\ - NE FONCTIONNE PAS
GetDiskClusterInfo.ps1 :
****************************************

<#
BOOL WINAPI GetDiskFreeSpace(
__in LPCTSTR lpRootPathName,
__out LPDWORD lpSectorsPerCluster,
__out LPDWORD lpBytesPerSector,
__out LPDWORD lpNumberOfFreeClusters,
__out LPDWORD lpTotalNumberOfClusters
);
#>
# Just declare Win32 API...
$b = Add-Type -memberDefinition @\"
[DllImport(\"Kernel32.dll\")]
public static extern bool GetDiskFreeSpace(
string lpRootName,
IntPtr lpSectorsPerCluster,
IntPtr lpBytesPerSector,
IntPtr lpNumberOfFreeClusters
IntPtr lpTotalNumberOfClusters
);
\"@ -passthru -name MyGetDiskFreeSpace

# Alloc some memory ...
$spc = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(20);
$bps = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(20);
$nfc = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(20);
$tnc = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(20);

# Call 'GetDiskFreeSpace' ...
$b::GetDiskFreeSpace(\"C:\\", $spc, $bps, $nfc, $tnc)

# Get the Value stored in the memory pointed by $spc...
$x = [System.Runtime.InteropServices.Marshal]::ReadInt32($spc)
$y = [System.Runtime.InteropServices.Marshal]::ReadInt32($bps)
$z = [System.Runtime.InteropServices.Marshal]::ReadInt32($nfc)
$t = [System.Runtime.InteropServices.Marshal]::ReadInt32($tnc)

# Display the result ...
\"SectorsPerCluster: $($x)\"
\"BytesPerSector: $($y)\"
\"NumberOfFreeClusters: $($z)\"
\"TotalNumberOfClusters: $($t)\"

# !! Free the memory ASAP....
[System.Runtime.InteropServices.Marshal]::FreeHGlobal($spc);
[System.Runtime.InteropServices.Marshal]::FreeHGlobal($bps);
[System.Runtime.InteropServices.Marshal]::FreeHGlobal($nfc);
[System.Runtime.InteropServices.Marshal]::FreeHGlobal($tnc);
****************************************

La pièce jointe Kernel32.txt est absente ou indisponible

<br><br>Message édité par: L.Skywalker, à: 26/07/10 16:57

Que la PowerForce soit avec vous.
Pièces jointes :

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 13 ans 8 mois #7458 par Arthur
Réponse de Arthur sur le sujet Re:Appel d'API Windows
Alors de tête le problème ne viens pas du fait qu'il faut mettre un DWORD_PTR au lieu de intptr ?

Sinon d'après la doc msdn GetDiskFreeSpaceEx réalise la même fonction que GetDiskFreeSpace mais pour des volumes de plus de 2 GB tu est sûr que c'est la bonne fonction?

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 13 ans 8 mois #7463 par Laurent Dardenne
Réponse de Laurent Dardenne sur le sujet Re:Appel d'API Windows
Salut,
essaie ceci, issu du site P/Invoke :
[code:1]
# Just declare Win32 API...
$b = Add-Type -memberDefinition @\&quot;
[DllImport(\&quot;kernel32.dll\&quot;, SetLastError=true, CharSet=CharSet.Auto)]
public static extern bool GetDiskFreeSpace(
string lpRootPathName,
out uint lpSectorsPerCluster,
out uint lpBytesPerSector,
out uint lpNumberOfFreeClusters,
out uint lpTotalNumberOfClusters);
\&quot;@ -passthru -name MyGetDiskFreeSpace


[REF]$spc,[REF]$bps,[REF]$nfc,[REF]$tnc =$null

# Call 'GetDiskFreeSpace' ...
$b::GetDiskFreeSpace(\&quot;C:\\&quot;, $spc, $bps, $nfc, $tnc)

# Display the result ...
\&quot;SectorsPerCluster: $($spc.Value)\&quot;
\&quot;BytesPerSector: $($bps.Value)\&quot;
\&quot;NumberOfFreeClusters: $($nfc.Value)\&quot;
\&quot;TotalNumberOfClusters: $($tnc.Value)\&quot;

#$spc.Value * $bps.Value * $nfc.Value
#$spc.Value * $bps.Value * $tnc.Value
[/code:1]
Tu peux contrôler à l'aide de classes WMI, Win32_DiskDrive...
Concernant la gestion de pointeur, il n'est pas nécessaire de gérer la mémoire, en tout cas la doc sur MSDN ne le précise pas comme sur cette API .
Je te laisse vérifier.<br><br>Message édité par: Laurent Dardenne, à: 26/07/10 14:41

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 13 ans 8 mois #7465 par POLICE Stéphane
Réponse de POLICE Stéphane sur le sujet Re:Appel d'API Windows
Bonjour bilbao,

bilbao a écrit:

Alors de tête le problème ne viens pas du fait qu'il faut mettre un DWORD_PTR au lieu de intptr ?

Sinon d'après la doc msdn GetDiskFreeSpaceEx réalise la même fonction que GetDiskFreeSpace mais pour des volumes de plus de 2 GB tu est sûr que c'est la bonne fonction?


Je pense aussi, qu'il doit effectivement y avoir une erreur au niveau de la définition de fonction.

Cependant, l'utilisation de DWORD_PTR provoque la même erreur.

En ce qui concerne les fonctions GetDiskFreeSpaceEx et GetDiskFreeSpace, elles ne retournent pas les mêmes informations, je recherchai les infos de cluster.

Mais merci pour ta réponse.

Que la PowerForce soit avec vous.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 13 ans 8 mois #7466 par POLICE Stéphane
Réponse de POLICE Stéphane sur le sujet Re:Appel d'API Windows
Bonjour Laurent Dardenne,

SUPER

Celà fonctionne.

MERCI. :)

Que la PowerForce soit avec vous.

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.070 secondes
Propulsé par Kunena