|
Îåêßíçóå áðü ôï ìÝëïò anjelinio. Τελευταία δημοσίευση από το μέλος manosB στις 05-02-2008, 14:57. Υπάρχουν 23 απαντήσεις.
-
25-09-2007, 20:38
|
|
Απ: 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
|
-
anjelinio
-
-
-
Μέλος από τις 21-06-2005
-
-
Δημοσιεύσεις 571
-
-
|
Απ: Finished Printing notification
Άργησες λίγο Πάνο, πλέον δεν είναι οι δηλώσεις το πρόβλημά μου. Είναι ότι το PRINTER_INFO_2 struct που σου γυρίζει το Win32 δεν είναι απαραίτητα ενημερωμένη σε όλα τα πεδία της. Ο μόνος "σίγουρος" ( με έναν ξεκάθαρα MS Win32 API τρόπο ορισμού του "σίγουρου" ... ) τρόπος είναι μέσω του Print Queue. Σε ευχαριστώ πολύ πάντως φίλο. Απ' αύριο .. " και πάλι στον αγώνα, ζήτω η λεγεώνα"
Angel O:]
|
|
-
26-09-2007, 16:07
|
-
anjelinio
-
-
-
Μέλος από τις 21-06-2005
-
-
Δημοσιεύσεις 571
-
-
|
Απ: 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
|
-
anjelinio
-
-
-
Μέλος από τις 21-06-2005
-
-
Δημοσιεύσεις 571
-
-
|
Απ: 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
|
-
anjelinio
-
-
-
Μέλος από τις 21-06-2005
-
-
Δημοσιεύσεις 571
-
-
|
Απ: Finished Printing notification
και μετά απο οοοοοολα αυτά ... ανακάλυψα ότι τελικά ... δεν παίρνεις ποτέ status FINISHED. Μόλις εξαφανίζεται απο τη λίστα του spooler ... τέλος.
"καταταχτείτε ... "
Angel O:]
|
|
-
02-10-2007, 17:36
|
|
Απ: 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
|
-
anjelinio
-
-
-
Μέλος από τις 21-06-2005
-
-
Δημοσιεύσεις 571
-
-
|
Απ: Finished Printing notification
LOL ... why not ? " Έχω δοκιμάσει τα πάντα, στο Ultrex θα κολλήσω;"
Angel O:]
|
|
-
03-10-2007, 12:43
|
|
Απ: 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
|
-
manosB
-
-

-
Μέλος από τις 05-10-2005
-
Καπανδρίτι
-
Δημοσιεύσεις 903
-
-
|
Απ: Finished Printing notification
Λοιπόν τι έγινε με αυτό το Post. Δουλεύει το System.Printing. Θέλω να το ενσωματώσω κάπου για αυτό και ρωτάω τώρα. Σου επιστρέφει completed. Το δοκίμασε κανείς?
Manos
|
|
Σελίδα 2 από 2 (24 εγγραφές)
2
|
|
|