More EnumPrinters help wanted. I wrote the following code from an example I
found on .NET 247. Anyhow, look at the For/Next loop. The first iteration,
it works fine. The messagebox shows me the share name of a printer. But on
the 2nd iteration, the Marshal.PtrToSt ructure line throws an
AccessViolation Exception was unhandled (Attempted to read or write protected
memory. This is often an indication that other memory is corrupt.). Can
anyone see what may be wrong in the code?
Thanks.
Imports System.Runtime. InteropServices
Module EnumPrinters
Public Function GetPrintShares( ByVal Server As String) As ArrayList
Dim pcbNeeded As Int32
Dim pcbReturned As Int32
Dim outC As IntPtr = IntPtr.Zero
Dim tmp As Integer = (EnumPrinters(P rinterEnum.peNA ME Or
PrinterEnum.peS HARED, _
"", 2, outC, 0, pcbNeeded, pcbReturned))
outC = Marshal.AllocHG lobal(pcbNeeded )
tmp = EnumPrinters(Pr interEnum.peNAM E Or PrinterEnum.peS HARED, _
"", 2, outC, pcbNeeded, pcbNeeded, pcbReturned)
MsgBox(tmp & " - " & pcbNeeded & " - " & pcbReturned)
Dim manyPR(pcbRetur ned) As PRINTER_INFO_2
Dim currentP As IntPtr = outC
Dim MyAL As New ArrayList
For i As Integer = 1 To pcbReturned
manyPR(i) = Marshal.PtrToSt ructure(current P, manyPR(i).GetTy pe)
MsgBox(manyPR(i ).pShareName)
MyAL.Add(manyPR (i).pShareName)
currentP = IntPtr.op_Expli cit(currentP.To Int32 +
Marshal.SizeOf( manyPR(i).GetTy pe))
Next
Marshal.FreeHGl obal(outC)
Return MyAL
End Function
Private Declare Auto Function EnumPrinters Lib "winspool.d rv" Alias
"EnumPrinte rsA" _
(ByVal Flags As Int32, _
ByVal Name As String, _
ByVal Level As Int32, _
ByVal pPrinterEnum As IntPtr, _
ByVal cbBuf As Int32, _
ByRef pcbNeeded As Int32, _
ByRef pcReturned As Int32) As Integer
Private Structure PRINTER_INFO_2
<MarshalAs(Unma nagedType.LPStr )> Dim pServerName As String
<MarshalAs(Unma nagedType.LPStr )> Dim pPrinterName As String
<MarshalAs(Unma nagedType.LPStr )> Dim pShareName As String
<MarshalAs(Unma nagedType.LPStr )> Dim pPortName As String
<MarshalAs(Unma nagedType.LPStr )> Dim pDriverName As String
<MarshalAs(Unma nagedType.LPStr )> Dim pComment As String
<MarshalAs(Unma nagedType.LPStr )> Dim pLocation As String
Dim pDevMode As IntPtr
<MarshalAs(Unma nagedType.LPStr )> Dim pSepFile As String
<MarshalAs(Unma nagedType.LPStr )> Dim pPrintProcessor As String
<MarshalAs(Unma nagedType.LPStr )> Dim pDatatype As String
<MarshalAs(Unma nagedType.LPStr )> Dim pParameters As String
Dim pSecurityDescri ptor As IntPtr
Dim Attributes As Long
Dim Priority As Long
Dim DefaultPriority As Long
Dim StartTime As Long
Dim UntilTime As Long
Dim Status As Long
Dim cJobs As Long
Dim AveragePPM As Long
End Structure
Private Enum PrinterEnum
peDEFAULT = &H1
peLOCAL = &H2
peCONNECTIONS = &H4
peNAME = &H8
peREMOTE = &H10
peSHARED = &H20
peNETWORK = &H40
End Enum
End Module
found on .NET 247. Anyhow, look at the For/Next loop. The first iteration,
it works fine. The messagebox shows me the share name of a printer. But on
the 2nd iteration, the Marshal.PtrToSt ructure line throws an
AccessViolation Exception was unhandled (Attempted to read or write protected
memory. This is often an indication that other memory is corrupt.). Can
anyone see what may be wrong in the code?
Thanks.
Imports System.Runtime. InteropServices
Module EnumPrinters
Public Function GetPrintShares( ByVal Server As String) As ArrayList
Dim pcbNeeded As Int32
Dim pcbReturned As Int32
Dim outC As IntPtr = IntPtr.Zero
Dim tmp As Integer = (EnumPrinters(P rinterEnum.peNA ME Or
PrinterEnum.peS HARED, _
"", 2, outC, 0, pcbNeeded, pcbReturned))
outC = Marshal.AllocHG lobal(pcbNeeded )
tmp = EnumPrinters(Pr interEnum.peNAM E Or PrinterEnum.peS HARED, _
"", 2, outC, pcbNeeded, pcbNeeded, pcbReturned)
MsgBox(tmp & " - " & pcbNeeded & " - " & pcbReturned)
Dim manyPR(pcbRetur ned) As PRINTER_INFO_2
Dim currentP As IntPtr = outC
Dim MyAL As New ArrayList
For i As Integer = 1 To pcbReturned
manyPR(i) = Marshal.PtrToSt ructure(current P, manyPR(i).GetTy pe)
MsgBox(manyPR(i ).pShareName)
MyAL.Add(manyPR (i).pShareName)
currentP = IntPtr.op_Expli cit(currentP.To Int32 +
Marshal.SizeOf( manyPR(i).GetTy pe))
Next
Marshal.FreeHGl obal(outC)
Return MyAL
End Function
Private Declare Auto Function EnumPrinters Lib "winspool.d rv" Alias
"EnumPrinte rsA" _
(ByVal Flags As Int32, _
ByVal Name As String, _
ByVal Level As Int32, _
ByVal pPrinterEnum As IntPtr, _
ByVal cbBuf As Int32, _
ByRef pcbNeeded As Int32, _
ByRef pcReturned As Int32) As Integer
Private Structure PRINTER_INFO_2
<MarshalAs(Unma nagedType.LPStr )> Dim pServerName As String
<MarshalAs(Unma nagedType.LPStr )> Dim pPrinterName As String
<MarshalAs(Unma nagedType.LPStr )> Dim pShareName As String
<MarshalAs(Unma nagedType.LPStr )> Dim pPortName As String
<MarshalAs(Unma nagedType.LPStr )> Dim pDriverName As String
<MarshalAs(Unma nagedType.LPStr )> Dim pComment As String
<MarshalAs(Unma nagedType.LPStr )> Dim pLocation As String
Dim pDevMode As IntPtr
<MarshalAs(Unma nagedType.LPStr )> Dim pSepFile As String
<MarshalAs(Unma nagedType.LPStr )> Dim pPrintProcessor As String
<MarshalAs(Unma nagedType.LPStr )> Dim pDatatype As String
<MarshalAs(Unma nagedType.LPStr )> Dim pParameters As String
Dim pSecurityDescri ptor As IntPtr
Dim Attributes As Long
Dim Priority As Long
Dim DefaultPriority As Long
Dim StartTime As Long
Dim UntilTime As Long
Dim Status As Long
Dim cJobs As Long
Dim AveragePPM As Long
End Structure
Private Enum PrinterEnum
peDEFAULT = &H1
peLOCAL = &H2
peCONNECTIONS = &H4
peNAME = &H8
peREMOTE = &H10
peSHARED = &H20
peNETWORK = &H40
End Enum
End Module
Comment