Power Builder - Funcion Kernel

 
Vista:

Funcion Kernel

Publicado por Juan Carlos (28 intervenciones) el 27/01/2003 09:55:44
Hola. Hace unos dias pregunte si alguien sabe de alguna funcion que obtenga informacion del disco duro (espacio libre, ocupado, etc) . Yo lo probe con la funcion del kernel GetDiskFreeSpaceEx pero no me funciona. Alguien sabe de alguna de obtener esta informacion ?
Muchas gracias
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:Funcion Kernel

Publicado por Pedro López (68 intervenciones) el 30/01/2003 10:12:12
A mi me funcionó declarando el ULARGE_INTEGER como una estructura de dos unsignedlong (de 32 bits).

Lo primero que debes hacer es declarar la estructura, por ejemplo:

str_ularge_long
unsignedlong ul_large_long_baja
unsignedlong ul_large_long_alta

La declaración de la función GetDiskFreeSpaceExA quedaría:
FUNCTION Long GetDiskFreeSpaceExA (string as_dir, ref str_ularge_long ast_userfreebytes, ref str_ularge_long ast_totalbytes, ref str_ularge_long ast_totalfreebytes) library "kernel32.dll"

// Después, en tu script, debes poner el siguiente código (lo puedes adaptar a tus necesidades):
str_ularge_long lstr_userfreebytes, lstr_totalbytes, lstr_totalfreebytes
long ll_ret
unsignedlong lul_libreex, lul_totalex

// Llamar a la función GetDiskFreeSpaceA
ll_ret = GetDiskFreeSpaceExA ("C:\", lstr_userfreebytes, lstr_totalbytes, lstr_totalfreebytes)

// Comprobar errores
if ll_ret = 0 then
MessageBox ("Error", "Error al acceder al disco.")
return -1
End if

// Se toma el valor ul_large_long_baja.
// Si el disco es muy grande, podría ser necesario hacer algún
// cálculo con ul_large_long_alta, pero yo no lo he utilizado.
lul_libreex = lstr_totalfreebytes.ul_large_long_baja
lul_totalex = lstr_totalbytes.ul_large_long_baja
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Funcion Kernel

Publicado por Pedro López (68 intervenciones) el 30/01/2003 10:18:48
También tienes que tener en cuenta que la función GetDiskFreeSpaceExA requiere W95 OSR2, WNT 4.0, o una versión superior de cualquiera de ellos. Si quieres asegurar la compatibilidad con las versiones anteriores, debes utilizar la función GetDiskFreeSpaceA, que es parecida a GetDiskFreeSpaceExA, pero tienes que realizar cálculos.

Ejemplo:

// Declarar la función GetDiskFreeSpaceA
Function Long GetDiskFreeSpaceA (String lpRootPathName, Ref Long lpSectorsPerCluster, Ref Long lpBytesPerCluster, Ref Long lpNumberOfFreeClusters, Ref Long lpTotalNumberOfClusters) library "Kernel32.dll"

// Después, en tu script, debes poner el siguiente código (lo puedes adaptar a tus necesidades):
unsignedlong lul_SectoresClust, lul_bytesSector, lul_Clust_libres, lul_Total_Clust, lul_esp_Total, lul_esp_libre
long ll_ret
// Llamar a la función GetDiskFreeSpaceA
ll_ret = GetDiskFreeSpaceA ("C:\", lul_SectoresClust, lul_bytesSector, lul_Clust_libres, lul_Total_Clust)
// Comprobar errores
if ll_ret = 0 then
MessageBox ("Error", "Error al acceder al disco.")
return -1
End if

// Cálculos para obtener el espacio libre y la capacidad total del disco:
// Espacio libre = (Bytes por sector) * (Sectores por cluster) * (Nº de clusters libres)
lul_esp_libre = lul_bytesSector * lul_SectoresClust * lul_Clust_libres
// Espacio total = (Bytes por sector) * (Sectores por cluster) * (Nº total de clusters)
lul_esp_Total = lul_bytesSector * lul_SectoresClust * lul_Total_Clust
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Funcion Kernel

Publicado por Juan Carlos (28 intervenciones) el 30/01/2003 17:53:20
Hola Pedro. He probado lo que me dices y esta vez no me falla la llamada pero no entiendo los datos devueltos. Me explico. Mi unidad C tiene espacio libre de 17.946.595.328 bytes (16,7 Gigas) y espacio total de 3.027.832.832 byes. El resultado de la funcion me indica que el espacio libre es de 767.246.336 y el total segun GetDiskFreeSpaceA es de -500.408.320 (con la otra llamada es de 3.794.558.976.
Falta hacer alguna conversion mas ?? o puede deberse a que son particiones de mas de dos gigas ???

Muchas gracias por tu ayuda
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Funcion Kernel

Publicado por Pedro López (68 intervenciones) el 31/01/2003 08:59:33
El problema está en los tipos que he utilizado en los ejemplos. Si miras en la ayuda de PowerBuilder, puedes comprobar que los valores máximos para los tipos Long y UnsignedLong son +2.147.483.647 y +4.294.967.295. Por eso obtienes resultados incorrectos.

Si utilizas GetDiskFreeSpaceA, debes cambiar los tipos de los parámetros de Long a UnsignedLong:

Después, debes guardar los resultados en variables de tipo double:
double ldbl_esp_Total, ldbl_esp_libre
......................................
ldbl_esp_libre = lul_bytesSector * lul_SectoresClust * lul_Clust_libres
ldbl_esp_Total = lul_bytesSector * lul_SectoresClust * lul_Total_Clust

Si utilizas GetDiskFreeSpaceExA, también tienes que almacenar el resultado en una variable de tipo Double, pero además tienes que componer el resultado (un entero de 64 bits), a partir de los dos enteros de 32 bits de la estructura. Por ejemplo, puedes crear una función (f_int64) que componga el entero de 64 bits a partir de los dos enteros de 32 bits, y que retorne el resultado en un double:

// Después en tu script:
double ldbl_libreex, ldbl_totalex
.......................................
ldbl_libreex = f_int64(lstr_totalfreebytes.ul_large_long_baja, lstr_totalfreebytes.ul_large_long_alta)
ldbl_totalex = f_int64(lstr_totalbytes.ul_large_long_baja, lstr_totalbytes.ul_large_long_alta)

Lo que no sé es que operación u operaciones deberías hacer en la función f_int64, para componer el entero de 64 bits. Puede que alguien que sepa de matemáticas te pueda ayudar en este caso.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Funcion Kernel

Publicado por Pedro López (68 intervenciones) el 31/01/2003 12:08:50
Hola Juan Carlos

En lo que te he dicho antes había un error.

Si utilizas GetDiskFreeSpaceA, además de recoger el resultado en un double, tambien tienes que convertir los valores UnsignedLong a Double al hacer el cálculo. Si no los conviertes, el resultado se sigue truncando.

Por ejemplo, te debería funcionar así:
// Declarar la función GetDiskFreeSpaceA
Function Long GetDiskFreeSpaceA (String lpRootPathName, Ref UnsignedLong lpSectorsPerCluster, Ref UnsignedLong lpBytesPerCluster, Ref UnsignedLong lpNumberOfFreeClusters, Ref UnsignedLong lpTotalNumberOfClusters) library "Kernel32.dll"

// En tu script:
double ldbl_esp_Total, ldbl_esp_libre
.................
// Llamar a la función GetDiskFreeSpaceA
.................
.................
// Cálculos para obtener el espacio libre y la capacidad total del disco
ldbl_esp_libre = double(lul_bytesSector) * double(lul_SectoresClust) * double(lul_Clust_libres)
ldbl_esp_Total = double(lul_bytesSector) * double(lul_SectoresClust) * double(lul_Total_Clust)

También tengo otra cosa que comentarte. Cuando te digo que utilices un Double (tanto con GetDiskFreeSpaceA como con GetDiskFreeSpaceExA), también te podría servir el tipo Decimal. Puedes hacer pruebas con los dos, para comprobar con cual va mejor, o si funciona igual con los dos.

Espero haberte ayudado, y comenta como lo has hecho al final.

Un saludo.

Pedro
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Funcion Kernel

Publicado por Juan Carlos (28 intervenciones) el 03/02/2003 09:23:45
Hola Pedro . Finalmente lo he conseguido y faltaba lo que comentabas, convertir los valores a DOUBLE. Haciendo esto funciona perfectamente. Muchas gracias por tu ayuda.
Un saludo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar