GETJob () Win32 Print spooler api 64bit Параметр неверный, как исправить? - PullRequest
0 голосов
/ 02 ноября 2018

Я пытаюсь заставить getJob () работать из api printerspooler в 64-битной версии.

Я использую следующее определение (как другие люди используют на SO)

[DllImport("winspool.drv", EntryPoint = "GetJob", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
public static extern bool GetJob([In] IntPtr hPrinter, [In] Int32 dwJobId, [In] Int32 Level, [Out] IntPtr lpJob, [In] Int32 cbBuf, ref IntPtr lpbSizeNeeded);

Но это работает только тогда, когда я не отлаживаю и я не в 64-битной версии.

В 64-разрядной версии я получаю Windows Ошибка: неверный параметр.

Как это исправить?

Я попытался изменить Int32 на IntPtr (4 => 8 байт в 64-битной версии) и наоборот IntPtr => Int32. безрезультатно ..

Документы здесь: https://docs.microsoft.com/en-us/windows/desktop/printdocs/getjob:

BOOL GetJob(
  _In_  HANDLE  hPrinter,
  _In_  DWORD   JobId,
  _In_  DWORD   Level,
  _Out_ LPBYTE  pJob,
  _In_  DWORD   cbBuf,
  _Out_ LPDWORD pcbNeeded
);

Я также пытался изменить ref на out и поместить ref / out в параметр lpJob, но даже это, похоже, не работает.

Что я мог попробовать дальше?

Редактировать

что, кажется, работает:

[DllImport("winspool.drv", EntryPoint = "GetJob", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
public static extern bool GetJob([In] IntPtr hPrinter, [In] Int32 dwJobId, [In] Int32 Level, [Out] byte[] lpJob, [In] Int32 cbBuf, ref Int32 lpbSizeNeeded);

и использовать его следующим образом:

public JOB_INFO_1(IntPtr hPrinter, Int32 dwJobId)
{
  var BytesWritten = new Int32();
  var ptBuf = new byte[0];


  if (PrinterMonitorComponent.ComponentTraceSwitch.TraceVerbose)
    Console.WriteLine("JOB_INFO_1 new(" + hPrinter.ToString() + "," + dwJobId.ToString() + ")");


  // \\ Get the required buffer size
  if (!UnsafeNativeMethods.GetJob(hPrinter, dwJobId, 1, ptBuf, 0, ref BytesWritten))
  {
    if (BytesWritten == 0)
    {
      var ex = new Win32Exception();
      if (PrinterMonitorComponent.ComponentTraceSwitch.TraceError)
        Console.WriteLine("{0} GetJob for JOB_INFO_1 failed on handle: {1} for job: {2} - {3}", this.GetType().ToString(), hPrinter, dwJobId, ex.Message);
      throw ex;
    }
  }

  // \\ Allocate a buffer the right size
  if (BytesWritten > 0)
    ptBuf = new byte[BytesWritten]; // Marshal.AllocHGlobal(BytesWritten);

  //Console.WriteLine($"Buffer {BytesWritten} x"); // uncommenting this code somehow breaks it again -.-
  // \\ Populate the JOB_INFO_1 structure
  if (!UnsafeNativeMethods.GetJob(hPrinter, dwJobId, 1, ptBuf, BytesWritten, ref BytesWritten))
  {
    if (PrinterMonitorComponent.ComponentTraceSwitch.TraceError)
      Console.WriteLine("GetJob for JOB_INFO_1 failed on handle: " + hPrinter.ToString() + " for job: " + dwJobId, this.GetType().ToString());
    throw new Win32Exception();
  }
  else
  {
    GCHandle handle = GCHandle.Alloc(ptBuf, GCHandleType.Pinned);
    Marshal.PtrToStructure(handle.AddrOfPinnedObject(), this);
    handle.Free();
    //Marshal.PtrToStructure(ptBuf, this);

  }

  // \\ Free the allocated memory
  //Marshal.FreeHGlobal(ptBuf);
}

edit2

, кажется, не работает, иногда, кажется, работает, но модульный тест не заметил изменений в файле csproj, поэтому я все еще тестировал 32-битную версию.

добавление следующей строки в csproj делает его работоспособным (он работает в 32-битной версии, перевод в 64-битную, не работает)

<PlatformTarget>x86</PlatformTarget>

1 Ответ

0 голосов
/ 02 ноября 2018

Похоже, это была проблема времени ...

Я тестировал на нулевом принтере, так или иначе, на 32-битной версии это в основном работало, но если перейти на 64-битную версию, то, должно быть, что-то пошло медленнее, поэтому он потерпит неудачу, то же самое для отладки.

Задание уже будет помещено в буфер, поэтому запрос информации о работе больше недоступен.

Чтобы исправить это, вы можете установить: Хранить напечатанные документы .

enter image description here

...