2013-02-12 13 views
0

Я создаю программу для захвата печатных документов, а затем конвертирую эти документы в xps \ image.Как перепечатать файл спула с помощью XPS-принтера?

В настоящее время я использую FileSystemWatcher контролировать директорию «C: \ Windows \ System32 \ Spool \ ПРИНТЕРЫ \» и скопировать Spl файлы, убедитесь, что его не дублировать то попробовать преобразовав его в ЭПС файл, напечатав УЗД файл с использованием Win32 Spooler API и Microsoft XPS Document Writer предопределенный принтер, но когда я укажу выходной файл, как показано ниже, возвращается код ошибки 1804, если я оставлю его пустым, он преуспевает, но затем я не получаю выходной файл ,

public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount, string outputFile, string dataType, out int errorCode) 
    { 
     IntPtr hPrinter; 
     var di = new DOCINFOA(); 
     var bSuccess = false; // Assume failure unless you specifically succeed. 

     di.pDocName = "Spool Doc"; 
     di.pDataType = dataType; 
     di.pOutputFile = outputFile; 

     // Open the printer. 
     if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero)) 
     { 
      // Start a document. 
      if (StartDocPrinter(hPrinter, 1, di)) 
      { 
       // Start a page. 
       if (StartPagePrinter(hPrinter)) 
       { 
        // Write your bytes. 
        var dwWritten = 0; 
        bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten); 
        EndPagePrinter(hPrinter); 
       } 
       EndDocPrinter(hPrinter); 
      } 
      ClosePrinter(hPrinter); 
     } 
     // If you did not succeed, GetLastError may give more information 
     // about why not. 
     errorCode = bSuccess == false ? Marshal.GetLastWin32Error() : 0; 
     return bSuccess; 
    } 

Итак, что я делаю неправильно, и как напечатать \ преобразовать файл катушки к XPS документа, и, если возможно, файл изображения и текстового файла.

Edit: Добавление Дополнительная информация

здесь является реализация DOCINFOA

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
    public class DOCINFOA 
    { 
     [MarshalAs(UnmanagedType.LPStr)] 
     public string pDataType; 
     [MarshalAs(UnmanagedType.LPStr)] 
     public string pDocName; 
     [MarshalAs(UnmanagedType.LPStr)] 
     public string pOutputFile; 
    } 

и здесь является полная цепочка вызовов:

Приложение работает следующий код

var dataTypes = new[] { null, "RAW", "RAW [FF appended]", "RAW [FF auto]", "NT EMF 1.003", "NT EMF 1.006", "NT EMF 1.007", "NT EMF 1.008", "TEXT", "XPS_PASS", "XPS2GDI" }; 
    foreach (var dataType in dataTypes) 
    { 
     int errorCode; 
     RawPrinterHelper.SendFileToPrinter(@"Microsoft XPS Document Writer", sourceFile, outputFile, dataType, out errorCode); 
     //print errorCode 
    } 

И в RawPrinterHelper

public static bool SendFileToPrinter(string szPrinterName, string szFileName, string outputPath, string dataType, out int errorCode) 
    { 
     // Open the file. 
     var fs = new FileStream(szFileName, FileMode.Open); 
     // Create a BinaryReader on the file. 
     var br = new BinaryReader(fs); 
     // Dim an array of bytes big enough to hold the file's contents. 
     // Your unmanaged pointer. 
     var documentPath = Path.GetFileName(szFileName); 
     var nLength = Convert.ToInt32(fs.Length); 
     // Read the contents of the file into the array. 
     var bytes = br.ReadBytes(nLength); 
     // Allocate some unmanaged memory for those bytes. 
     var pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength); 
     // Copy the managed byte array into the unmanaged array. 
     Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength); 
     // Send the unmanaged bytes to the printer. 
     var bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength, outputPath, dataType, out errorCode); 
     // Free the unmanaged memory that you allocated earlier. 
     Marshal.FreeCoTaskMem(pUnmanagedBytes); 
     fs.Close(); 
     return bSuccess; 
    } 

И API функции

[DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, 
    ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
    public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd); 

    [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
    public static extern bool ClosePrinter(IntPtr hPrinter); 

    [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, 
    ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
    public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di); 

    [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
    public static extern bool EndDocPrinter(IntPtr hPrinter); 

    [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
    public static extern bool StartPagePrinter(IntPtr hPrinter); 

    [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
    public static extern bool EndPagePrinter(IntPtr hPrinter); 

    [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
    public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten); 
+0

Что вы устанавливаете для pDataType? Это, скорее всего, причина ошибки. Попробуйте установить значение null. Если это не работает, попробуйте «RAW». –

+0

@CareyGregory Я пробовал эти типы null, «RAW», «RAW [FF appended]», «RAW [FF auto]», «NT EMF 1.003», «NT EMF 1.006», «NT EMF 1.007», «NT EMF 1.008 "," TEXT "," XPS_PASS "," XPS2GDI "в петле, и все они дали ту же ошибку – MEYWD

+0

Пожалуйста, добавьте ваше объявление DOCINFOA на свой пост. –

ответ

1

Проблема ваша декларация DOC_INFO_1 структуры. Он не соответствует the layout Windows expects. Объявление для Windows выглядит следующим образом:

typedef struct _DOC_INFO_1 { 
    LPTSTR pDocName; 
    LPTSTR pOutputFile; 
    LPTSTR pDatatype; 
} DOC_INFO_1; 

Но ваша декларация имеет это так:

public class DOCINFOA 
{ 
    public string pDataType; 
    public string pDocName; 
    public string pOutputFile; 
} 

Перегруппируйте элементы в вашем объявлении, чтобы соответствовать Windows, и-структуру он должен решить вашу проблему.

EDIT: Плохая новость. Ваш подход не будет работать. Посмотрите на документацию для WritePrinter:

WritePrinter поддерживает только GDI печати и не должны использоваться для XPS печати. Если ваше задание на печать использует XPS или путь печати OpenXPS, then use the XPS Print API. Отправка заданий на печать XPS или OpenXPS в буфер печати с использованием WritePrinter не поддерживается и может привести к неопределенным результатам.

+0

Спасибо много, это решило проблему кода ошибки 1804, однако сохраненный файл на пути вывода является другим файлом spl (главным образом копией), а не файлом XPS, и окно все еще появляется, чтобы сохранить файл, хотя он появляется в странный способ с сообщением о том, что «программа не может отображать сообщение на вашем рабочем столе», поэтому можно использовать pOutputFile для указания места назначения xps, а если нет, есть ли другой способ сделать это? – MEYWD

+1

@MEYWD Я добавил к моему ответу. Боюсь, вам придется перепроектировать это. –

 Смежные вопросы

  • Нет связанных вопросов^_^