🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: be.comp.programming
5 messages
5 total messages Started by SLE Wed, 03 Sep 2003 14:55
VB.NET & EnumJobs()
#4260
Author: SLE
Date: Wed, 03 Sep 2003 14:55
12 lines
1369 bytes
Heeft er iemand een werkend stukje VB.NET code om JOB_INFO_2 informatie via
EnjumJobs() uit een printerqueue te lezen? Ik probeer Q202480 te vertalen
naar VB.NET maar geraak in de knoei, onder meer wanneer het op marshalling
etc. aankomt.

Jammer dat die API's (nog) niet in managed classes zijn gewrapped ;-)


Thanks,

--
SLE
Re: VB.NET & EnumJobs()
#4261
Author: Pieter Philippaerts
Date: Wed, 03 Sep 2003 20:47
6 lines
1531 bytes
"SLE" <info@NOSPAMproit.be> wrote in message
> Ik probeer Q202480 te vertalen
> naar VB.NET maar geraak in de knoei, onder meer wanneer het op marshalling
> etc. aankomt.

Kan je je declaraties eens posten?
Re: VB.NET & EnumJobs()
#4262
Author: SLE
Date: Thu, 04 Sep 2003 07:07
72 lines
4186 bytes
"Pieter Philippaerts" <Pieter@nospam.mentalis.org> wrote...
> "SLE" <info@NOSPAMproit.be> wrote in message
> > Ik probeer Q202480 te vertalen
> > naar VB.NET maar geraak in de knoei, onder meer wanneer het op
marshalling
> > etc. aankomt.
>
> Kan je je declaraties eens posten?
>

Ik heb intussen van Microsoft PSS een "officieuze" vertaling van Q202480
naar VB.NET ontvangen. Let wel, copy/paste van de volledige code in een
nieuw VB.NET project werkt niet, had ik ook niet onmiddellijk verwacht.
Volledige code posten is net iets tīŋŊ, dus hier volgen de declaraties (indien
ik er niet uit geraak zal ik een url posten naar het volledige projectje):

Public Class WINAPI
 Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"
(<MarshalAsAttribute(UnmanagedType.AsAny)> ByVal o1 As Object,
<MarshalAsAttribute(UnmanagedType.AsAny)> ByVal o2 As Object, ByVal Length
As Integer)

 Declare Auto Function GetPrinter Lib "winspool.drv" (ByVal hPrinter As
IntPtr, ByVal Level As Integer, ByRef pPrinter As Byte, ByVal cbBuf As
Integer, ByRef pcbNeeded As Integer) As Boolean

 <DllImport("winspool.drv", EntryPoint:="EnumPrintersA", SetLastError:=True,
CharSet:=CharSet.Unicode, ExactSpelling:=True,
CallingConvention:=CallingConvention.StdCall)> Public Shared Function
EnumPrinters(ByVal flags As Long, ByVal name As String, ByVal Level As Long,
ByVal pPrinterEnum As Byte, ByVal cdBuf As Long, ByVal pcbNeeded As Long,
ByVal pcReturned As Long) As Long
  End Function

 <DllImport("kernel32", EntryPoint:="lstrcpyA", SetLastError:=True,
CharSet:=CharSet.Unicode, ExactSpelling:=True,
CallingConvention:=CallingConvention.StdCall)> Public Shared Function
lstrcpy(ByVal lpString1 As String, ByVal lpString2 As String) As Long
  End Function

 <DllImport("winspool.drv", EntryPoint:="ClosePrinter", SetLastError:=True,
CharSet:=CharSet.Unicode, ExactSpelling:=True,
CallingConvention:=CallingConvention.StdCall)> Public Shared Function
ClosePrinter(ByVal hPrinter As IntPtr) As Long
  End Function

 <DllImport("winspool.drv", EntryPoint:="EnumJobsA", SetLastError:=True,
CharSet:=CharSet.Unicode, ExactSpelling:=True,
CallingConvention:=CallingConvention.StdCall)> Public Shared Function
EnumJobs(ByVal hPrinter As IntPtr, ByRef FirstJob As Long, ByVal NoJobs As
Long, ByVal Level As Long, ByRef pJob As Byte, ByRef cdBuf As Long, ByVal
pcbNeeded As Long, ByVal pcReturned As Long) As Long
  End Function

 Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" (ByVal
pPrinterName As String, ByRef phPrinter As IntPtr,
<MarshalAsAttribute(UnmanagedType.AsAny)> ByVal o1 As Object) As Long

End Class

Wat me al onmiddellijk opvalt, is dat er nog "Long" declaraties zijn ... ik
dacht dat dit in .NET sowieso "Integer" aka "Int32" moest zijn?

O ja, ter info: de aanleiding van dit probleem is een ander probleem (zie
andere thread), nl. het feit dat de win32_printer noch win32_printjob WMI
classes niet cluster-aware (MSCS) zijn :-(


Thanks,

--
SLE
Re: VB.NET & EnumJobs()
#4263
Author: Pieter Philippaerts
Date: Thu, 04 Sep 2003 07:51
84 lines
5122 bytes
"SLE" <info@NOSPAMproit.be> wrote
>  Declare Auto Function GetPrinter Lib "winspool.drv" (ByVal hPrinter As
> IntPtr, ByVal Level As Integer, ByRef pPrinter As Byte, ByVal cbBuf As
> Integer, ByRef pcbNeeded As Integer) As Boolean

"ByRef pPrinter As Byte" moet "ByVal pPrinter As Byte()" worden.

>  <DllImport("winspool.drv", EntryPoint:="EnumPrintersA",
SetLastError:=True,
> CharSet:=CharSet.Unicode, ExactSpelling:=True,
> CallingConvention:=CallingConvention.StdCall)> Public Shared Function
> EnumPrinters(ByVal flags As Long, ByVal name As String, ByVal Level As
Long,
> ByVal pPrinterEnum As Byte, ByVal cdBuf As Long, ByVal pcbNeeded As Long,
> ByVal pcReturned As Long) As Long
>   End Function

Deze declaratie is compleet fout.
- Alle Longs in deze declaratie moeten Integers worden.
- "ByVal pPrinterEnum As Byte" moet  "ByVal pPrinterEnum As Byte()" worden.
- als EntryPoint geef he de ANSI versie van de functie aan, maar als CharSet
geef je Unicode aan. Ofwel moet je omschakelen naar "EnumPrintersW" als
entry point [maar deze functie is misschien niet aanwezig op Windows9x/ME]
ofwel Charset op Ansi zetten.

>  <DllImport("kernel32", EntryPoint:="lstrcpyA", SetLastError:=True,
> CharSet:=CharSet.Unicode, ExactSpelling:=True,
> CallingConvention:=CallingConvention.StdCall)> Public Shared Function
> lstrcpy(ByVal lpString1 As String, ByVal lpString2 As String) As Long
>   End Function

- Zelfde opmerking als hierboven: ANSI <=> Unicode
- return value is geen Long. Ofwel IntPtr ofwel String.

>  <DllImport("winspool.drv", EntryPoint:="ClosePrinter",
SetLastError:=True,
> CharSet:=CharSet.Unicode, ExactSpelling:=True,
> CallingConvention:=CallingConvention.StdCall)> Public Shared Function
> ClosePrinter(ByVal hPrinter As IntPtr) As Long
>   End Function

Return value is Boolean of IntPtr...

>  <DllImport("winspool.drv", EntryPoint:="EnumJobsA", SetLastError:=True,
> CharSet:=CharSet.Unicode, ExactSpelling:=True,
> CallingConvention:=CallingConvention.StdCall)> Public Shared Function
> EnumJobs(ByVal hPrinter As IntPtr, ByRef FirstJob As Long, ByVal NoJobs As
> Long, ByVal Level As Long, ByRef pJob As Byte, ByRef cdBuf As Long, ByVal
> pcbNeeded As Long, ByVal pcReturned As Long) As Long
>   End Function

- Zelfde opmerking als hierboven: ANSI <=> Unicode
- Longs moeten Integers worden
- "ByRef pJob As Byte" moet "ByVal pJob As Byte()" worden
- FirstJob, cdBuf  moeten ByVal zijn
- pcbNeeded, pcReturned moeten ByRef zijn

>  Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA"
(ByVal
> pPrinterName As String, ByRef phPrinter As IntPtr,
> <MarshalAsAttribute(UnmanagedType.AsAny)> ByVal o1 As Object) As Long

Het is natuurlijk mijn persoonlijke smaak, maar ik ben geen voorstander van:
"<MarshalAsAttribute(UnmanagedType.AsAny)> ByVal o1 As Object"
Persoonlijk verkies ik "ByVal o1 As IntPtr" [vooral als die parameter toch
enkel gebruikt gaat worden om NULL -- IntPtr.Zero -- mee te geven].

> Wat me al onmiddellijk opvalt, is dat er nog "Long" declaraties zijn ...
ik
> dacht dat dit in .NET sowieso "Integer" aka "Int32" moest zijn?

Die declaraties zijn dan ook compleet fout. Het kan niet missen dat je
problemen hebt.
Voor CopyMemory, lstrcpy en dergelijke zijn er wel equivalente methodes in
de runtime en je bent best dat je die dan ook gebruikt. Als je gaat
interoppen dan moet je zeker en vast eens de 'Marshal' klasse bekijken -- je
zal vlug merken dat het een extreem handige interop klasse is. De meest
interessante methodes zijn PtrToStringAnsi, PtrToStringUni, PtrToStructure,
ReadInt32, ReadIntPtr, SizeOf, StructureToPtr en last but not least Copy. De
AllocHGlobal/FreeHGlobal combo kan ook zeer handig zijn bij ingewikkelde
structures.

Mvg,
Pieter Philippaerts
Re: VB.NET & EnumJobs()
#4264
Author: SLE
Date: Thu, 04 Sep 2003 08:20
33 lines
2345 bytes
"Pieter Philippaerts" <Pieter@nospam.mentalis.org> wrote in message...
> "SLE" <info@NOSPAMproit.be> wrote

<cut>

>
> > Wat me al onmiddellijk opvalt, is dat er nog "Long" declaraties zijn ...
> ik
> > dacht dat dit in .NET sowieso "Integer" aka "Int32" moest zijn?
>
> Die declaraties zijn dan ook compleet fout. Het kan niet missen dat je
> problemen hebt.
> Voor CopyMemory, lstrcpy en dergelijke zijn er wel equivalente methodes in
> de runtime en je bent best dat je die dan ook gebruikt. Als je gaat
> interoppen dan moet je zeker en vast eens de 'Marshal' klasse bekijken --
je
> zal vlug merken dat het een extreem handige interop klasse is. De meest
> interessante methodes zijn PtrToStringAnsi, PtrToStringUni,
PtrToStructure,
> ReadInt32, ReadIntPtr, SizeOf, StructureToPtr en last but not least Copy.
De
> AllocHGlobal/FreeHGlobal combo kan ook zeer handig zijn bij ingewikkelde
> structures.
>

Pieter, bedankt voor je waardevolle reactie. Ik pas een en ander aan en
mocht ik nog een probleem hebben, dan kom ik er hier op terug ;-)


Thanks,

--
SLE
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads