LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Win32 API GetPrinter function help

Solved!
Go to solution

I am using the WInspool.drv to determine printer status.

Using that DLL, I am trying to execute the GetPrinter function.

When I execute the function, it returns an error.

Can anyone advise me what I am doing wrong?

 

My seperate functions for getting default printer, opening and closing the printer works with success.

Veni Vidi Duci
0 Kudos
Message 1 of 24
(6,492 Views)

Sorry, still on LabVIEW 2012, can't open your VI.

 

What is the error? Do you get a dialog box reporting an error, or an error on the Error Out wire, or a return value indicating a Windows error?

0 Kudos
Message 2 of 24
(6,476 Views)

I am sorry, allow me to clarify.

The error is not in the error cluster of the call library node.

What is occuring is the GetPrinter function is returning a value of 0, which is a function call failure.

I am positive the issue is my inputs into the function are incorrect. But I am not sure exactly what it is.

 

I am trying to pass the printer handle. I know this works since it works in my other functions.

I am also passing a Level of 2, a null value and size of 0 for the pointer, and pcbNeeded is a pointer return value.

I read online I should be able to pass a null by passing int32 value of 0. I think that is what I am doing.

 

I tested this function in C using the following example code sample, and I am trying to duplicate it in LabVIEW.

DWORD cByteNeeded;

GetPrinter(hPrinter, 2, NULL, 0, &cByteNeeded)

Veni Vidi Duci
0 Kudos
Message 3 of 24
(6,466 Views)

You have messed up the pPrinter input, it is a buffer of length cbBuf, not a single byte.  I actually call this function twice, like many WinAPI functions it will tell you the buffer size you need (Always 144 on my 32-bit system).  On the first call pPrinter is an empty U8 array and cbBuf is the length of this array (0).  For the second call I use initialize Array to create an array of U8 with length given by pcbNeeded which is also wired to cbBuf and pcbNeeded for the second call.

 

You could probably just provide a safe, large value for the buffer, but I usually just use the two-step approach.

0 Kudos
Message 4 of 24
(6,463 Views)

So are you saying I need to make the input pointer an array rather than a single variable?

Are there any examples?

 

Thank's for the advice. It's greatly appreciated.

Veni Vidi Duci
0 Kudos
Message 5 of 24
(6,455 Views)

What you call pPrinter needs to be an Array of type U8, choose 'Array Data Pointer'.  You don't need the cluster, the only inputs you need to supply are the handle and the level.

0 Kudos
Message 6 of 24
(6,434 Views)

I updated my VI, attached. The function now returns error 1097.

I would think you need more than just Level, pPrinter and the handle. If the API is a C function, shouldn't I have to pass all the inputs it requires?

Or does LabVIEW automatically ignore all of that?

 

MSDN resource for GetPrinter

https://msdn.microsoft.com/en-us/library/windows/desktop/dd144911(v=vs.85).aspx

 

BOOL GetPrinter(
  _In_  HANDLE  hPrinter,
  _In_  DWORD   Level,
  _Out_ LPBYTE  pPrinter,
  _In_  DWORD   cbBuf,
  _Out_ LPDWORD pcbNeeded
);

Veni Vidi Duci
0 Kudos
Message 7 of 24
(6,419 Views)

You need to configure all the parameters in the Call Library Function Node. You do not need to actually wire values to all the parameters; LabVIEW will supply default values (for example, numeric values default to 0). When you are passing anything more than a scalar by pointer (a string or an array), you do need to pre-allocate in LabVIEW.

 

You should call GetPrinter twice. The first time, you only need to wire the hPrinter and Level. Take the pcbNeeded output from that call, and initialize an array of U8 to that size, then call GetPrinter a second time. For the second call, wire the initialized array to pPrinter, and the array size to cbBuf. You'll then need to convert the array output to the desired data, based on Level. The embedded strings in the output struct will be annoying because you'll need to copy the data from the pointer location into LabVIEW strings, and you don't know the length of those strings, but you could make it work.

0 Kudos
Message 8 of 24
(6,385 Views)

If I do not wire cbBuf or pcbNeeded, I get a compile issue and the VI will not execute.

If I wire default values to these inputs, the function will return a 0, which is a failure.

My function prototype is:

 

int32_t GetPrinterA(int32_t handle, uint32_t level, uint8_t *pPrinter, uint32_t cbBuf , uint32_t *pcbNeeded);

 

I understand the function needs to be run twice. But should it not return a non-zero answer for the first run?

I am building the program up one step at a time.

Veni Vidi Duci
0 Kudos
Message 9 of 24
(6,376 Views)

If you save for previous, for LabVIEW 2012, I'll take a look. Please be more specific than "a compile issue." What's the exact text? Make sure you're using the correct calling convention. Nearly all Windows API functions use WINAPI.

0 Kudos
Message 10 of 24
(6,360 Views)