Hilft das? 

-----Original Message-----
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of Frank Matthiesen
Sent: Dienstag, 5. April 2005 09:54
To: framework.net@glengamoi.com
Subject: [Framework.net] Workaround Denkanstoss gesucht

Moin Moin,

ich brauche mal einen Denkanstoss.
Ich erzeuge für eine Uni per Microsoft-Reportings-Services Kontoauszüge im
PDF-Format für die Studenten.
(Einsatz einer anderen kommerziellen Komponente derzeit aus politischen
Gründen nicht möglich)

Leider ist das erzeugte PDF nicht 100% konform. D.h. Windows-User mit
AdobeReader >= 6.0 koennen die PDF-Files ohne Probs lesen.
Aber alle anderen (Pinguine, Apfelmaenner etc.) drehen am Rad.

MS ist das Problem bekannt und es soll noch diesen Monat ein neues
Servicepack geben, welches u.a. die PDF-Export-Probs behebt.
Erscheinungsdatum wurde aber immer wieder nach hinten verschoben und daher
muss ich jetzt kurzfristig erstmal Abhilfe schaffen.

Derzeitiger Ablauf:
.net-Exe wird mit Parametern angestossen, erzeugt je Student ein PDF-File
und versendet dieses per Mail.

Mein Gedanke für kurzfristigen Workaround:
.net-Exe wird mit Parametern angestossen, erzeugt je Student ein PDF-File
druckt dieses über installierten PS-Printer in ein File und dann erneute
Umwandlung per Ghostscript -> Versand per Mail Hab nur leider keinen blassen
von Ghostscript......

Würdet ihr das ebenso angehen?


gruss

frank

_______________________________________________
Framework.net Mailingliste, Postings senden an:
Framework.net@glengamoi.com
An-/Abmeldung und Suchfunktion unter:
http://www.glengamoi.com/mailman/listinfo/framework.net
' Copyright (c) 2002 Dan Mount and Ghostgum Software Pty Ltd
'
' Permission is hereby granted, free of charge, to any person obtaining 
' a copy of this software and associated documentation files (the 
' "Software"), to deal in the Software without restriction, including
' without limitation the rights to use, copy, modify, merge, publish, 
' distribute, sublicense, and/or sell copies of the Software, and to
' permit persons to whom the Software is furnished to do so, subject to 
' the following conditions:
'
' The above copyright notice and this permission notice shall be
' included in all copies or substantial portions of the Software.
'
' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
' EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
' MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
' NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
' BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
' ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
' CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
' SOFTWARE.


' This is an example of how to call the Ghostscript DLL from
' Visual Basic.NET.  There are two examples, one converts
' colorcir.ps to PDF, the other is like command line Ghostscript.
' The display device is not supported.
'
' This code is not compatible with VB6.  There is another
' example which does work with VB6.  Differences include:
' 1. VB.NET uses GCHandle to get pointer
'    VB6 uses StrPtr/VarPtr
' 2. VB.NET Integer is 32bits, Long is 64bits
'    VB6 Integer is 16bits, Long is 32bits
' 3. VB.NET uses IntPtr for pointers
'    VB6 uses Long for pointers
' 4. VB.NET strings are always Unicode
'    VB6 can create an ANSI string
' See the following URL for some VB6 / VB.NET details
'  
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvb600/html/vb6tovbdotnet.asp

Option Explicit On 

Imports System.Runtime.InteropServices

Module gsapi

    Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal 
dest As IntPtr, ByVal source As IntPtr, ByVal bytes As Long)

    '------------------------------------------------
    'UDTs Start
    '------------------------------------------------
    <StructLayout(LayoutKind.Sequential)> Public Structure GS_Revision
        Public strProduct As IntPtr
        Public strCopyright As IntPtr
        Public intRevision As Integer
        Public intRevisionDate As Integer
    End Structure
    '------------------------------------------------
    'UDTs End
    '------------------------------------------------

    '------------------------------------------------
    'Callback Functions Start
    '------------------------------------------------
    'These are only required if you use gsapi_set_stdio
    Public Delegate Function StdioCallBack(ByVal handle As IntPtr, ByVal strptr 
As IntPtr, ByVal count As Integer) As Integer

    Public Function gsdll_stdin(ByVal intGSInstanceHandle As IntPtr, ByVal strz 
As IntPtr, ByVal intBytes As Integer) As Integer
        ' This is dumb code that reads one byte at a time
        ' Ghostscript doesn't mind this, it is just very slow
        If intBytes = 0 Then
            gsdll_stdin = 0
        Else
            Dim ich As Integer = Console.Read()
            If ich = -1 Then
                gsdll_stdin = 0 ' EOF
            Else
                Dim bch As Byte = ich
                Dim gcByte As GCHandle = GCHandle.Alloc(bch, 
GCHandleType.Pinned)
                Dim ptrByte As IntPtr = gcByte.AddrOfPinnedObject()
                CopyMemory(strz, ptrByte, 1)
                ptrByte = IntPtr.Zero
                gcByte.Free()
                gsdll_stdin = 1
            End If
        End If
    End Function

    Public Function gsdll_stdout(ByVal intGSInstanceHandle As IntPtr, ByVal 
strz As IntPtr, ByVal intBytes As Integer) As Integer
        ' If you can think of a more efficient method, please tell me!
        ' We need to convert from a byte buffer to a string
        ' First we create a byte array of the appropriate size
        Dim aByte(intBytes) As Byte
        ' Then we get the address of the byte array
        Dim gcByte As GCHandle = GCHandle.Alloc(aByte, GCHandleType.Pinned)
        Dim ptrByte As IntPtr = gcByte.AddrOfPinnedObject()
        ' Then we copy the buffer to the byte array
        CopyMemory(ptrByte, strz, intBytes)
        ' Release the address locking
        ptrByte = IntPtr.Zero
        gcByte.Free()
        ' Then we copy the byte array to a string, character by character
        Dim str As String
        Dim i As Integer
        For i = 0 To intBytes - 1
            str = str + Chr(aByte(i))
        Next
        ' Finally we output the message
        Console.Write(str)
        gsdll_stdout = intBytes
    End Function

    Public Function gsdll_stderr(ByVal intGSInstanceHandle As IntPtr, ByVal 
strz As IntPtr, ByVal intBytes As Integer) As Integer
        gsdll_stderr = gsdll_stdout(intGSInstanceHandle, strz, intBytes)
    End Function
    '------------------------------------------------
    'Callback Functions End
    '------------------------------------------------

    '------------------------------------------------
    'API Calls Start
    '------------------------------------------------
    'Win32 API
    'GhostScript API
    '    Public Declare Function gsapi_revision Lib "gsdll32.dll" (ByVal 
pGSRevisionInfo As IntPtr, ByVal intLen As Integer) As Integer
    Public Declare Function gsapi_revision Lib "gsdll32.dll" (ByRef 
pGSRevisionInfo As GS_Revision, ByVal intLen As Integer) As Integer
    Public Declare Function gsapi_new_instance Lib "gsdll32.dll" (ByRef 
lngGSInstance As IntPtr, ByVal lngCallerHandle As IntPtr) As Integer
    Public Declare Function gsapi_set_stdio Lib "gsdll32.dll" (ByVal 
lngGSInstance As IntPtr, ByVal gsdll_stdin As StdioCallBack, ByVal gsdll_stdout 
As StdioCallBack, ByVal gsdll_stderr As StdioCallBack) As Integer
    Public Declare Sub gsapi_delete_instance Lib "gsdll32.dll" (ByVal 
lngGSInstance As IntPtr)
    Public Declare Function gsapi_init_with_args Lib "gsdll32.dll" (ByVal 
lngGSInstance As IntPtr, ByVal lngArgumentCount As Integer, ByVal lngArguments 
As IntPtr) As Integer
    Public Declare Function gsapi_run_file Lib "gsdll32.dll" (ByVal 
lngGSInstance As IntPtr, ByVal strFileName As String, ByVal intErrors As 
Integer, ByVal intExitCode As Integer) As Integer
    Public Declare Function gsapi_exit Lib "gsdll32.dll" (ByVal lngGSInstance 
As IntPtr) As Integer
    '------------------------------------------------
    'API Calls End
    '------------------------------------------------

    '------------------------------------------------
    'User Defined Functions Start
    '------------------------------------------------
    Public Function StringToAnsiZ(ByVal str As String) As Byte()
        ' Convert a Unicode string to a null terminated Ansi string for 
Ghostscript.
        ' The result is stored in a byte array.  Later you will need to convert
        ' this byte array to a pointer with GCHandle.Alloc(XXXX, 
GCHandleType.Pinned)
        ' and GSHandle.AddrOfPinnedObject()
        Dim intElementCount As Integer
        Dim intCounter As Integer
        Dim aAnsi() As Byte
        Dim bChar As Byte
        intElementCount = Len(str)
        ReDim aAnsi(intElementCount + 1)
        For intCounter = 0 To intElementCount - 1
            bChar = Asc(Mid(str, intCounter + 1, 1))
            aAnsi(intCounter) = bChar
        Next intCounter
        aAnsi(intElementCount) = 0
        StringToAnsiZ = aAnsi
    End Function

    Public Function AnsiZtoString(ByVal strz As IntPtr) As String
        ' We need to convert from a byte buffer to a string
        Dim byteCh(1) As Byte
        Dim bOK As Boolean = True
        Dim gcbyteCh As GCHandle = GCHandle.Alloc(byteCh, GCHandleType.Pinned)
        Dim ptrByte As IntPtr = gcbyteCh.AddrOfPinnedObject()
        Dim j As Integer = 0
        Dim str As String
        While bOK
            ' This is how to do pointer arithmetic!
            Dim sPtr As New IntPtr(strz.ToInt64() + j)
            CopyMemory(ptrByte, sPtr, 1)
            If byteCh(0) = 0 Then
                bOK = False
            Else
                str = str + Chr(byteCh(0))
            End If
            j = j + 1
        End While
        AnsiZtoString = str
    End Function

    Public Function CheckRevision(ByVal intRevision As Integer) As Boolean
        ' Check revision number of Ghostscript
        Dim intReturn As Integer
        Dim udtGSRevInfo As GS_Revision
        Dim gcRevision As GCHandle
        gcRevision = GCHandle.Alloc(udtGSRevInfo, GCHandleType.Pinned)
        intReturn = gsapi_revision(udtGSRevInfo, 16)
        Console.WriteLine("Revision = " & udtGSRevInfo.intRevision)
        Console.WriteLine("RevisionDate = " & udtGSRevInfo.intRevisionDate)
        Console.WriteLine("Product = " & AnsiZtoString(udtGSRevInfo.strProduct))
        Console.WriteLine("Copyright = " & 
AnsiZtoString(udtGSRevInfo.strCopyright))

        If udtGSRevInfo.intRevision = intRevision Then
            CheckRevision = True
        Else
            CheckRevision = False
        End If
        gcRevision.Free()
    End Function

    Public Function CallGS(ByVal astrGSArgs() As String) As Boolean
        Dim intReturn As Integer
        Dim intGSInstanceHandle As IntPtr
        Dim aAnsiArgs() As Object
        Dim aPtrArgs() As IntPtr
        Dim aGCHandle() As GCHandle
        Dim intCounter As Integer
        Dim intElementCount As Integer
        Dim iTemp As Integer
        Dim callerHandle As IntPtr
        Dim gchandleArgs As GCHandle
        Dim intptrArgs As IntPtr

        ' Print out the revision details.
        ' If we want to insist on a particular version of Ghostscript
        ' we should check the return value of CheckRevision().
        CheckRevision(704)

        ' Load Ghostscript and get the instance handle
        intReturn = gsapi_new_instance(intGSInstanceHandle, callerHandle)
        If (intReturn < 0) Then
            Return (False)
        End If

        ' Capture stdio
        Dim stdinCallback As StdioCallBack
        stdinCallback = AddressOf gsdll_stdin
        Dim stdoutCallback As StdioCallBack
        stdoutCallback = AddressOf gsdll_stdout
        Dim stderrCallback As StdioCallBack
        stderrCallback = AddressOf gsdll_stderr
        intReturn = gsapi_set_stdio(intGSInstanceHandle, stdinCallback, 
stdoutCallback, stderrCallback)

        If (intReturn >= 0) Then
            ' Convert the Unicode strings to null terminated ANSI byte arrays
            ' then get pointers to the byte arrays.
            intElementCount = UBound(astrGSArgs)
            ReDim aAnsiArgs(intElementCount)
            ReDim aPtrArgs(intElementCount)
            ReDim aGCHandle(intElementCount)
            For intCounter = 0 To intElementCount
                aAnsiArgs(intCounter) = StringToAnsiZ(astrGSArgs(intCounter))
                aGCHandle(intCounter) = GCHandle.Alloc(aAnsiArgs(intCounter), 
GCHandleType.Pinned)
                aPtrArgs(intCounter) = 
aGCHandle(intCounter).AddrOfPinnedObject()
            Next
            gchandleArgs = GCHandle.Alloc(aPtrArgs, GCHandleType.Pinned)
            intptrArgs = gchandleArgs.AddrOfPinnedObject()
            callerHandle = IntPtr.Zero

            intReturn = gsapi_init_with_args(intGSInstanceHandle, 
intElementCount + 1, intptrArgs)

            ' Release the pinned memory
            For intCounter = 0 To intElementCount
                aGCHandle(intCounter).Free()
            Next
            gchandleArgs.Free()

            ' Stop the Ghostscript interpreter
            gsapi_exit(intGSInstanceHandle)
        End If

        ' release the Ghostscript instance handle
        gsapi_delete_instance(intGSInstanceHandle)

        If (intReturn >= 0) Then
            CallGS = True
        Else
            CallGS = False
        End If

    End Function

    Private Function ConvertFile() As Boolean
        Dim astrArgs(10) As String
        astrArgs(0) = "ps2pdf" 'The First Parameter is Ignored
        astrArgs(1) = "-dNOPAUSE"
        astrArgs(2) = "-dBATCH"
        astrArgs(3) = "-dSAFER"
        astrArgs(4) = "-r300"
        astrArgs(5) = "-sDEVICE=pdfwrite"
        astrArgs(6) = "-sOutputFile=c:\out.pdf"
        astrArgs(7) = "-c"
        astrArgs(8) = ".setpdfwrite"
        astrArgs(9) = "-f"
        astrArgs(10) = "c:\gs\gs7.04\examples\colorcir.ps"
        Return CallGS(astrArgs)
    End Function

    Private Function InteractiveGS() As Boolean
        Dim astrArgs(2) As String
        astrArgs(0) = "gs" 'The First Parameter is Ignored
        astrArgs(1) = "-c"
        astrArgs(2) = "systemdict /start get exec"
        Return CallGS(astrArgs)
    End Function


    '------------------------------------------------
    'User Defined Functions End
    '------------------------------------------------

    Sub Main()
        ConvertFile()
        'InteractiveGS()
        MsgBox("Done")
    End Sub

End Module

Antwort per Email an