PC SOFT

FORUMS PROFESSIONNELS
WINDEVWEBDEV et WINDEV Mobile

Accueil → WINDEV 24 → API winspool.drv Statut Imprimante
API winspool.drv Statut Imprimante
Débuté par Graviere Julien, 29 aoû. 2006 11:33 - 28 réponses
Posté le 29 août 2006 - 11:33
Ce message à l'attention de Philippe Pasquali ou tout autre developpeur ayant eu besoin du code ci-après :

Suite au code posté sur le Forum le 15/06/2005, je tente d'obtenir le statut de mon imprimante et cela ne fonctionne pas : même quand l'imprimante est en erreur, le code me renvoie 0 (tout est ok).
Je ne comprends pas cette ligne :
Etat = tSTATUS[1]:status //Pourquoi un indice de 1?
//Pourquoi ce n'est pas dynamique
//Puis je avoir plus d'explication?



x_PRINTER_INFO_2 est une structure
pServerName est un entier
pPrinterName est un entier
pShareName est un entier
pPortName est un entier
pDriverName est un entier
pComment est un entier
pLocation est un entier
pDevMode est un entier
pSepFile est un entier
pPrintProcessor est un entier
pDatatype est un entier
pParameters est un entier
pSecurityDescriptor est un entier
Attributes est un entier
Priority est un entier
DefaultPriority est un entier
StartTime est un entier
UntilTime est un entier
Status est un entier
cJobs est un entier
AveragePPM est un entier
END
-----------------------------------------------------------------------------------------------
pPrinterName est une chaîne ASCIIZ sur 256 = pPrinter
phPrinter est un entier = 0
pcbNeeded est un entier = 0
RetCode est un entier
tSTATUS est un tableau dynamique de 100 x_PRINTER_INFO_2
Buf est une chaîne ASCIIZ sur 2048
Etat est un entier = 0
Req est une chaîne
InfoErreur est une chaîne
-------------------------------------------------------------------------------------------
SI API( "winspool.drv" ,"OpenPrinterA", pPrinterName, &phPrinter, Null) <> 0 ALORS
RetCode = API("winspool.drv", "GetPrinterA", phPrinter, 2, &tSTATUS, 0,&pcbNeeded)
RetCode = API("winspool.drv", "GetPrinterA", phPrinter, 2, &tSTATUS,pcbNeeded, &pcbNeeded)
SI RetCode<>0 ALORS
Etat = tSTATUS[1]:status
FIN
API("winspool.drv", "ClosePrinter", phPrinter)
FIN
Posté le 29 août 2006 - 12:13
Depuis j'avais modifié le bazard (sans le dire : pas bien çà)
j'utilise PRINTER_INFO_6 qui est plus adaptée à ce type de fonction

//****************************
CONSTANT
// STATUT D'UNE IMPRIMANTE...................
// Peut etre une combinaison de ces valeurs
PRINTER_STATUS_PAUSED = 0x00000001
PRINTER_STATUS_ERROR = 0x00000002
PRINTER_STATUS_PENDING_DELETION = 0x00000004
PRINTER_STATUS_PAPER_JAM = 0x00000008
PRINTER_STATUS_PAPER_OUT = 0x00000010
PRINTER_STATUS_MANUAL_FEED = 0x00000020
PRINTER_STATUS_PAPER_PROBLEM = 0x00000040
PRINTER_STATUS_OFFLINE = 0x00000080
PRINTER_STATUS_IO_ACTIVE = 0x00000100
PRINTER_STATUS_BUSY = 0x00000200
PRINTER_STATUS_PRINTING = 0x00000400
PRINTER_STATUS_OUTPUT_BIN_FULL = 0x00000800
PRINTER_STATUS_NOT_AVAILABLE = 0x00001000
PRINTER_STATUS_WAITING = 0x00002000
PRINTER_STATUS_PROCESSING = 0x00004000
PRINTER_STATUS_INITIALIZING = 0x00008000
PRINTER_STATUS_WARMING_UP = 0x00010000
PRINTER_STATUS_TONER_LOW = 0x00020000
PRINTER_STATUS_NO_TONER = 0x00040000
PRINTER_STATUS_PAGE_PUNT = 0x00080000
PRINTER_STATUS_USER_INTERVENTION = 0x00100000
PRINTER_STATUS_OUT_OF_MEMORY = 0x00200000
PRINTER_STATUS_DOOR_OPEN = 0x00400000
PRINTER_STATUS_SERVER_UNKNOWN = 0x00800000
PRINTER_STATUS_POWER_SAVE = 0x01000000
INVALID_PRINTER = 0x10000000
END

//****************************
_PRINTER_INFO_6 est une structure
Status est un entier
END

//****************************
// Renvoie le status d'une imprimante
//****************************
FUNCTION iGetStatus(pPrinterName=iInfoImprimante())

Status, hdPrint, Ret, cbBuf, pcbNeeded sont des entiers
PrinterName est une chaîne ASCIIZ sur 512 = pPrinterName
tPRINTER est une x_PRINTER_INFO_6
PRINTER_INFO_LEVEL est un entier = 6
Buf est une chaîne ASCIIZ sur 1024
Status = INVALID_PRINTER

// Ouverture du handle avec l'imprimante
Ret = API( "winspool.drv", "OpenPrinterA" , &PrinterName, &hdPrint, Null)
IF Ret = 0 THEN RENVOYER Status

// Execution de la fonction une fois avec 0 pour connaitre le nombre exact
cbBuf = 0
pcbNeeded = 0
API( "winspool.drv", "GetPrinterA", hdPrint, PRINTER_INFO_LEVEL, &tPRINTER,
cbBuf, &pcbNeeded)

// Met le nombre renvoyer par le premier appel
cbBuf = pcbNeeded
Ret = API( "winspool.drv", "GetPrinterA", hdPrint, PRINTER_INFO_LEVEL,
&tPRINTER, cbBuf, &pcbNeeded)
IF Ret = 0 THEN
API("winspool.drv","ClosePrinter", hdPrint)
RENVOYER Status
END

Status = tPRINTER:Status

API("winspool.drv","ClosePrinter", hdPrint)

RENVOYER Status


Status = tPRINTER[1]:Status

API("winspool.drv","ClosePrinter", hdPrint)

RENVOYER Status // peut etre un OuBinaire des constantes

"Graviere Julien" <gravierejulien@yahoo.fr> a écrit dans le message de news:
44f3e771$1@news.pcsoft.fr...

Ce message à l'attention de Philippe Pasquali ou tout autre developpeur
ayant eu besoin du code ci-après :

Suite au code posté sur le Forum le 15/06/2005, je tente d'obtenir le
statut de mon imprimante et cela ne fonctionne pas : même quand
l'imprimante est en erreur, le code me renvoie 0 (tout est ok).
Je ne comprends pas cette ligne :
Etat = tSTATUS[1]:status //Pourquoi un indice de 1?
//Pourquoi ce n'est pas dynamique
//Puis je avoir plus d'explication?



x_PRINTER_INFO_2 est une structure
pServerName est un entier
pPrinterName est un entier
pShareName est un entier
pPortName est un entier
pDriverName est un entier
pComment est un entier
pLocation est un entier
pDevMode est un entier
pSepFile est un entier
pPrintProcessor est un entier
pDatatype est un entier
pParameters est un entier
pSecurityDescriptor est un entier
Attributes est un entier
Priority est un entier
DefaultPriority est un entier
StartTime est un entier
UntilTime est un entier
Status est un entier
cJobs est un entier
AveragePPM est un entier
END
-----------------------------------------------------------------------------------------------
pPrinterName est une chaîne ASCIIZ sur 256 = pPrinter
phPrinter est un entier = 0
pcbNeeded est un entier = 0
RetCode est un entier
tSTATUS est un tableau dynamique de 100 x_PRINTER_INFO_2
Buf est une chaîne ASCIIZ sur 2048
Etat est un entier = 0
Req est une chaîne
InfoErreur est une chaîne
-------------------------------------------------------------------------------------------
SI API( "winspool.drv" ,"OpenPrinterA", pPrinterName, &phPrinter, Null) <>
0 ALORS
RetCode = API("winspool.drv", "GetPrinterA", phPrinter, 2, &tSTATUS,
0,&pcbNeeded)
RetCode = API("winspool.drv", "GetPrinterA", phPrinter, 2,
&tSTATUS,pcbNeeded, &pcbNeeded)
SI RetCode<>0 ALORS
Etat = tSTATUS[1]:status
FIN
API("winspool.drv", "ClosePrinter", phPrinter)
FIN
Posté le 29 août 2006 - 13:06
J'ai vu les differences de code, mais le resultat est le meme, la fonction me renvoie toujours 0!
De plus j'ai une erreur de compilation sur la ligne "Status = tPRINTER[1]:Status", ce qui parait logique puisque la structure printer_info_6 ne contient qu'un entier!
Est ce normal?
Merci beaucoup!
Posté le 29 août 2006 - 14:05
Attention dans ma copie il y a une bourde
...........
> RENVOYER Status
****************************
LE PROGRAMME FINI ICI
****************************

Status = tPRINTER[1]:Status

API("winspool.drv","ClosePrinter", hdPrint)

RENVOYER Status // peut etre un OuBinaire des constantes


Si je met mon imprimante en pause, j'ai bien PRINTER_STATUS_PAUSED =
0x00000001
mais si le document est en erreur, je pense qu'il faut aller voir le status
du job et non du spool



"philippe pasquali" <philippe.pasquali@bopack.fr> a écrit dans le message de
news: 44f3f69b$1@news.pcsoft.fr...

Depuis j'avais modifié le bazard (sans le dire : pas bien çà)
j'utilise PRINTER_INFO_6 qui est plus adaptée à ce type de fonction

//****************************
CONSTANT
// STATUT D'UNE IMPRIMANTE...................
// Peut etre une combinaison de ces valeurs
PRINTER_STATUS_PAUSED = 0x00000001
PRINTER_STATUS_ERROR = 0x00000002
PRINTER_STATUS_PENDING_DELETION = 0x00000004
PRINTER_STATUS_PAPER_JAM = 0x00000008
PRINTER_STATUS_PAPER_OUT = 0x00000010
PRINTER_STATUS_MANUAL_FEED = 0x00000020
PRINTER_STATUS_PAPER_PROBLEM = 0x00000040
PRINTER_STATUS_OFFLINE = 0x00000080
PRINTER_STATUS_IO_ACTIVE = 0x00000100
PRINTER_STATUS_BUSY = 0x00000200
PRINTER_STATUS_PRINTING = 0x00000400
PRINTER_STATUS_OUTPUT_BIN_FULL = 0x00000800
PRINTER_STATUS_NOT_AVAILABLE = 0x00001000
PRINTER_STATUS_WAITING = 0x00002000
PRINTER_STATUS_PROCESSING = 0x00004000
PRINTER_STATUS_INITIALIZING = 0x00008000
PRINTER_STATUS_WARMING_UP = 0x00010000
PRINTER_STATUS_TONER_LOW = 0x00020000
PRINTER_STATUS_NO_TONER = 0x00040000
PRINTER_STATUS_PAGE_PUNT = 0x00080000
PRINTER_STATUS_USER_INTERVENTION = 0x00100000
PRINTER_STATUS_OUT_OF_MEMORY = 0x00200000
PRINTER_STATUS_DOOR_OPEN = 0x00400000
PRINTER_STATUS_SERVER_UNKNOWN = 0x00800000
PRINTER_STATUS_POWER_SAVE = 0x01000000
INVALID_PRINTER = 0x10000000
END

//****************************
_PRINTER_INFO_6 est une structure
Status est un entier
END

//****************************
// Renvoie le status d'une imprimante
//****************************
FUNCTION iGetStatus(pPrinterName=iInfoImprimante())

Status, hdPrint, Ret, cbBuf, pcbNeeded sont des entiers
PrinterName est une chaîne ASCIIZ sur 512 = pPrinterName
tPRINTER est une x_PRINTER_INFO_6
PRINTER_INFO_LEVEL est un entier = 6
Buf est une chaîne ASCIIZ sur 1024
Status = INVALID_PRINTER

// Ouverture du handle avec l'imprimante
Ret = API( "winspool.drv", "OpenPrinterA" , &PrinterName, &hdPrint, Null)
IF Ret = 0 THEN RENVOYER Status

// Execution de la fonction une fois avec 0 pour connaitre le nombre exact
cbBuf = 0
pcbNeeded = 0
API( "winspool.drv", "GetPrinterA", hdPrint, PRINTER_INFO_LEVEL,
&tPRINTER,
cbBuf, &pcbNeeded)

// Met le nombre renvoyer par le premier appel
cbBuf = pcbNeeded
Ret = API( "winspool.drv", "GetPrinterA", hdPrint, PRINTER_INFO_LEVEL,
&tPRINTER, cbBuf, &pcbNeeded)
IF Ret = 0 THEN
API("winspool.drv","ClosePrinter", hdPrint)
RENVOYER Status
END

Status = tPRINTER:Status

API("winspool.drv","ClosePrinter", hdPrint)

RENVOYER Status


Status = tPRINTER[1]:Status

API("winspool.drv","ClosePrinter", hdPrint)

RENVOYER Status // peut etre un OuBinaire des constantes

"Graviere Julien" <gravierejulien@yahoo.fr> a écrit dans le message de
news:
44f3e771$1@news.pcsoft.fr...

Ce message à l'attention de Philippe Pasquali ou tout autre developpeur
ayant eu besoin du code ci-après :

Suite au code posté sur le Forum le 15/06/2005, je tente d'obtenir le
statut de mon imprimante et cela ne fonctionne pas : même quand
l'imprimante est en erreur, le code me renvoie 0 (tout est ok).
Je ne comprends pas cette ligne :
Etat = tSTATUS[1]:status //Pourquoi un indice de 1?
//Pourquoi ce n'est pas dynamique
//Puis je avoir plus d'explication?



x_PRINTER_INFO_2 est une structure
pServerName est un entier
pPrinterName est un entier
pShareName est un entier
pPortName est un entier
pDriverName est un entier
pComment est un entier
pLocation est un entier
pDevMode est un entier
pSepFile est un entier
pPrintProcessor est un entier
pDatatype est un entier
pParameters est un entier
pSecurityDescriptor est un entier
Attributes est un entier
Priority est un entier
DefaultPriority est un entier
StartTime est un entier
UntilTime est un entier
Status est un entier
cJobs est un entier
AveragePPM est un entier
END
-----------------------------------------------------------------------------------------------
pPrinterName est une chaîne ASCIIZ sur 256 = pPrinter
phPrinter est un entier = 0
pcbNeeded est un entier = 0
RetCode est un entier
tSTATUS est un tableau dynamique de 100 x_PRINTER_INFO_2
Buf est une chaîne ASCIIZ sur 2048
Etat est un entier = 0
Req est une chaîne
InfoErreur est une chaîne
-------------------------------------------------------------------------------------------
SI API( "winspool.drv" ,"OpenPrinterA", pPrinterName, &phPrinter, Null)
<>
0 ALORS
RetCode = API("winspool.drv", "GetPrinterA", phPrinter, 2, &tSTATUS,
0,&pcbNeeded)
RetCode = API("winspool.drv", "GetPrinterA", phPrinter, 2,
&tSTATUS,pcbNeeded, &pcbNeeded)
SI RetCode<>0 ALORS
Etat = tSTATUS[1]:status
FIN
API("winspool.drv", "ClosePrinter", phPrinter)
FIN


Posté le 29 août 2006 - 15:57
J'avais compris la bourde, mais mon problème est que meme si j'eteins l'imprimante, je devrai avoir un statut = PRINTER_STATUS_OFFLINE!
Hors mon statut est égale à 0!
Pourtant il reconnait bien l'imprimante,puisqu'avec l'autre fonction,il me renvoie les fichiers qui sont dans la file d'attente!
As tu un idée?
De plus question pour mon info personnelle : quel est l'interet de faire une structure avec un seul menbre dedans!
Merci
Julien
Posté le 29 août 2006 - 16:11
1° Ton imprimante est-elle en réseau ou locale ?

2° C'était une copie d'un code de test et c'est resté comme cela... Eh oui
parfois quant ca fonctionne on revient plus dessus pour simplifier.

"Graviere Julien" <gravierejulien@yahoo.fr> a écrit dans le message de news:
44f42b15$1@news.pcsoft.fr...

J'avais compris la bourde, mais mon problème est que meme si j'eteins
l'imprimante, je devrai avoir un statut = PRINTER_STATUS_OFFLINE!
Hors mon statut est égale à 0!
Pourtant il reconnait bien l'imprimante,puisqu'avec l'autre fonction,il me
renvoie les fichiers qui sont dans la file d'attente!
As tu un idée?
De plus question pour mon info personnelle : quel est l'interet de faire
une structure avec un seul menbre dedans!
Merci
Julien
Posté le 29 août 2006 - 16:34
J'ai essayer les 2, mais actuellment, je suis en test sur une imprimante locale non partagée!
Quoi que je fasse, bourrage papier,hors ligne, plus de papier, j'ai la variable ret qui est egale à 1 et status à 0!!
Comment puis je me sortir de cette impasse?
Julien
Posté le 30 août 2006 - 10:41
Je te remercie sincerement, je vais tester cela et je te tiens au courant!
Cordialement
Julien
Posté le 30 août 2006 - 16:07
Plus personne pour mon problème?
Pascal?
Posté le 30 août 2006 - 16:15
Je ne sais plus quoi faire, j'ai toujours 0 quoi que je fasse, pourtant l'imprimante est hors ligne!!
Posté le 30 août 2006 - 16:30
Je t'ai envoyé la fenetre de resultat sur ta boite mail pascal!
Posté le 30 août 2006 - 16:59
Si c'est a mon adresse, je n'ai rien reçu.
"Graviere Julien" <gravierejulien@yahoo.fr> a écrit dans le message de news:
44f6d420$1@news.pcsoft.fr...


Je t'ai envoyé la fenetre de resultat sur ta boite mail pascal!

Posté le 30 août 2006 - 17:14
Oups !
j't'avais complétement oublié ! je regarde en fin de journée mais je ne te
promet rien...

"Graviere Julien" <gravierejulien@yahoo.fr> a écrit dans le message de news:
44f433f9$1@news.pcsoft.fr...

J'ai essayer les 2, mais actuellment, je suis en test sur une imprimante
locale non partagée!
Quoi que je fasse, bourrage papier,hors ligne, plus de papier, j'ai la
variable ret qui est egale à 1 et status à 0!!
Comment puis je me sortir de cette impasse?
Julien
Posté le 30 août 2006 - 18:47
Redonne moi tona dresse stp!
Posté le 30 août 2006 - 19:03
Bon aprés tests sur
1 imprimante locale dont le spool était en pause
1 imprimante réseau avec toner bas
voila le bordel

// ************************************
// ON REVIENT AVEC CETTE STRUCTURE
// ************************************
_PRINTER_INFO_2 est une structure
pServerName est un entier
pPrinterName est un entier
pShareName est un entier
pPortName est un entier
pDriverName est un entier
pComment est un entier
pLocation est un entier
pDevMode est un entier
pSepFile est un entier
pPrintProcessor est un entier
pDatatype est un entier
pParameters est un entier
pSecurityDescriptor est un entier
Attributes est un entier
Priority est un entier
DefaultPriority est un entier
StartTime est un entier
UntilTime est un entier
Status est un entier
cJobs est un entier
AveragePPM est un entier
END

// *****************************************************************
// LA FONCTION TRES DETAILLEE POUR FACILITER LA COMPREHENSION
// *****************************************************************
FUNCTION iPrinterGetStatus(pPrinterName=iInfoImprimante())

// Renvoie les informations sur une imprimante
// voir à la fin les informations renvoyées


hdPrint, Ret, cbBuf, pcbNeeded sont des entiers
sPrinterName est une chaîne ASCIIZ sur 512 = pPrinterName
basePRINTER est un _PRINTER_INFO_2
tPRINTER est un tableau dynamique de 1 _PRINTER_INFO_2
PRINTER_INFO_LEVEL est un entier = 2

// Ouverture du handle avec l'imprimante
Ret = API( winspool_drv, "OpenPrinterA" , &sPrinterName, &hdPrint, Null)
IF Ret = 0 THEN RENVOYER ""

// Execution de la fonction une fois avec 0 pour connaitre le nombre exact
cbBuf = 0
pcbNeeded = 0
API( winspool_drv, "GetPrinterA", hdPrint, PRINTER_INFO_LEVEL, &tPRINTER,
cbBuf, &pcbNeeded)
IF pcbNeeded > 0 THEN
cbBuf = pcbNeeded

// On redimensionne tPrinter de facon a avoir assez de place.............

// C'est un peut confu, mais il semble que GetPrinterA stocke dans le
premier tPRINTER[1] les adresses des chaines qui sont stockées aprés mais
dans la même zone mémoire

// pcbNeeded : Nombre d'octet pour la structure et les data
// dimension(basePRINTER) : Nombre d'octet pour 1 structure
// donc pour etre sur on prend
PartieEntière(pcbNeeded/dimension(basePRINTER))+1

Dimension(tPRINTER, PartieEntière(pcbNeeded/Dimension(basePRINTER))+1)
// et on relance
Ret = API( winspool_drv, "GetPrinterA", hdPrint, PRINTER_INFO_LEVEL,
&tPRINTER, cbBuf, &pcbNeeded)
IF Ret = 0 THEN
API(winspool_drv,"ClosePrinter", hdPrint)
RENVOYER ""
END
END

API(winspool_drv,"ClosePrinter", hdPrint)

// Ici on peut exploiter
ServeurName est une chaîne = ChaîneRécupère( tPRINTER[1]:pServerName,
crAdresseASCIIZ)
PrinterName est une chaîne = ChaîneRécupère( tPRINTER[1]:pPrinterName,
crAdresseASCIIZ)
ShareName est une chaîne = ChaîneRécupère( tPRINTER[1]:pShareName,
crAdresseASCIIZ)
PortName est une chaîne = ChaîneRécupère( tPRINTER[1]:pPortName,
crAdresseASCIIZ)
DriverName est une chaîne = ChaîneRécupère( tPRINTER[1]:pDriverName,
crAdresseASCIIZ)
Comment est une chaîne = ChaîneRécupère( tPRINTER[1]:pComment,
crAdresseASCIIZ)
Location est une chaîne = ChaîneRécupère( tPRINTER[1]:pLocation,
crAdresseASCIIZ)
DevMode est une chaîne = ChaîneRécupère( tPRINTER[1]:pDevMode,
crAdresseASCIIZ)
SepFile est une chaîne = ChaîneRécupère( tPRINTER[1]:pSepFile,
crAdresseASCIIZ)
PrintProcessor est une chaîne = ChaîneRécupère( tPRINTER[1]:pPrintProcessor,
crAdresseASCIIZ)
sDatatype est une chaîne = ChaîneRécupère( tPRINTER[1]:pDatatype,
crAdresseASCIIZ)
Parametres est une chaîne
Attribut est un entier = tPRINTER[1]:Attributes
Priority est un entier = tPRINTER[1]:Priority
DefaultPriority est un entier = tPRINTER[1]:DefaultPriority
StartTime est un entier = tPRINTER[1]:StartTime
UntilTime est un entier = tPRINTER[1]:UntilTime
Status est un entier= tPRINTER[1]:Status
cJobs est un entier = tPRINTER[1]:cJobs
AveragePPM est un entier = tPRINTER[1]:AveragePPM

//* Concatenation des informations
Resultat est une chaîne = ""
Resultat += ServeurName + TAB // 01
Resultat += PrinterName + TAB // 02
Resultat += ShareName + TAB // 03
Resultat += PortName + TAB // 04
Resultat += DriverName + TAB // 05
Resultat += Comment + TAB // 06
Resultat += Location + TAB // 07
Resultat += DevMode + TAB // 08
Resultat += SepFile + TAB // 09
Resultat += PrintProcessor + TAB // 10
Resultat += sDatatype + TAB // 11
Resultat += Parametres + TAB // 12
Resultat += NumériqueVersChaine(Attribut) + TAB // 13
Resultat += NumériqueVersChaine(Priority) + TAB // 14
Resultat += NumériqueVersChaine(DefaultPriority) + TAB // 15
Resultat += NumériqueVersChaine(StartTime) + TAB // 16
Resultat += NumériqueVersChaine(UntilTime) + TAB // 17
Resultat += NumériqueVersChaine(Status) + TAB // 18
Resultat += NumériqueVersChaine(cJobs) + TAB // 19
Resultat += NumériqueVersChaine(AveragePPM) + TAB // 20

// Pour avoir le status faire Val(ExtraitChaine(....,18))
RENVOYER Resultat

// *****************************************************************
// DANS LE CODE D'UN BOUTON
// *****************************************************************
InfoPrinter est une chaîne = iPrinterGetStatus()
IF InfoPrinter <> "" THEN
Status est un entier = Val(ExtraitChaîne(InfoPrinter,18))
END

// *****************************************************************
// RESULTAT DES TEST
// *****************************************************************
- Imprimante réseaux prête mais dont le toner est bas 0x20000
(PRINTER_STATUS_TONER_LOW) --> OK
- Imprimante locale absente mais dont le spool est en pause 0x1
(PRINTER_STATUS_PAUSED) --> OK
- Imprimante réseaux en bourage papier 0x8
(PRINTER_STATUS_PAPER_JAM) --> OK

Voila voila...


"Graviere Julien" <gravierejulien@yahoo.fr> a écrit dans le message de news:
44f57c3b$1@news.pcsoft.fr...

Plus personne pour mon problème?
Pascal?

Posté le 30 août 2006 - 22:23
D'aprés ce que j'ai compris la fonction rempli une zone mémoire avec les
valeurs pour 1 seule tSTATUS (taille fixe) puis par avec une zone de type
buffer binaire (taille variable)
En windev on ne peut pas déclarer ce type de donnée qui est un peut batarde
à mon goût

Exemple
_point est une structure
x est un entier
y est un entier
end

si tu fais :
point est un point

tu auras en mémoire
1 octet de x
2 octet de x
3 octet de x
4 octet de x // car un entier avec Windev est sur 4 octets
5 octet de y
6 octet de y
7 octet de y
8 octet de y // car un entier avec Windev est sur 4 octets

Si tu fais :
tblpoint est un tableau de 100 point
tu auras en memoire 100 fois de suite le shémas de dessus 100*8 octets

Mais rien ne t'empêche ( et µ$soft ne se géne pas) d'y mette autre chose car
ce n'est que des octets !
les deux * 4 premiers octets étant des adresses de zone mémoire pointant
dans les (100-2)*8 octets suivants qui eut ne sont absolument pas structuré
comme des tSTATUS.
Voila l'explication du tSTATUS[1] car c'est le seul d'utile

Si tu veux voir exactement comment cela se passe tu fais
phPrinter est un entier
RetCode est un entier
BufferBin est une chaîne fixe sur 5000
pcbNeeded est un entier
IF API( "winspool.drv" ,"OpenPrinterA", "\\BROSRV002\BROPRT219", &phPrinter,
Null) <> 0 ALORS
RetCode = API("winspool.drv", "GetPrinterA", phPrinter, 2, Null,
0,&pcbNeeded)
RetCode = API("winspool.drv", "GetPrinterA", phPrinter, 2, &BufferBin,
pcbNeeded, &pcbNeeded)
STOP
// ICI AVEC LE DEBOGUEUR, inspecter la variable : Remplace(BufferBin[[1
sur pcbNeeded]], Caract(0x0),".")
// et tu vas entre guillemet comprendre.... le début du buffer est
organisé celon la structure tSTATUS qui contient
// des adresse sur des zones contenus aprés la structure.
API("winspool.drv", "ClosePrinter", phPrinter)
END



"Graviere Julien" <gravierejulien@yahoo.fr> a écrit dans le message de news:
44f3e771$1@news.pcsoft.fr...

Ce message à l'attention de Philippe Pasquali ou tout autre developpeur
ayant eu besoin du code ci-après :

Suite au code posté sur le Forum le 15/06/2005, je tente d'obtenir le
statut de mon imprimante et cela ne fonctionne pas : même quand
l'imprimante est en erreur, le code me renvoie 0 (tout est ok).
Je ne comprends pas cette ligne :
Etat = tSTATUS[1]:status //Pourquoi un indice de 1?
//Pourquoi ce n'est pas dynamique
//Puis je avoir plus d'explication?



x_PRINTER_INFO_2 est une structure
pServerName est un entier
pPrinterName est un entier
pShareName est un entier
pPortName est un entier
pDriverName est un entier
pComment est un entier
pLocation est un entier
pDevMode est un entier
pSepFile est un entier
pPrintProcessor est un entier
pDatatype est un entier
pParameters est un entier
pSecurityDescriptor est un entier
Attributes est un entier
Priority est un entier
DefaultPriority est un entier
StartTime est un entier
UntilTime est un entier
Status est un entier
cJobs est un entier
AveragePPM est un entier
END
-----------------------------------------------------------------------------------------------
pPrinterName est une chaîne ASCIIZ sur 256 = pPrinter
phPrinter est un entier = 0
pcbNeeded est un entier = 0
RetCode est un entier
tSTATUS est un tableau dynamique de 100 x_PRINTER_INFO_2
Buf est une chaîne ASCIIZ sur 2048
Etat est un entier = 0
Req est une chaîne
InfoErreur est une chaîne
-------------------------------------------------------------------------------------------
SI API( "winspool.drv" ,"OpenPrinterA", pPrinterName, &phPrinter, Null) <>
0 ALORS
RetCode = API("winspool.drv", "GetPrinterA", phPrinter, 2, &tSTATUS,
0,&pcbNeeded)
RetCode = API("winspool.drv", "GetPrinterA", phPrinter, 2,
&tSTATUS,pcbNeeded, &pcbNeeded)
SI RetCode<>0 ALORS
Etat = tSTATUS[1]:status
FIN
API("winspool.drv", "ClosePrinter", phPrinter)
FIN
Posté le 01 décembre 2010 - 23:51
Bonjour,
Je remonte se post , car comme il est dit, moi aussi j'ai toujours status 0 que l'imprimante soit On, off, connecté etc ..
Dans mon cas c'est une imprimante réseau (partagée sur un autre poste)

L'idée et de savoir si l'imprimante est prete, cad le PC de l'imprimante est allumé, l'imprimante est connecté et en marche , voir la connexion réseau fonctionne pour accéder à l'imprimante.

Si quelqu'un a trouvé la solution , je suis preneur...
Posté le 02 décembre 2010 - 11:06
bonjour Marco,

Si l'utilisation de dotnet n'est pas un obstacle voici une autre méthode pour récupérer des infos imprimante avec Windev :
En utilisant WMI avec assemblage DotNet
Pour utiliser cela dans votre projet il vous faut :
1 - Utiliser l'assemblage .NET "System.Management" :
Menu Atelier/.NET/Utiliser Un Assemblage .NET dans ce projet
Dans la fenêtre qui s'ouvre cliquer sur "Lister les assemblages référencés"
Quand la recherche est terminée cocher "Mscorlib" et "System.Management"
2 - Récupérer la collection de procédure pWMI.wdg qui se trouve dans l'exemple complet WD WMI DOTNET et l'inclure dans votre projet
Rajouter la procédure suivante dans votre collection pWMI.wdg
// Syntaxe :
//[ <Résultat> = ] RécupèreInfoImprimante ()
//
// Ecrit par Jurassic Pork le 20/05/2010
// Cette procédure permet de récupérer les infos d'Etat sur les imprimantes
// Paramètres :
// Aucun
// Valeur de retour :
// chaîne : Nom de l'imprimante + RC + Status de l'imprimante + RC + mode de connexion de l'imprimante

Procedure RécupèreInfoImprimante()

sChaineRetour est une chaîne
sListeInfo est une chaîne
sUneInformation est une chaîne

// Récupération de toutes les informations sur les imprimantes
sListeInfo = RécupèreContenu("win32_Printer",gsServeur + "root\CIMV2")

POUR TOUTE CHAINE sUneInformation DE sListeInfo SEPAREE PAR RC+RC

// Récupération des informations
sChaineRetour += "Imprimante : " + TrouveInformation(sUneInformation,"Caption") + RC +...
// Récupération du status
// Valeur Signification
// 1 (0x1) Other
// 2 (0x2) Unknown
// 3 (0x3) Idle
// 4 (0x4) Printing
// 5 (0x5) Warming Up
// 6 (0x6) Stopped printing
// 7 (0x7) Offline
// Attention cette info peut être fausse si WorkOffLine = 1 ( mode Hors connexion)
"Status : " + TrouveInformation(sUneInformation,"PrinterStatus") + RC +...
// Récupération du mode Hors connexion = 1 Connecté = 0
"WorkOffLine : " + TrouveInformation(sUneInformation,"WorkOffLine") + RC +...
"=====================================================" + RC
FIN

RENVOYER sChaineRetour


La procédure décrite précédemment n'est qu'un exempkle et elle est bien sur adaptable suivant ses besoins. D'autres infos sont disponibles dans win32_Printer. L'information qui t'intéresse est la propriété WorkOffLine pour une imprimante réseau.

Ami calmant, J.P ;-)
Posté le 02 décembre 2010 - 12:26
Bonjour, Merci pour la réponse,
J'avais déjà trouvé cet exemple, et je l'ai essayé, (pas très à l'aise avec DOT NET)
mais c'est bien expliqué ;-)
Juste la ligne :

RécupèreContenu("win32_Printer",gsServeur + "root\CIMV2")


je ne vois pas ce qu'est : gsServeur + "root\CIMV2"

mais je l'ai remplacé par une chaine vide et cela fonctionne !
Il m'affiche toutes les imprimantes du poste

Le problème pour mon imprimante partagée ( elle est en USB sur un autre poste et partagée )

Si elle est allumée, le poste allumé , et la connexion réseau OK
j'ai le status 3 (0x3) Idle

Si je l'éteint j'ai aussi le status 3 (0x3) Idle
alors que dans le panneau de config de Windows , il affiche bien "Etat : hors connexion"

et à propos de : gsServeur + "root\CIMV2"
est il possible de demande l'etat d'une imprimante précise ?
car avec une chaine vide, et 9 imprimantes installées sur les poste ( imprimante virtuelle compris ) cela prend un peu de temps ?

l'idée et que les client arrête de remplir le spool avec 50 documents et attendent ce moment pour me dire que l'impression ne marche plus !
Vous connaissez la suite, il faut arrêter le service, vider le spool, redémarrer le service, leurs dire que comme "les dernières fois" qu'il pensent à vérifier que l'imprimante est en ligne, et bien sur leurs expliquer pour la n ieme fois que ce n'est pas la faute du logiciel... même si ils nous croient pas ;-) mais on a la l'habitude ...


Merci, et bon dev
Posté le 02 décembre 2010 - 13:50
Je me répond moi même, cela pourra aider quelqu'un d'autre.

Jurassic Pork , je me suis permis de modifier ton code, mais je rend à César etc...
Il faut en faite combiner Status et WorkOffLine.

Code du bouton
sNomImprimante est une chaîne
sResultat est une chaîne
sNomImprimante =Remplace( iInfoImprimante(),"\","\\")

sResultat = RécupèreInfoImprimante(sNomImprimante)
SI sResultat <> "OK" ALORS
Erreur(sResultat)
RETOUR
FIN


puis procedure
Procedure RécupèreInfoImprimante(NomImprimante)

sChaineRetour est une chaîne
sListeInfo est une chaîne
sUneInformation est une chaîne
bImprimanteReseau est un booléen
nStatusest un entier
bWorkOfflineest un booléen
sMonPC est une chaîne ="\\"+NetNomMachine()+"\"

sListeInfo = RécupèreContenu("win32_Printer",sMonPC + "root\CIMV2","name = '"+sNomImprimante+"'")
sUneInformation = ExtraitChaîne(sListeInfo,1,RC+RC)

// Récupération des informations
// Imprimante réseau ?
bImprimanteReseau = Val(TrouveInformation(sUneInformation,"Network"))
// Recherche le status
nStatus = Val(TrouveInformation(sUneInformation,"PrinterStatus"))
bWorkOffline= Val(TrouveInformation(sUneInformation,"WorkOffline"))

SELON nStatus
CAS 1// Other
sChaineRetour ="Vérifiez que votre imprimante est bien allumée et connectée et qu'elle n'est pas en 'Pause'"+RC+"Impression abandonnée"
CAS 2// Unknown
sChaineRetour ="Vérifiez que votre imprimante est bien allumée et connectée"+RC+"Impression abandonnée"
CAS 3// Idle
SI bImprimanteReseau ALORS
SI bWorkOffline ALORS
sChaineRetour ="Vérifiez que votre imprimante est bien allumée et connectée"+RC+"Impression abandonnée"
SINON
sChaineRetour ="OK"
FIN
SINON
sChaineRetour ="OK"
FIN
CAS 4// Printing
sChaineRetour ="OK"
CAS 5// Warming Up
sChaineRetour ="OK"
CAS 6// Stopped printing
sChaineRetour ="Vérifiez que l'imprimante n'est pas en pause"+RC+"Impression abandonnée"
CAS 7// Offline
sChaineRetour ="Vérifiez que votre imprimante est bien allumée et connectée"+RC+"Impression abandonnée"
FIN

RENVOYER sChaineRetour

il y a sans doute encore des améliorations à faire... mais pour ce que je désirais cela me suffit.

quant aux autres informations sur l'imprimante , elle sont ici :
http://msdn.microsoft.com/en-us/library/aa394363.aspx

Merci encore pour le coup de main et bon dev à tous
Posté le 02 décembre 2010 - 15:14
Bon ben moi de mon côté j'ai trouvé le moyen de faire du WMI sans dotNet.
Ça consiste à "Ecrire" et exécuter le code VBScript dans une application WinDev, grâce au composant ActiveX ScriptControl (installé automatiquement avec Windows). Merci à JBO sur un autre Forum.
Voici un exemple d'utilisation pour les imprimantes :
sList est une chaîne
oScript est un objet automation "MSScriptControl.ScriptControl"
RequeteWMI est une chaîne
// chaine qui représente le code VBSCRIPT
sScriptVBS est une chaîne = [

Function ScanImprimantes()
Dim objWMIService, colImprimantes, objImprimante, sInfo

Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colImprimantes = objWMIService.ExecQuery("LaRequêteWMI")

sInfo = ""
For Each objImprimante In colImprimantes
If sInfo <> "" Then sInfo = sInfo & Chr(13) & Chr(10)
// ici il faut mettre les champs que l'on recherche
// dans cet exemple le séparateur de champ est |
sInfo = sInfo & objImprimante.Caption
sInfo = sInfo & "|" & objImprimante.PrinterStatus
sInfo = sInfo & "|" & objImprimante.WorkOffLine
Next

ScanImprimantes = sInfo
End Function
]
// en commentaire une requête pour rechercher que l'imprimante qui contient PIXMA dans son nom
// RequeteWMI = "SELECT Caption,PrinterStatus,WorkOffLine FROM Win32_Printer WHERE Caption LIKE '%PIXMA%'"
RequeteWMI = "SELECT Caption,PrinterStatus,WorkOffLine FROM Win32_Printer"
// on remplace dans le script le mot clé LaRequêteWMI par la requête WMI
sScriptVBS= Remplace(sScriptVBS,"LaRequêteWMI",RequeteWMI)

oScript>>Language("VBScript")
oScript>>AddCode(sScriptVBS)
oScript>>Timeout(-1)//pas de timeout
sList = oScript>>Run("ScanImprimantes") //Appel
// le resultat est dans sList


Ami calmant, J.P ;-)
Membre enregistré
7 messages
Posté le 03 juin 2015 - 09:48
Bonjour messieurs !

Je me permet de déterrer ce sujet car il m’intéresse grandement. J'ai relu le fil et me rend compte que dans le code fourni par Marco ou Jurasic Pork, la fonction "TrouveInformation" n'est pas fournie.

Alors certes je pourrai la recoder en fonction de la documentation MSDN mais j'avoue préférer récupérer celle qui a déjà été faite en partant du principe qu'elle est déjà fonctionnelle.

En outre j'ai tenté de me servir de la solution de Jurrasic Pork pour faire usage du WMI sans DotNet mais le résultat est assez... perturbant... J'ai repris le code et ai tenté une éxécution basique avant de personnaliser la requête pour une imprimante en particulier (car oui c'est de cela dont il est question) et à l'éxecution de la liste "oScript>>AddCode(sScriptVBS)", j'obtient l'erreur suivante :

Appel WL :
Traitement de 'Clic sur BTN_TestImprimantes' (Fen_Test_Fenêtre.BTN_TestImprimantes), ligne 34, thread 0

Que s'est-il passé ?
Vous avez appelé la méthode Automation 'AddCode'.
En tentant d'invoquer la méthode <AddCode> ou de lire la propriété <AddCode>, l'objet Automation/ActiveX a renvoyé l'erreur suivante :
'Erreur 800A0400 : Instruction attendue'
En tentant d'invoquer la méthode <AddCode>, l'objet Automation/ActiveX a renvoyé l'erreur suivante :
'Erreur 800A0400 : Instruction attendue'
En tentant de lire la propriété <AddCode>, l'objet Automation/ActiveX a renvoyé l'erreur suivante :
'Erreur 80020003, Le membre demandé n'existe pas'
En tentant d'écrire la propriété <AddCode>, l'objet Automation/ActiveX a renvoyé l'erreur suivante :
'Erreur 80020003, Le membre demandé n'existe pas'

Vous me direz que la réponse se trouve très certainement dans la documentation MSScriptControl.ScriptControl, documentation que j'ai consultée... mais bien évidement ca me dit que la méthode "AddCode" existe bel et bien :-/ Je tourne un peu en rond la...

Doc MSScriptControl : https://msdn.microsoft.com/en-us/library/aa227637(v=vs.60).aspx

En vous remerciant par avance !
Membre enregistré
7 messages
Posté le 03 juin 2015 - 10:06
[EDIT]

Bon... mea culpa... en farfouillant un peu plus que je ne l'avais déjà fait, j'ai trouvé la provenance des fonctions "TrouveInformation" et "RécupèreContenu", je vais les essayer :merci:

[/EDIT]

Ceci étant je tourne toujours en rond pour le Script
Membre enregistré
7 messages
Posté le 03 juin 2015 - 11:05
[EDIT 2]

J'ai réussi à faire fonctionner le Script VB de Jurassic Pork, finalement ! Cela relève de l'erreur idiote et du manque de pratique de VB je l'avoue :)

Le problème se situait dans les commentaires mis par ce dernier dans le Script... LEs commentaires VB tant délimités par une apostrophe et non "//", cela provoquait une erreur...

[/EDIT 2]

Donc pour information, le code fourni par Jurassic Pork fonctionnel est :

sList est une chaîne
oScript est un objet automation "MSScriptControl.ScriptControl"
RequeteWMI est une chaîne
// chaine qui représente le code VBSCRIPT
sScriptVBS est une chaîne = [

Function ScanImprimantes()
Dim objWMIService, colImprimantes, objImprimante, sInfo

Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colImprimantes = objWMIService.ExecQuery("LaRequêteWMI")

sInfo = ""
For Each objImprimante In colImprimantes
If sInfo <> "" Then sInfo = sInfo & Chr(13) & Chr(10)
' ici il faut mettre les champs que l'on recherche
' dans cet exemple le séparateur de champ est |
sInfo = sInfo & objImprimante.Caption
sInfo = sInfo & "|" & objImprimante.PrinterStatus
sInfo = sInfo & "|" & objImprimante.WorkOffLine
Next

ScanImprimantes = sInfo
End Function
]
// en commentaire une requête pour rechercher que l'imprimante qui contient PIXMA dans son nom
// RequeteWMI = "SELECT Caption,PrinterStatus,WorkOffLine FROM Win32_Printer WHERE Caption LIKE '%PIXMA%'"
RequeteWMI = "SELECT Caption,PrinterStatus,WorkOffLine FROM Win32_Printer"
// on remplace dans le script le mot clé LaRequêteWMI par la requête WMI
sScriptVBS= Remplace(sScriptVBS,"LaRequêteWMI",RequeteWMI)

oScript>>Language("VBScript")
oScript>>AddCode(sScriptVBS)
oScript>>Timeout(-1)//pas de timeout
sList = oScript>>Run("ScanImprimantes") //Appel
// le resultat est dans sList


Quant au code fourni plus haut, je me permet de préciser une chose importante pour le faire fonctionner (comme elle était déja précisée dans le tuto d'un autre forum). Pour que celui ci soit fonctionnel il faut :
1) Ajouter l'utilisation d'un assemblage .NET à votre projet appelé "System.Management" (Menu Atelier -> .NET -> Assemblages utilisés dans le projet -> cocher System.Management"
2) Importer la collection de procédures "pWMI" présente dans l'exemple Windev fourni appelé "WD WMI DOTNET" qui se situe dans le répertoire de WinDev (%%RepWindev%%\Exemples\Exemples\Exemples complets\WD WMI DOTNET\pWMI.wdg)

Voila, j'espère avoir pu aider ceux qui repasseront par ici!

Pour information ces codes sont fonctionnels sous Windev18 avec un Windows 8.1 64 bits

Bon dév à tous !
Membre enregistré
7 messages
Posté le 03 juin 2015 - 15:49
Bon, je reviens à la charge avec les imprimantes et toutes les informations que l'on peut tirer de la classe Win32_Printer.

J'ai donc remis les mains dans le VBS pour réussir à implémenter gentiment plus de fonctionnalités dans la solution fournies par Jurassic Pork car je la préfère à la première tout simplement parceque j'aime contrôler toutes les étapes de mon code et cela me semble plus être le cas avec celle la. Bref, je vous présente le code que j'utilise maintenant :

v_chn_List est une chaîne
v_obj_Script est un objet automation "MSScriptControl.ScriptControl"
v_chn_RequeteWMI est une chaîne
v_chn_ScriptVBS est une chaîne

// chaine qui représente le code VBSCRIPT
v_chn_ScriptVBS = [

FUNCTION ExplodeTab(MyTab,Title)

Dim sResult
Dim i

sResult = Chr(13) & Chr(10) & Title & " : "

IF IsArray(varTest) THEN
IF varTest = Null THEN
sResult = sResult & "None (null array)"
ELSE
IF MyTab.EOF AND MyTab.BOF THEN
sResult = sResult & "None (empty array)"
ELSE
FOR i = 0 TO (UBound(MyTab)-1)
'Si l'élement i Contient qqch
IF LenB(MyTab(i)) > 0 THEN
' On l'Ajoute A LA chaîne
sResult = sResult & Chr(13) & Chr(10) & " - " & MyTab(i)
END IF
Next
END IF
END IF
ELSE
sResult = sResult & "None (invalid array - VarType : " & vartype(varTest) & ")"
END IF

ExplodeTab = sResult

END FUNCTION

FUNCTION ScanImprimantes()
Dim objWMIService, colImprimantes, objImprimante, sInfo

Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colImprimantes = objWMIService.ExecQuery("LaRequêteWMI")

sInfo = ""
FOR EACH objImprimante IN colImprimantes

IF sInfo <> "" THEN
sInfo = sInfo & Chr(13) & Chr(10)
END IF

'Ici il faut mettre les champs que l'on recherche
' POUR avoir toutes les possibilités => https://msdn.microsoft.com/en-us/library/aa394363%28v=vs.85%29.aspx
' Si le lien est corrompu ou n'est plus valable, rechercher "Win32_Printer class" DANS google
sInfo = sInfo & Chr(13) & Chr(10) & "---------------------------------------"
sInfo = sInfo & Chr(13) & Chr(10) & "Attributes : " & objImprimante.Attributes
sInfo = sInfo & Chr(13) & Chr(10) & "Availability : " & objImprimante.Availability
'sInfo = sInfo & ExplodeTab(objImprimante.AvailableJobSheets,"AvailableJobSheets")
sInfo = sInfo & Chr(13) & Chr(10) & "AvailableJobSheets : " & objImprimante.AvailableJobSheets
sInfo = sInfo & Chr(13) & Chr(10) & "AveragePagesPerMinute : " & objImprimante.AveragePagesPerMinute
sInfo = sInfo & ExplodeTab(objImprimante.Capabilities,"Capabilities")
sInfo = sInfo & ExplodeTab(objImprimante.CapabilityDescriptions,"CapabilityDescriptions")
sInfo = sInfo & Chr(13) & Chr(10) & "Caption : " & objImprimante.Caption
sInfo = sInfo & ExplodeTab(objImprimante.CharSetsSupported,"CharSetsSupported")
sInfo = sInfo & Chr(13) & Chr(10) & "Comment : " & objImprimante.Comment
sInfo = sInfo & Chr(13) & Chr(10) & "ConfigManagerErrorCode : " & objImprimante.ConfigManagerErrorCode
sInfo = sInfo & Chr(13) & Chr(10) & "ConfigManagerUserConfig : " & objImprimante.ConfigManagerUserConfig
sInfo = sInfo & Chr(13) & Chr(10) & "CreationClassName : " & objImprimante.CreationClassName
sInfo = sInfo & ExplodeTab(objImprimante.CurrentCapabilities,"CurrentCapabilities")
sInfo = sInfo & Chr(13) & Chr(10) & "CurrentCharSet : " & objImprimante.CurrentCharSet
sInfo = sInfo & Chr(13) & Chr(10) & "CurrentLanguage : " & objImprimante.CurrentLanguage
sInfo = sInfo & Chr(13) & Chr(10) & "CurrentMimeType : " & objImprimante.CurrentMimeType
sInfo = sInfo & Chr(13) & Chr(10) & "CurrentNaturalLanguage : " & objImprimante.CurrentNaturalLanguage
sInfo = sInfo & Chr(13) & Chr(10) & "CurrentPaperType : " & objImprimante.CurrentPaperType
sInfo = sInfo & Chr(13) & Chr(10) & "Default : " & objImprimante.Default
sInfo = sInfo & ExplodeTab(objImprimante.DefaultCapabilities,"DefaultCapabilities")
sInfo = sInfo & Chr(13) & Chr(10) & "DefaultCopies : " & objImprimante.DefaultCopies
sInfo = sInfo & Chr(13) & Chr(10) & "DefaultLanguage : " & objImprimante.DefaultLanguage
sInfo = sInfo & Chr(13) & Chr(10) & "DefaultMimeType : " & objImprimante.DefaultMimeType
sInfo = sInfo & Chr(13) & Chr(10) & "DefaultNumberUp : " & objImprimante.DefaultNumberUp
sInfo = sInfo & Chr(13) & Chr(10) & "DefaultPaperType : " & objImprimante.DefaultPaperType
sInfo = sInfo & Chr(13) & Chr(10) & "DefaultPriority : " & objImprimante.DefaultPriority
sInfo = sInfo & Chr(13) & Chr(10) & "Description : " & objImprimante.Description
sInfo = sInfo & Chr(13) & Chr(10) & "DetectedErrorState : " & objImprimante.DetectedErrorState
sInfo = sInfo & Chr(13) & Chr(10) & "DeviceID : " & objImprimante.DeviceID
sInfo = sInfo & Chr(13) & Chr(10) & "Direct : " & objImprimante.Direct
sInfo = sInfo & Chr(13) & Chr(10) & "DoCompleteFirst : " & objImprimante.DoCompleteFirst
sInfo = sInfo & Chr(13) & Chr(10) & "DriverName : " & objImprimante.DriverName
sInfo = sInfo & Chr(13) & Chr(10) & "EnableBIDI : " & objImprimante.EnableBIDI
sInfo = sInfo & Chr(13) & Chr(10) & "EnableDevQueryPrint : " & objImprimante.EnableDevQueryPrint
sInfo = sInfo & Chr(13) & Chr(10) & "ErrorCleared : " & objImprimante.ErrorCleared
sInfo = sInfo & Chr(13) & Chr(10) & "ErrorDescription : " & objImprimante.ErrorDescription
sInfo = sInfo & ExplodeTab(objImprimante.ErrorInformation,"ErrorInformation")
sInfo = sInfo & Chr(13) & Chr(10) & "ExtendedDetectedErrorState : " & objImprimante.ExtendedDetectedErrorState
sInfo = sInfo & Chr(13) & Chr(10) & "ExtendedPrinterStatus : " & objImprimante.ExtendedPrinterStatus
sInfo = sInfo & Chr(13) & Chr(10) & "Hidden : " & objImprimante.Hidden
sInfo = sInfo & Chr(13) & Chr(10) & "HorizontalResolution : " & objImprimante.HorizontalResolution
sInfo = sInfo & Chr(13) & Chr(10) & "InstallDate : " & objImprimante.InstallDate
sInfo = sInfo & Chr(13) & Chr(10) & "JobCountSinceLastReset : " & objImprimante.JobCountSinceLastReset
sInfo = sInfo & Chr(13) & Chr(10) & "KeepPrintedJobs : " & objImprimante.KeepPrintedJobs
sInfo = sInfo & ExplodeTab(objImprimante.LanguagesSupported,"LanguagesSupported")
sInfo = sInfo & Chr(13) & Chr(10) & "LastErrorCode : " & objImprimante.LastErrorCode
sInfo = sInfo & Chr(13) & Chr(10) & "Local : " & objImprimante.LOCAL
sInfo = sInfo & Chr(13) & Chr(10) & "Location : " & objImprimante.Location
sInfo = sInfo & Chr(13) & Chr(10) & "MarkingTechnology : " & objImprimante.MarkingTechnology
sInfo = sInfo & Chr(13) & Chr(10) & "MaxCopies : " & objImprimante.MaxCopies
sInfo = sInfo & Chr(13) & Chr(10) & "MaxNumberUp : " & objImprimante.MaxNumberUp
sInfo = sInfo & Chr(13) & Chr(10) & "MaxSizeSupported : " & objImprimante.MaxSizeSupported
sInfo = sInfo & ExplodeTab(objImprimante.MimeTypesSupported,"MimeTypesSupported")
sInfo = sInfo & Chr(13) & Chr(10) & "Name : " & objImprimante.Name
sInfo = sInfo & ExplodeTab(objImprimante.NaturalLanguagesSupported,"NaturalLanguagesSupported")
sInfo = sInfo & Chr(13) & Chr(10) & "Network : " & objImprimante.Network
sInfo = sInfo & ExplodeTab(objImprimante.PaperSizesSupported,"PaperSizesSupported")
sInfo = sInfo & ExplodeTab(objImprimante.PaperTypesAvailable,"PaperTypesAvailable")
sInfo = sInfo & Chr(13) & Chr(10) & "Parameters : " & objImprimante.Parameters
sInfo = sInfo & Chr(13) & Chr(10) & "PNPDeviceID : " & objImprimante.PNPDeviceID
sInfo = sInfo & Chr(13) & Chr(10) & "PortName : " & objImprimante.PortName
sInfo = sInfo & ExplodeTab(objImprimante.PowerManagementCapabilities,"PowerManagementCapabilities")
sInfo = sInfo & Chr(13) & Chr(10) & "PowerManagementSupported : " & objImprimante.PowerManagementSupported
sInfo = sInfo & ExplodeTab(objImprimante.PrinterPaperNames,"PrinterPaperNames")
sInfo = sInfo & Chr(13) & Chr(10) & "PrinterState : " & objImprimante.PrinterState
sInfo = sInfo & Chr(13) & Chr(10) & "PrinterStatus : " & objImprimante.PrinterStatus
sInfo = sInfo & Chr(13) & Chr(10) & "PrintJobDataType : " & objImprimante.PrintJobDataType
sInfo = sInfo & Chr(13) & Chr(10) & "PrintProcessor : " & objImprimante.PrintProcessor
sInfo = sInfo & Chr(13) & Chr(10) & "Priority : " & objImprimante.Priority
sInfo = sInfo & Chr(13) & Chr(10) & "Published : " & objImprimante.Published
sInfo = sInfo & Chr(13) & Chr(10) & "Queued : " & objImprimante.Queued
sInfo = sInfo & Chr(13) & Chr(10) & "RawOnly : " & objImprimante.RawOnly
sInfo = sInfo & Chr(13) & Chr(10) & "SeparatorFile : " & objImprimante.SeparatorFile
sInfo = sInfo & Chr(13) & Chr(10) & "ServerName : " & objImprimante.ServerName
sInfo = sInfo & Chr(13) & Chr(10) & "Shared : " & objImprimante.Shared
sInfo = sInfo & Chr(13) & Chr(10) & "ShareName : " & objImprimante.ShareName
sInfo = sInfo & Chr(13) & Chr(10) & "SpoolEnabled : " & objImprimante.SpoolEnabled
sInfo = sInfo & Chr(13) & Chr(10) & "StartTime : " & objImprimante.StartTime
sInfo = sInfo & Chr(13) & Chr(10) & "Status : " & objImprimante.Status
sInfo = sInfo & Chr(13) & Chr(10) & "StatusInfo : " & objImprimante.StatusInfo
sInfo = sInfo & Chr(13) & Chr(10) & "SystemCreationClassName : " & objImprimante.SystemCreationClassName
sInfo = sInfo & Chr(13) & Chr(10) & "SystemName : " & objImprimante.SystemName
sInfo = sInfo & Chr(13) & Chr(10) & "TimeOfLastReset : " & objImprimante.TimeOfLastReset
sInfo = sInfo & Chr(13) & Chr(10) & "UntilTime : " & objImprimante.UntilTime
sInfo = sInfo & Chr(13) & Chr(10) & "VerticalResolution : " & objImprimante.VerticalResolution
sInfo = sInfo & Chr(13) & Chr(10) & "WorkOffline : " & objImprimante.WorkOffline
sInfo = sInfo & Chr(13) & Chr(10) & "---------------------------------------"

Next

ScanImprimantes = sInfo
END FUNCTION

]

// Rechercher que l'imprimante dont le nom commence par "Toshiba" et fini par "4610"
v_chn_RequeteWMI = "SELECT * FROM Win32_Printer WHERE Caption like 'Toshiba%' AND Caption like '%4610'"
// on remplace dans le script le mot clé LaRequêteWMI par la requête WMI
v_chn_ScriptVBS= Remplace(v_chn_ScriptVBS,"LaRequêteWMI",v_chn_RequeteWMI)

v_obj_Script>>Language("VBScript")

QUAND EXCEPTION DANS
v_obj_Script>>AddCode(v_chn_ScriptVBS)
FAIRE
Erreur(ExceptionInfo(errComplet))
RETOUR
FIN

v_obj_Script>>Timeout(-1)//pas de timeout

v_chn_List = v_obj_Script>>Run("ScanImprimantes") //Appel

POUR TOUTE CHAINE chn_Ligne DE v_chn_List SEPAREE PAR RC
Trace(chn_Ligne)
FIN


Comme vous pouvez le voir, je liste toutes les propriétés possibles de l'imprimante trouvées (d'ou la longueur du code). J'ai aussi agrémenté le code VBS d'une fonction "ExplodeTab(MyTab,Title)" qui à pour but de renvoyer le contenu de chaque occurrence d'un tableau passé en paramètre sous forme de chaine.

Ceci étant, je pêche sur un détail...
Dans la fonction ScanImprimantes(), on peut voir des lignes du style

"sInfo = sInfo & ExplodeTab( ... "

Ces lignes ont pour but de lire le contenu de tableaux renvoyés par la classe Win32_Printer, je pense que vous l'aurez deviné ! Le problème étant qu'a priori, chacun des tableaux dont je souhaite extraire le contenu est invalide. Et pour aller plus loin, il n'est même pas invalide mais "null" comem le dit le résultat de ma trace :


---------------------------------------
Attributes : 2120
Availability :
AvailableJobSheets :
AveragePagesPerMinute : 0
Capabilities : None (invalid array - VarType : 0)
CapabilityDescriptions : None (invalid array - VarType : 0)
Caption : Toshiba 4610a
CharSetsSupported : None (invalid array - VarType : 0)
Comment :
ConfigManagerErrorCode :
ConfigManagerUserConfig :
CreationClassName : Win32_Printer
CurrentCapabilities : None (invalid array - VarType : 0)
CurrentCharSet :
CurrentLanguage :
CurrentMimeType :
CurrentNaturalLanguage :
CurrentPaperType :
Default : Faux
DefaultCapabilities : None (invalid array - VarType : 0)
DefaultCopies :
DefaultLanguage :
DefaultMimeType :
DefaultNumberUp :
DefaultPaperType :
DefaultPriority : 0
Description :
DetectedErrorState : 0
DeviceID : Toshiba 4610a
Direct : Faux
DoCompleteFirst : Faux
DriverName : Toshiba 4610
EnableBIDI : Vrai
EnableDevQueryPrint : Faux
ErrorCleared :
ErrorDescription :
ErrorInformation : None (invalid array - VarType : 0)
ExtendedDetectedErrorState : 0
ExtendedPrinterStatus : 2
Hidden : Faux
HorizontalResolution : 150
InstallDate :
JobCountSinceLastReset : 0
KeepPrintedJobs : Faux
LanguagesSupported : None (invalid array - VarType : 0)
LastErrorCode :
Local : Vrai
Location :
MarkingTechnology :
MaxCopies :
MaxNumberUp :
MaxSizeSupported :
MimeTypesSupported : None (invalid array - VarType : 0)
Name : Toshiba 4610a
NaturalLanguagesSupported : None (invalid array - VarType : 0)
Network : Faux
PaperSizesSupported : None (invalid array - VarType : 0)
PaperTypesAvailable : None (invalid array - VarType : 0)
Parameters :
PNPDeviceID :
PortName : Toshiba: 0_USB
PowerManagementCapabilities : None (invalid array - VarType : 0)
PowerManagementSupported :
PrinterPaperNames : None (invalid array - VarType : 0)
PrinterState : 0
PrinterStatus : 3
PrintJobDataType : RAW
PrintProcessor : winprint
Priority : 1
Published : Faux
Queued : Faux
RawOnly : Faux
SeparatorFile :
ServerName :
Shared : Vrai
ShareName : IBM 4610
SpoolEnabled : Vrai
StartTime :
Status : Unknown
StatusInfo :
SystemCreationClassName : Win32_ComputerSystem
SystemName : ABRIGNON
TimeOfLastReset :
UntilTime :
VerticalResolution : 150
WorkOffline : Faux
---------------------------------------

Ma question est la suivante : est-ce normal ? Ou est-ce moi qui ai mal codé une des parties de tout ca ?
Membre enregistré
874 messages
Popularité : +11 (11 votes)
Posté le 02 mai 2016 - 18:17
Pour suivre la trace de l'imprimante

--
Bertin CARRIERE
Consultant & Formateur
bertin.carriere@gmail.com
http://www.zen-project.be http://www.linkedin.com/in/bertincarriere

Belgique +32(0)2/318.02.67
France +33(0)3/66.722.542
Espagne +34.5/12.702.266

Membre de http://www.be-dev.be
Membre enregistré
2 949 messages
Popularité : +89 (91 votes)
Posté le 03 mai 2016 - 21:01
ABOUT IT

http://forum.pcsoft.fr/fr-FR/pcsoft.br.windev/1200-trabalhando-com-registro-windows-ter-lista-impressoras-impressora-1215/read.awp

:merci:

--
Adriano José Boller
______________________________________________
Consultor e Representante Oficial da
PcSoft no Brasil
+55 (41) 9949 1800
adrianoboller@gmail.com
skype: adrianoboller
http://wxinformatica.com.br/
Membre enregistré
221 messages
Popularité : +3 (3 votes)
Posté le 02 septembre 2016 - 20:20
Arno_INOVAXO a écrit :
...
Ceci étant, je pêche sur un détail...
Dans la fonction ScanImprimantes(), on peut voir des lignes du style

"sInfo = sInfo & ExplodeTab( ... "

Ces lignes ont pour but de lire le contenu de tableaux renvoyés par la classe Win32_Printer, je pense que vous l'aurez deviné ! Le problème étant qu'a priori, chacun des tableaux dont je souhaite extraire le contenu est invalide. Et pour aller plus loin, il n'est même pas invalide mais "null"
Ma question est la suivante : est-ce normal ? Ou est-ce moi qui ai mal codé une des parties de tout ca ?



Salut Arno,

Voici un code qui fonctionne impec pour ta Fonction ExplodeTab, et qui en plus est plus simple :

v_chn_ScriptVBS = [
FUNCTION ExplodeTab(MyTab,Title)

Dim sResult
sResult = Chr(13) & Chr(10) & Title & " : "

IF IsArray(MyTab) THEN
Dim res, i
for each i in MyTab
IF res = "" THEN
res = i
ELSE
res = res & " - " & i
END IF
next
IF res = "" THEN
sResult = sResult & "None (null array) "
ELSE
sResult = sResult & res
END IF
ELSE
sResult = sResult & "None (invalid array - VarType : " & vartype(MyTab) & ")"
END IF

ExplodeTab = sResult

END FUNCTION

' La suite du script est inchangée
]


Pour info, si la fonction d'origine ne marchait pas chez toi c'est que tu t'étais planté sur des noms de variable (inversion entre MyTab et varTest sortie de nulle part). Mais malgré que j'ai corrigé ces coquilles dans ton code d'origine, je n'ai pas réussi à le faire fonctionner. La méthode UBound(MyTab) plante inlassablement, de même que MyTab.EOF. Je ne comprends pas non plus pourquoi. En VB ça devrait marcher. Peut-être qu'en VBS il y a quelques subtilités qu'on ignore...

En tout cas avec ma correction ci-dessus, plus de problème. Et ça m'arrange bien, car si la procédure en DotNet fonctionne impeccable chez moi, elle me retourne des erreurs chez un client sous Windows Serveur 2008.

Merci à tous pour votre aide.

Marc.
Membre enregistré
717 messages
Popularité : +13 (13 votes)
Posté le 03 septembre 2016 - 09:05
hello,
pour faire du WMI avec WINDEV il existe aussi l'objet automation WbemScripting.SWbemLocator . Attention à cause de l'utilisation de ItemIndex cet objet présent de base dans toutes les versions Windows n'est utilisable entièrement qu'à partir de Vista ( donc pas sur XP).
Voici un exemple de code qui correspond à ce que fait notre ami Arno pour les premières propriétés d'imprimante :
// J.P Septembre 2016
objLocator est un objet automation "WbemScripting.SWbemLocator"
objService est un objet automation dynamique
Resultats est un objet automation dynamique
Propriétés est un objet automation dynamique

QUAND EXCEPTION DANS
objService = objLocator>>ConnectServer(".", "root\cimv2")
objService>>Security_>>ImpersonationLevel = 3

// Récupération des propriétés de l'imprimante HP
Resultats = objService>>ExecQuery("SELECT * FROM Win32_Printer WHERE Caption like 'HP%' ")
POUR x = 0 _A_ Resultats>>Count -1
Propriétés = Resultats>>ItemIndex(x)>>Properties_
Trace("Attributes : ",Propriétés>>Item("Attributes")>>Value )
Trace("Availability : " ,Propriétés>>Item("Availability")>>Value)
Trace("AvailableJobSheets : " ,Propriétés>>Item("AvailableJobSheets")>>Value)
Trace("AveragePagesPerMinute : " ,Propriétés>>Item("AveragePagesPerMinute")>>Value)
Trace("Capabilities : " ,ConcatèneTableau(Propriétés>>Item("Capabilities")>>Value))
Trace("CapabilityDescriptions : " ,ConcatèneTableau(Propriétés>>Item("CapabilityDescriptions")>>Value))
Trace("Caption : ",Propriétés>>Item("Caption")>>Value )
Trace("CharSetsSupported : " ,ConcatèneTableau(Propriétés>>Item("CharSetsSupported")>>Value))
Trace("Comment : " ,ConcatèneTableau(Propriétés>>Item("Comment")>>Value))
Trace("=========================")
FIN
FAIRE
Erreur("Erreur execution WMI",ExceptionInfo())
ExceptionActive()
FIN


avec la fonction ConcatèneTableau :
Procedure ConcatèneTableau(MonTableau)
ChaineResultat est une chaîne = ""
SI MonTableau <> Null ALORS
POUR TOUT elem DE MonTableau
ChaineResultat = ChaineResultat + elem + "|"
FIN
SI Droite(ChaineResultat,1) = "|" ALORS ChaineResultat = Gauche(ChaineResultat,Taille(ChaineResultat) - 1)
FIN
RENVOYER ChaineResultat


la fonction concatèneTableau sert quand le WMI renvoie un tableau. Elle le présente sous forme de chaîne avec les éléments du tableau séparés par un "|". Un peu la fonctionnalité de ExplodeTab.

Voici le résultat de l'exécution du code chez moi :





Ami calmant, J.P

--
Ami calmant, J.P