Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Finished Printing notification

Îåêßíçóå áðü ôï ìÝëïò anjelinio. Τελευταία δημοσίευση από το μέλος manosB στις 05-02-2008, 14:57. Υπάρχουν 23 απαντήσεις.
Σελίδα 2 από 2 (24 εγγραφές)   < 1 2
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  25-09-2007, 20:38 35417 σε απάντηση της 35394

    Απ: Finished Printing notification

    Ρίξε μία ματιά στο http://www.thescripts.com/forum/thread229577.html . Όχι ότι ο τύπος κατάφερε να παίξει, αλλά θα δεις πως κάνει τις δηλώσεις:

    [StructLayout( LayoutKind.Sequential,CharSet=CharSet.Auto)]

    public struct PRINTERINFO2

    {

    [MarshalAs(UnmanagedType.LPTStr)]public string pServerName;
    [MarshalAs(UnmanagedType.LPTStr)]public string pPrinterName;
    [MarshalAs(UnmanagedType.LPTStr)]public string pShareName;
    [MarshalAs(UnmanagedType.LPTStr)]public string pPortName;
    [MarshalAs(UnmanagedType.LPTStr)]public string pDriverName;
    [MarshalAs(UnmanagedType.LPTStr)]public string pComment;
    [MarshalAs(UnmanagedType.LPTStr)]public string pLocation;
    public IntPtr pDevMode;
    [MarshalAs(UnmanagedType.LPTStr)]public string pSepFile;
    [MarshalAs(UnmanagedType.LPTStr)]public string pPrintProcessor;
    [MarshalAs(UnmanagedType.LPTStr)]public string pDatatype;
    [MarshalAs(UnmanagedType.LPTStr)]public string pParameters;
    public IntPtr pSecurityDescriptor;
    public int Attributes;
    public int Priority;
    public int DefaultPriority;
    public int StartTime;
    public int UntilTime;
    public int Status;
    public int cJobs;
    public int AveragePPM;
    }

    public class Printer

    {

    [ DllImport( "winspool.drv",CharSet=CharSet.Unicode,ExactSpelling=false, CallingConvention=CallingConvention.StdCall )]
    public static extern long OpenPrinter(string pPrinterName,ref IntPtr phPrinter, int pDefault);

    [ DllImport("winspool.drv",CharSet=CharSet.Unicode,ExactSpelling=true, CallingConvention=CallingConvention.StdCall )]
    public static extern long ClosePrinter(IntPtr hPrinter);

    [ DllImport("winspool.drv" ,CharSet=CharSet.Auto)]
    public static extern bool GetPrinter(IntPtr hPrinter,int Level,ref PRINTERINFO2 pPrinter,int cbBuf,ref int pcbNeeded);

    }


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  25-09-2007, 21:24 35418 σε απάντηση της 35417

    Απ: Finished Printing notification

    Άργησες λίγο Πάνο, πλέον δεν είναι οι δηλώσεις το πρόβλημά μου. Είναι ότι το PRINTER_INFO_2 struct που σου γυρίζει το Win32 δεν είναι απαραίτητα ενημερωμένη σε όλα τα πεδία της. Ο μόνος "σίγουρος" ( με έναν ξεκάθαρα MS Win32 API τρόπο ορισμού του "σίγουρου" ... ) τρόπος είναι μέσω του Print Queue.

    Σε ευχαριστώ πολύ πάντως φίλο. Απ' αύριο .. "και πάλι στον αγώνα, ζήτω η λεγεώνα" Smile

    Angel
    O:]
  •  26-09-2007, 16:07 35457 σε απάντηση της 35418

    Απ: Finished Printing notification

    Άντε άλλη μια ... οκ, λοιπόν, μπορείς να διαβάσεις το print queue ενός εκτυπωτή μέσω της EnumJobs(...) Win32 function, αλλά ...

    Της περνάς έναν pointer (IntPtr) σε μια περιοχή μνήμης την οποία έχεις κάνει allocate, και στη γεμίζει με JOB_INFO_1 structure instances.
    Το θέμα μου τώρα είναι, πως κάνεις unmarshall ένα array;;; O Marshal class δεν έχει κάτι out-of-the-box γι' αυτό.

    Οπότε, σκεπτόμενος ότι ένα unmanaged array είναι στην ουσία απλώς ένα collection απο pointers, σκέφτηκα να κάνω "enumerate" αυτό το unmanaged array, να διαβάζω τον εκάστοτε pointer, και να κάνω πλέον αυτόν unmarshall σε ένα struct instance χρησιμοποιώντας την Marshal.PtrToStructure(IntPtr, Type)

    Κώδικας:

                        // ok, bytes required is NOT 0 ... proceed then
                        IntPtr ptrJobInfo = Marshal.AllocCoTaskMem(Convert.ToInt32(bytesRequired));
                        if (EnumJobs(printerHandle, 0, 10, 1, ptrJobInfo, bytesRequired, out bytesRequired, out numReturned))
                        {
                            for (int index = 0; index < numReturned; index++) {
                                // ok, first read an IntPtr off the original pointer * IntPtr.Size
                                // ( I'm hoping that the array returned is indeed a collection of pointers to objects )
                                IntPtr structPtr = Marshal.ReadIntPtr(ptrJobInfo, index * IntPtr.Size);
                                JOB_INFO_1 job = (JOB_INFO_1)Marshal.PtrToStructure(structPtr, typeof(JOB_INFO_1));
                            }


                            // kill that memory as well ...
                            Marshal.DestroyStructure(ptrJobInfo, typeof(JOB_INFO_1[]));
                        }

    Αυτό .. δεν έπαιξε. Μου έσκασε ExecutionEngineException.

    Στα καπάκια σκέφτηκα ότι ίσως δεν θυμόμουν καλά απο το C++ μάθημα στο Παν/μιο, και ίσως θα έπρεπε να κάνω increment τον pointer στο Marshal.ReadIntPtr(ptrJobInfo, index * IntPtr.Size); όχι με το IntPtr.Size, αλλά με το Marshal.SizeOf(...) του structure μου.

    Αλλά έστω κι έτσι, πάλι τρώω το exception στο πρώτο item μέσα στο unmanaged array - εκεί που δεν έχω κάνει increment καν τον pointer.

    Τί μπέρδεμα !!!

    Angel
    O:]
  •  26-09-2007, 16:36 35458 σε απάντηση της 35457

    Απ: Finished Printing notification

    Το έκανα !!! Το έκανα !!! Τράλαλά λαλά λαλά !!!

    Νιώθω σαν τον Hiro ( απο το Heroes ... ) όταν τηλεμεταφέρθηκε στη Νέα Υόρκη !

    Κι ο κώδικας:

            public static void EnumPrinterJobs(string printerName) {
                IntPtr printerHandle;
                // ok, let's try to open the printer first ...
                if (OpenPrinter(printerName, out printerHandle, IntPtr.Zero))
                {
                    try
                    {
                        // ok, now ... I'm doin' this 2 times. The first i do just to fail & get back the required bytes for my
                        // buffer length
                        uint bytesRequired;
                        uint numReturned;

                        EnumJobs(printerHandle, 0, 10, 1, IntPtr.Zero, 0, out bytesRequired, out numReturned);
                        if (bytesRequired <= 0)
                        {
                            int lastError = Marshal.GetLastWin32Error();
                            Marshal.ThrowExceptionForHR(lastError);
                        }

                        // ok, bytes required is NOT 0 ... proceed then
                        IntPtr ptrJobInfo = Marshal.AllocCoTaskMem(Convert.ToInt32(bytesRequired));
                        if (EnumJobs(printerHandle, 0, 10, 1, ptrJobInfo, bytesRequired, out bytesRequired, out numReturned))
                        {
                            // Get a var ready ...
                            //JOB_INFO_1[] pInfo = (JOB_INFO_1[])Marshal.PtrToStructure(ptrJobInfo, typeof(JOB_INFO_1[]));
                           
                            //JOB_INFO_1[] pInfo = new JOB_INFO_1[numReturned];
                            //Marshal.PtrToStructure(ptrJobInfo, pInfo);

                            for (int index = 0; index < numReturned; index++) {
                                // ok, first read an IntPtr off the original pointer * IntPtr.Size
                                // ( I'm hoping that the array returned is indeed a collection of pointers to objects )
     
                                // Cast to int & increment ...
                                int intPtr = ((int)ptrJobInfo + (index * Marshal.SizeOf(typeof(JOB_INFO_1))));
                                IntPtr incPtr = new IntPtr(intPtr);

                                JOB_INFO_1 job = (JOB_INFO_1)Marshal.PtrToStructure(incPtr, typeof(JOB_INFO_1));
                                Console.WriteLine("JobID: {0}. Document: {1}. Status:{2}", job.JobId, job.pDocument, job.Status);
                            }
                           

                            // and deserialize off the memory buffer, innit ???
                            //Console.WriteLine("Fetched Status: {0}", pInfo.Status);

                            // kill that memory as well ...
                            Marshal.FreeCoTaskMem(ptrJobInfo);
                        }


                    } finally {
                        // Close the printer ...
                        ClosePrinter(printerHandle);
                    }
                }

    Και τελικά, αν δε θυμάστε, ένα unmanaged array είναι ένα sequential block of memory, όπου σε chunks μεγέθους sizeof(my_data_type) βρίσκονται τα μέλη του array.
    ( Φρικτό το ότι ένα System.IntPtr δεν έχει μια increment ή κάποιο "+" operator υλοποιημένα, και πρέπει να το κάνεις cast σε Int32 για να του προσθέσεις ... )

    Επίσης φρικτό το ότι πρέπει τώρα να βρώ τι παίζει με τα strings γιατί μου τα φέρνει πίσω αλαμπουρνέζικα μέσα στο struct, και σε τί αντιστοιχούν οι int τιμές που παίρνει το .Status και να τι αντιστοιχήσω σε ένα enumeration δικό μου ... :S



    Angel
    O:]
  •  26-09-2007, 19:15 35474 σε απάντηση της 35458

    Απ: Finished Printing notification

    και μετά απο οοοοοολα αυτά ... ανακάλυψα ότι τελικά ... δεν παίρνεις ποτέ status FINISHED. Μόλις εξαφανίζεται απο τη λίστα του spooler ... τέλος.

    "καταταχτείτε ... "

    Angel
    O:]
  •  02-10-2007, 17:36 35751 σε απάντηση της 35474

    Απ: Finished Printing notification

    Σκαλίζοντας για άσχετα πράγματα, έπεσα πάνω στο System.Printing namespace του .NET 3.0 (μην το μπλέκετε με το .NET 3.5). Περιλαμβάνει κλάσεις για PrintServer, PrintQueue και ...  PrintSystemJobInfo. Η οποία έχει το property JobStatus, η οποία παρέχει πληροφορίες για Paperout, Deleted, Spooling και φυσικά, Completed (μεταξύ άλλων). Άγγελε, έχεις όρεξη να το ψάξεις και αυτό?

     


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  03-10-2007, 10:24 35769 σε απάντηση της 35751

    Απ: Finished Printing notification

    LOL ... why not ?  "Έχω δοκιμάσει τα πάντα, στο Ultrex θα κολλήσω;" Big Smile

    Angel
    O:]
  •  03-10-2007, 12:43 35774 σε απάντηση της 35769

    Απ: Finished Printing notification

    Μου φαίνεται ότι όταν πρόσθεσαν την υποστήριξη για Office documents στο .NET 3.0 είπαν "Δεν βάζουμε και ένα καλό namespace για server-side printing"?

    Μπορεί να φανεί διεστραμμένο, αλλά αυτό το Namespace μπορεί να είναι ένας εξίσου ισχυρός λόγος να περάσει κανείς σε .NET 3.0  με το Workflow και το WCF! Τα άλλα είναι φοβερά χρήσιμα για να φτιάξεις μία νέα αρχιτεκτονική. Το System.Printing όμως σου επιτρέπει να κάνεις εύκολα μία απαραίτητη δουλειά.

    (Υπό τον όρο ότι δουλεύει καλά φυσικά)


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  05-02-2008, 14:57 39875 σε απάντηση της 35774

    Απ: Finished Printing notification

    Λοιπόν τι έγινε με αυτό το Post. Δουλεύει το System.Printing. Θέλω να το ενσωματώσω κάπου για αυτό και ρωτάω τώρα. Σου επιστρέφει completed. Το δοκίμασε κανείς?

    Manos
Σελίδα 2 από 2 (24 εγγραφές)   < 1 2
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems