Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

pausing a job

Posted on 2010-09-22
20
Medium Priority
?
784 Views
Last Modified: 2013-11-08
Dear experts

I am plying about with the WMI settings on C++

What i am trying to do is resume a paused job. However I cant do it with the SetJob command

It deletes the job but it doesnt resume

On both i am getting a result of 1 which indicates Setjob occured successfully

any idea how to fix this

I have set the printer to pause using SetPrinter
if thats the reason for my problems how do i pause a print job if the default settings of a printer are not set to pause?
INT MonitorPrinter(char *pPrinter)
{
	int iIndex = 0;
	DWORD dwNeeded, dwRet, dwPrinterStatus;
	HANDLE hPrinter=NULL; 
	HANDLE hWait;


	JOB_INFO_2  *pJobs=NULL;
	int iJobs, iTempIndex;
	int jobid=4;
	int c;
//	int id1=atoi(id);







	PRINTER_DEFAULTS pd;
	pd.pDatatype = NULL;
	pd.pDevMode = NULL;
	pd.DesiredAccess = PRINTER_ALL_ACCESS;


	if(!OpenPrinter(pPrinter,&hPrinter,&pd)) 
	{
		DisplayError("OpenPrinter Failed");
		return FALSE;
	}


	GetJobs(hPrinter,       
		&pJobs, /* Pointer to be filled.  */ 
		&iJobs,            /* Count of jobs filled.  */ 
	
		&dwPrinterStatus);         /* Print Queue status.    */ 

for (iIndex = 0; iIndex < iJobs; iIndex++)
	{

	int check =pJobs[iIndex].JobId;

		//if (id1 == check)
		
		{
	char *user="working";
	pJobs[0].pUserName=user;	
//	pJobs[0].pStatus=JOB_STATUS_PRINTING;
	printf("Username is %s\n", pJobs[0].pUserName);
	
	
	c =	SetJob(hPrinter, pJobs[iIndex].JobId, 2, (LPBYTE) pJobs,JOB_CONTROL_RESUME);

	printf("Result is %d\n",c);
}
}


	return (0);
}

Open in new window

0
Comment
Question by:samelamin
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 12
  • 7
20 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 33734662
'JOB_CONTROL_RELEASE' seems to be the problem - try
	c =	SetJob(hPrinter, pJobs[iIndex].JobId, 2, (LPBYTE) pJobs,JOB_CONTROL_RESUME);

Open in new window

0
 

Author Comment

by:samelamin
ID: 33734702
Ive tried that too
Its why i changed it to JOB_CONTROL_RESUME, and ive updated the code
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 33734860
Hi samelamin,

is the job still deleted with 'JOB_CONTROL_RESUME'? Is it the same if you don't set a user name? What is 'GetJobs'? Is it a function you wrote? Seems not to be a GDI function ...

ZOPPO

0
Vim Reference Guide

Vim is a powerful text editor favored by many sysadmins and developers - here are some commands that you'll want to keep in your back pocket!

 

Author Comment

by:samelamin
ID: 33734972
It is yes
GetJobs will fill the Job_INFO_2 structure with the given jobs in the printer.

What is odd is i am using SetPrinter to change the default settings to pause, but when i print to it the job status is just "Ready" instead of paused

Even if i set aprint job to pause using the windows console and use SETJOB to change it to resume it still does not work

Ami not pausing the printer properly?
if (command==1)
	{
	
    SetPrinter(hPrinter, 0, NULL, PRINTER_CONTROL_PAUSE);

	printf("Setting printer %s to pause\n",Printer);
	}
	else if(command==2)
	{
	SetPrinter(hPrinter, 0, NULL, PRINTER_CONTROL_RESUME);
	printf("Setting printer %s to resume\n",Printer);

Open in new window

0
 
LVL 31

Expert Comment

by:Zoppo
ID: 33735568
I'm not sure if I understand correctly, but if so I think you mix up printer and job status - if the printer is PAUSED a new job may even be READY - pausing and resuming the job won't do anything as long as the printer is PAUSED.
0
 

Author Comment

by:samelamin
ID: 33735640
I thought so

So how do i set the printer to be paused to allow all jobs given to it to be paused?
0
 

Author Comment

by:samelamin
ID: 33735677
IF i understand your comment Zoppe the underlying setting for a printer should be resume.

Given that how do i set all jobs given to it to be paused?
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 33735823
Hm - I'm not sure if there's an easy way - only thing I can think of is to set the printer to PAUSED, then set all jobs to be PAUSED, the re-set the printer to READY ... but thus you cannot ensure that i.e. a new printer job is started while the printer is READY - maybe there are ways to somehow implement that your app gets notified if a new print job is started, but unfortunateley I haven't such deep knowledge of the print/spooler stuff ...
0
 

Author Comment

by:samelamin
ID: 33735950
I did that too but what i thought was once i set the printer to ready all the jobs will resume
0
 

Author Comment

by:samelamin
ID: 33742307
OK i have a question

How do i pause a printer, because it isnt really paused its shown as ready, how do i make the status change to paused

Also Zoppo I tried your solution unfortunately when i pause a printer then print
the moment i change it to resume it resumes the first job in the queue

So it doesnt allow me to choose when i want to resume the job.
0
 
LVL 31

Accepted Solution

by:
Zoppo earned 2000 total points
ID: 33742460
Hm - that's strange - IMO pausing/resuming the printer should work.

I attach the code of a small command line program I wrote - this simply toggles the PAUSED state of my local printer 'PDFCreator' (you can replace the printer name in 'main') - if I run it the state of the printer is shown correctly.

> when i pause a printer then print the moment i change it to resume it resumes the first job in the queue
IMO this should only happen if the print job is READY - it shouldn't happen if for all jobs the state is PAUSED ...

ZOPPO
#include <windows.h>
#include <iostream>

bool TogglePrinterState( char* pszPrinter )
{
	HANDLE hPrinter = NULL;
	PRINTER_DEFAULTS pd;
	pd.pDatatype = NULL;
	pd.pDevMode = NULL;
	pd.DesiredAccess = PRINTER_ALL_ACCESS;


	if ( FALSE == OpenPrinter( pszPrinter, &hPrinter, &pd ) )
	{
		std::cout << "Error: cannot open printer '" << pszPrinter << "' (ec: " << GetLastError() << ")" << std::endl;
		return false;
	}

	bool bRet = true;

	DWORD dwLen = 0;
	PRINTER_INFO_2* pInfo = NULL;

	if ( FALSE == GetPrinter( hPrinter, 2, NULL, 0, &dwLen ) )
	{
		if ( GetLastError() == 122 && dwLen > 0 )
		{
			pInfo = (PRINTER_INFO_2*)new BYTE[ dwLen ];

			if ( FALSE == GetPrinter( hPrinter, 2, (LPBYTE)pInfo, dwLen, &dwLen ) )
			{
				std::cout << "Error calling 'GetPrinter' (ec: " << GetLastError() << ")" << std::endl;
				bRet = false;

				goto clean_up;
			}
		}
	}

	if ( 0 != ( pInfo->Status & PRINTER_STATUS_PAUSED ) )
	{
		if ( FALSE != SetPrinter( hPrinter, 0, NULL, PRINTER_CONTROL_RESUME ) )
		{
			std::cout << "Resumed printer '" << pszPrinter << "' ..." << std::endl;
		}
	}
	else
	{
		if ( FALSE != SetPrinter( hPrinter, 0, NULL, PRINTER_CONTROL_PAUSE ) )
		{
			std::cout << "Paused printer '" << pszPrinter << "' ..." << std::endl;
		}
	}

clean_up:
	delete [] pInfo;

	CloseHandle( hPrinter );

	return bRet;
}

int main(int argc, char* argv[])
{
	TogglePrinterState( "PDFCreator" );
	return 0;
}

Open in new window

0
 

Author Comment

by:samelamin
ID: 33742609
Thanks for this

But this will toggle the pause, when you toggle the resume do all jobs start resuming or do they stay paused?>
0
 

Author Comment

by:samelamin
ID: 33742632
Yup it starts resuming everything as soon as i toggle it back so thats not going to work
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 33742634
When the printer's state is resumed using this code only those jobs which aren't paused start printing - the paused ones still keep as 'Paused' in the job list ...
0
 

Author Comment

by:samelamin
ID: 33742647
oh I think i get you
You mean i have to:

1) Toggle printer to pause
2) print document then set status to pause
3)resume the printer

Is that what you mean?
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 33742658
Yes, exactly - changing printer's state doesn't anyhow affect the job's states, so you have to control them both ...
0
 

Author Comment

by:samelamin
ID: 33742678
OK when i set a jobs status to pause it still doesnt chage its actual status from ready to pause

here is how i am changing the status
c =	SetJob(hPrinter, pJobs[iIndex].JobId, 2, (LPBYTE) pJobs,JOB_CONTROL_PAUSE);

Open in new window

0
 

Author Comment

by:samelamin
ID: 33742777
Got it working

It was due to the fact i had pJobs refrenced. It should be NULL

Anyways thank you Zoppo

Its annoying to switch it to paused,print document and pause it, then again resume the printer

But oh well thank you
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 33742879
Fine, I'm glad I could help you so far. But, as told, there might be better solutions which I just don't know - i.e. there's a "Print Monitor API" which might give you the ability to intercept print-spooler calls, but I simply don't know if this can be used for your purpose since I never used it.

BTW: Are the print jobs started by your application or by third party applications? If it's yours you should be able to simply start the jobs in a resumed state ...

Have a nice day,

best regards,

ZOPPO
0
 

Author Comment

by:samelamin
ID: 33742899
Well for testing purposes im just printing Test Pages so i suppose it is me who starts them

But in future it may be started by someone else but my application will always have admin rights
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
In this tutorial I will show you how to provide a dynamic RTF document on your website generated with data from your database. For this tutorial you will need Microsoft Word or WordPad, WhizBase and Microsoft Access. In this tutorial I will show …
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

688 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question