プリンタの監視(C言語)

キーワード:

OpenPrinter, FindFirstChangeNotificaition, ClosePrinter, WaitForSingleObject, FindNextPrinterChangeNotification, FreePrinterNotifyInfo, FindClosePrinterChangeNotification

サンプルコード:

void DoPrtNotify()
{
	HANDLE hPrinter = INVALID_HANDLE_VALUE;
	HANDLE hNotify;
	BOOL b;
	PRINTER_NOTIFY_INFO *p;
	DWORD i;
	char *pBuf;
	DWORD *adwData;

	PRINTER_NOTIFY_OPTIONS no;
	PRINTER_NOTIFY_OPTIONS_TYPE not[2];
	WORD pnf[100], jnf[100];
	DWORD ChangeReason;

	no.Version = 2;
	no.Count = 2;
	no.pTypes = not;

	i = 0;
	pnf[i++] = PRINTER_NOTIFY_FIELD_SERVER_NAME;
	pnf[i++] = PRINTER_NOTIFY_FIELD_PRINTER_NAME;
	pnf[i++] = PRINTER_NOTIFY_FIELD_SHARE_NAME;
	pnf[i++] = PRINTER_NOTIFY_FIELD_PORT_NAME;
	pnf[i++] = PRINTER_NOTIFY_FIELD_DRIVER_NAME;
	pnf[i++] = PRINTER_NOTIFY_FIELD_COMMENT;
	pnf[i++] = PRINTER_NOTIFY_FIELD_LOCATION;
	pnf[i++] = PRINTER_NOTIFY_FIELD_SEPFILE;
	pnf[i++] = PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR;
	pnf[i++] = PRINTER_NOTIFY_FIELD_PARAMETERS;
	pnf[i++] = PRINTER_NOTIFY_FIELD_DATATYPE;
	pnf[i++] = PRINTER_NOTIFY_FIELD_ATTRIBUTES;
	pnf[i++] = PRINTER_NOTIFY_FIELD_PRIORITY;
	pnf[i++] = PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY;
	pnf[i++] = PRINTER_NOTIFY_FIELD_START_TIME;
	pnf[i++] = PRINTER_NOTIFY_FIELD_UNTIL_TIME;
	pnf[i++] = PRINTER_NOTIFY_FIELD_STATUS_STRING;
	pnf[i++] = PRINTER_NOTIFY_FIELD_CJOBS;
	pnf[i++] = PRINTER_NOTIFY_FIELD_AVERAGE_PPM;
	pnf[i++] = PRINTER_NOTIFY_FIELD_TOTAL_PAGES;
	pnf[i++] = PRINTER_NOTIFY_FIELD_PAGES_PRINTED;
	pnf[i++] = PRINTER_NOTIFY_FIELD_TOTAL_BYTES;
	pnf[i++] = PRINTER_NOTIFY_FIELD_BYTES_PRINTED;

	not[0].Type = PRINTER_NOTIFY_TYPE;
	not[0].Count = i;
	not[0].pFields = pnf;

	i=0;
	jnf[i++] = JOB_NOTIFY_FIELD_PRINTER_NAME;
	jnf[i++] = JOB_NOTIFY_FIELD_MACHINE_NAME;
	jnf[i++] = JOB_NOTIFY_FIELD_PORT_NAME;
	jnf[i++] = JOB_NOTIFY_FIELD_USER_NAME;
	jnf[i++] = JOB_NOTIFY_FIELD_NOTIFY_NAME;
	jnf[i++] = JOB_NOTIFY_FIELD_DATATYPE;
	jnf[i++] = JOB_NOTIFY_FIELD_PRINT_PROCESSOR;
	jnf[i++] = JOB_NOTIFY_FIELD_PARAMETERS;
	jnf[i++] = JOB_NOTIFY_FIELD_DRIVER_NAME;
	jnf[i++] = JOB_NOTIFY_FIELD_STATUS_STRING;
	jnf[i++] = JOB_NOTIFY_FIELD_DOCUMENT;
	jnf[i++] = JOB_NOTIFY_FIELD_PRIORITY;
	jnf[i++] = JOB_NOTIFY_FIELD_POSITION;
	jnf[i++] = JOB_NOTIFY_FIELD_START_TIME;
	jnf[i++] = JOB_NOTIFY_FIELD_UNTIL_TIME;
	jnf[i++] = JOB_NOTIFY_FIELD_TIME;
	jnf[i++] = JOB_NOTIFY_FIELD_TOTAL_PAGES;
	jnf[i++] = JOB_NOTIFY_FIELD_PAGES_PRINTED;
	jnf[i++] = JOB_NOTIFY_FIELD_TOTAL_BYTES;
	jnf[i++] = JOB_NOTIFY_FIELD_BYTES_PRINTED;

	not[1].Type = JOB_NOTIFY_TYPE;
	not[1].Count = 20;
	not[1].pFields = jnf;


	b = OpenPrinter(
		"\\\\ringo\\ringoprt",
		&hPrinter,
		NULL);

	if(!b) {
		printf("printer can not open(%d)\n", GetLastError());
		return;
	}

	hNotify = FindFirstPrinterChangeNotification(
		hPrinter,
		PRINTER_CHANGE_ALL,
		0,
		&no);

	if(hNotify == INVALID_HANDLE_VALUE) {
		printf("find first fail(%d)\n", GetLastError());
		ClosePrinter(hPrinter);
		return;
	}

	for(;;) {

		WaitForSingleObject(hNotify, INFINITE);

		no.Flags = 0; 

		b = FindNextPrinterChangeNotification(
			hNotify,
			&ChangeReason,
			&no,
			&p);

		if(!b) printf("find next error(%d)\n", GetLastError());

		printf("\nイベント発生...\n");
		printf("\t通知理由: ");

		if(ChangeReason & PRINTER_CHANGE_ADD_PRINTER) printf("プリンタ追加 ");
		if(ChangeReason & PRINTER_CHANGE_SET_PRINTER) printf("プリンタの設定変更 " );
		if(ChangeReason & PRINTER_CHANGE_DELETE_PRINTER) printf("プリンタ削除 ");
		if(ChangeReason & PRINTER_CHANGE_FAILED_CONNECTION_PRINTER) printf("接続失敗 ");
		if(ChangeReason & PRINTER_CHANGE_ADD_JOB) printf("ジョブ追加 ");
		if(ChangeReason & PRINTER_CHANGE_SET_JOB) printf("ジョブ設定変更 ");
		if(ChangeReason & PRINTER_CHANGE_DELETE_JOB) printf("ジョブ削除 ");
		if(ChangeReason & PRINTER_CHANGE_WRITE_JOB) printf("ジョブ書き込み ");
		if(ChangeReason & PRINTER_CHANGE_ADD_FORM) printf("フォーム追加 ");
		if(ChangeReason & PRINTER_CHANGE_SET_FORM) printf("フォーム設定変更 ");
		if(ChangeReason & PRINTER_CHANGE_DELETE_FORM) printf("フォーム削除 ");
		if(ChangeReason & PRINTER_CHANGE_ADD_PORT) printf("ポート追加 ");
		if(ChangeReason & PRINTER_CHANGE_CONFIGURE_PORT) printf("ポート設定変更 ");
		if(ChangeReason & PRINTER_CHANGE_DELETE_PORT) printf("ポート削除 ");
		if(ChangeReason & PRINTER_CHANGE_ADD_PRINT_PROCESSOR) printf("プリントプロセッサ追加 ");
		if(ChangeReason & PRINTER_CHANGE_DELETE_PRINT_PROCESSOR) printf("プリントプロセッサ削除 ");
		if(ChangeReason & PRINTER_CHANGE_ADD_PRINTER_DRIVER) printf("ドライバ追加 ");
		if(ChangeReason & PRINTER_CHANGE_SET_PRINTER_DRIVER) printf("ドライバ設定変更 ");
		if(ChangeReason & PRINTER_CHANGE_DELETE_PRINTER_DRIVER) printf("ドライバ削除 ");
		if(ChangeReason & PRINTER_CHANGE_TIMEOUT) printf("タイムアウト ");
		printf("\n");

		if(p != NULL) {
			for(i=0; i<p->Count; i++) {
				pBuf = p->aData[i].NotifyData.Data.pBuf;
				adwData = p->aData[i].NotifyData.adwData;

				switch(p->aData[i].Type) {
				case PRINTER_NOTIFY_TYPE:
					printf("\tプリンタ通知(no.%d)...", i);
					switch(p->aData[i].Field) {
					case PRINTER_NOTIFY_FIELD_SERVER_NAME:
						printf("サーバ名:%s\n", pBuf);
						break;
					case PRINTER_NOTIFY_FIELD_PRINTER_NAME:
						printf("プリンタ名:%s\n", pBuf);
						break; 
					case PRINTER_NOTIFY_FIELD_SHARE_NAME:
						printf("共有名:%s\n", pBuf);
						break;
					case PRINTER_NOTIFY_FIELD_PORT_NAME:
						printf("ポート名:%s\n", pBuf);
						break;
					case PRINTER_NOTIFY_FIELD_DRIVER_NAME:
						printf("ドライバ名:%s\n", pBuf);
						break;
					case PRINTER_NOTIFY_FIELD_COMMENT:
						printf("プリンタの説明:%s\n", pBuf);
						break;
					case PRINTER_NOTIFY_FIELD_LOCATION:
						printf("設置場所:%s\n", pBuf);
						break;
					case PRINTER_NOTIFY_FIELD_DEVMODE:
						// DEVMODE structure
						break;
					case PRINTER_NOTIFY_FIELD_SEPFILE:
						printf("区切りファイル名:%s\n", pBuf);
						break;
					case PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR:
						printf("プリントプロセッサ名:%s\n", pBuf);
						break;
					case PRINTER_NOTIFY_FIELD_PARAMETERS:
						printf("プリントプロセッサのパラメータ:%s\n", pBuf);
						break;
					case PRINTER_NOTIFY_FIELD_DATATYPE:
						printf("データの種類:%s\n", pBuf);
						break;
					case PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR:
						// SECURITY_DESCRIPTOR
						break;
					case PRINTER_NOTIFY_FIELD_ATTRIBUTES:
						printf("プリンタの状態:\n");
						if(PRINTER_ATTRIBUTE_QUEUED & adwData[0]) printf("\t\tキュー\n");
						if(PRINTER_ATTRIBUTE_DIRECT & adwData[0]) printf("\t\tプリンタに直接データを送る\n");
						if(PRINTER_ATTRIBUTE_DEFAULT & adwData[0]) printf("\t\tデフォルト\n");
						if(PRINTER_ATTRIBUTE_SHARED & adwData[0]) printf("\t\t共有する\n");
						if(PRINTER_ATTRIBUTE_NETWORK & adwData[0]) printf("\t\tネットワーク\n");
						if(PRINTER_ATTRIBUTE_HIDDEN & adwData[0]) printf("\t\t隠しプリンタ\n");
						if(PRINTER_ATTRIBUTE_LOCAL & adwData[0]) printf("\t\tローカルプリンタ\n");
						if(PRINTER_ATTRIBUTE_ENABLE_DEVQ & adwData[0]) printf("\t\t一致しないドキュメントを保留する\n");
						if(PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS & adwData[0]) printf("\t\t印刷後ドキュメントを残す\n");
						if(PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST & adwData[0]) printf("\t\tスプールされたドキュメントを最初に印刷する\n");
						if(PRINTER_ATTRIBUTE_WORK_OFFLINE & adwData[0]) printf("\t\tオフライン印刷\n");
						if(PRINTER_ATTRIBUTE_ENABLE_BIDI & adwData[0]) printf("\t\tenable BIDI(?)\n");
						if(PRINTER_ATTRIBUTE_RAW_ONLY & adwData[0]) printf("\t\t直接データ送信のみ\n");
						break;
					case PRINTER_NOTIFY_FIELD_PRIORITY:
						printf("現在の優先度:%d\n", adwData[0]);
						break;
					case PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY:
						printf("デフォルトの優先度:%d\n", adwData[0]);
						break;
					case PRINTER_NOTIFY_FIELD_START_TIME:
						printf("利用可能となる開始時間:%02d:%02d\n", adwData[0]/60, adwData[0]%60);
						break;
					case PRINTER_NOTIFY_FIELD_UNTIL_TIME:
						printf("利用不可能になる時間:%02d:%02d\n", adwData[0]/60, adwData[0]%60);
						break;
					case PRINTER_NOTIFY_FIELD_STATUS:
						if(adwData[0] & PRINTER_STATUS_PAUSED) printf("一時停止 ");
						if(adwData[0] & PRINTER_STATUS_ERROR) printf("エラー ");
						if(adwData[0] & PRINTER_STATUS_PENDING_DELETION) printf("pending_deletion ");
						if(adwData[0] & PRINTER_STATUS_PAPER_JAM) printf("紙詰まり ");
						if(adwData[0] & PRINTER_STATUS_PAPER_OUT) printf("紙排出 ");
						if(adwData[0] & PRINTER_STATUS_MANUAL_FEED) printf("manual_feed ");
						if(adwData[0] & PRINTER_STATUS_PAPER_PROBLEM) printf("紙の問題 ");
						if(adwData[0] & PRINTER_STATUS_OFFLINE) printf("オフライン ");
						if(adwData[0] & PRINTER_STATUS_IO_ACTIVE) printf("io_active ");
						if(adwData[0] & PRINTER_STATUS_BUSY) printf("busy ");
						if(adwData[0] & PRINTER_STATUS_PRINTING) printf("印刷中 ");
						if(adwData[0] & PRINTER_STATUS_OUTPUT_BIN_FULL) printf("output_bin_full ");
						if(adwData[0] & PRINTER_STATUS_NOT_AVAILABLE) printf("not_available ");
						if(adwData[0] & PRINTER_STATUS_WAITING) printf("待機中 ");
						if(adwData[0] & PRINTER_STATUS_PROCESSING) printf("処理中 ");
						if(adwData[0] & PRINTER_STATUS_INITIALIZING) printf("初期化中 ");
						if(adwData[0] & PRINTER_STATUS_WARMING_UP) printf("warming_up ");
						if(adwData[0] & PRINTER_STATUS_TONER_LOW) printf("トナーが少ない ");
						if(adwData[0] & PRINTER_STATUS_NO_TONER) printf("トナーが無い ");
						if(adwData[0] & PRINTER_STATUS_PAGE_PUNT) printf("page_punt ");
						if(adwData[0] & PRINTER_STATUS_USER_INTERVENTION) printf("user_intervention ");
						if(adwData[0] & PRINTER_STATUS_OUT_OF_MEMORY) printf("out_of_memory ");
						if(adwData[0] & PRINTER_STATUS_DOOR_OPEN) printf("door_open ");
						if(adwData[0] & PRINTER_STATUS_SERVER_UNKNOWN) printf("server_unknown ");
						if(adwData[0] & PRINTER_STATUS_POWER_SAVE) printf("power_save ");
							
						break;
					case PRINTER_NOTIFY_FIELD_STATUS_STRING:
						printf("状態:%d\n", pBuf);
					case PRINTER_NOTIFY_FIELD_CJOBS:
						printf("キューにためられたジョブの数:%d\n", adwData[0]);
						break;
					case PRINTER_NOTIFY_FIELD_AVERAGE_PPM:
						printf("1ページあたりの平均印刷時間:%d分\n", adwData[0]);
						break;
					case PRINTER_NOTIFY_FIELD_TOTAL_PAGES:
						printf("総ページ数:%d\n", adwData[0]);
						break;
					case PRINTER_NOTIFY_FIELD_PAGES_PRINTED:
						printf("印刷ページ数:%d\n", adwData[0]);
						break;
					case PRINTER_NOTIFY_FIELD_TOTAL_BYTES:
						printf("総バイト数:%d\n", adwData[0]);
						break;
					case PRINTER_NOTIFY_FIELD_BYTES_PRINTED:
						printf("印刷バイト数:%d\n", adwData[0]);
						break;
					}
					break;
				case JOB_NOTIFY_TYPE:
					printf("\tジョブ通知(no.%d, id:%d)...", i, p->aData[i].Id);
					switch(p->aData[i].Field) {
					case JOB_NOTIFY_FIELD_PRINTER_NAME:
						printf("プリンタ名:%s\n", pBuf);
						break;
					case JOB_NOTIFY_FIELD_MACHINE_NAME:
						printf("ジョブ作成元マシン名:%s\n", pBuf);
						break;
					case JOB_NOTIFY_FIELD_PORT_NAME:
						printf("ポート:%s\n", pBuf);
						break;
					case JOB_NOTIFY_FIELD_USER_NAME:
						printf("ジョブ作成元ユーザ名:%s\n", pBuf);
						break;
					case JOB_NOTIFY_FIELD_NOTIFY_NAME:
						printf("通知先ユーザ:%s\n", pBuf);
						break;
					case JOB_NOTIFY_FIELD_DATATYPE:
						printf("データの種類:%s\n", pBuf);
						break;
					case JOB_NOTIFY_FIELD_PRINT_PROCESSOR:
						printf("プリントプロセッサ名:%s\n", pBuf);
						break;
					case JOB_NOTIFY_FIELD_PARAMETERS:
						printf("プリントプロセッサへのパラメータ:%s\n", pBuf);
						break;
					case JOB_NOTIFY_FIELD_DRIVER_NAME:
						printf("ドライバ名:%s\n", pBuf);
						break;
					case JOB_NOTIFY_FIELD_DEVMODE:
						// DEVMODE
						break;
					case JOB_NOTIFY_FIELD_STATUS:
						printf("ジョブの状態(flag):");
						if(adwData[0] & JOB_STATUS_PAUSED) printf("一時停止 ");
						if(adwData[0] & JOB_STATUS_ERROR) printf("エラー ");
						if(adwData[0] & JOB_STATUS_DELETING) printf("削除中 ");
						if(adwData[0] & JOB_STATUS_SPOOLING) printf("スプール中 ");
						if(adwData[0] & JOB_STATUS_PRINTING) printf("印刷中 ");
						if(adwData[0] & JOB_STATUS_OFFLINE) printf("オフライン ");
						if(adwData[0] & JOB_STATUS_PAPEROUT) printf("出力中 ");
						if(adwData[0] & JOB_STATUS_PRINTED) printf("印刷終了 ");
						if(adwData[0] & JOB_STATUS_DELETED) printf("削除終了 ");
						if(adwData[0] & JOB_STATUS_BLOCKED_DEVQ) printf("blocked_dev_queue ");
						if(adwData[0] & JOB_STATUS_USER_INTERVENTION) printf("user_intervention ");
						if(adwData[0] & JOB_STATUS_RESTART) printf("リスタート ");
						printf("\n");
						break;
					case JOB_NOTIFY_FIELD_STATUS_STRING:
						printf("ジョブの状態(msg):%s\n", pBuf);
						break;
					case JOB_NOTIFY_FIELD_DOCUMENT:
						printf("ドキュメント名:%s\n", pBuf);
						break;
					case JOB_NOTIFY_FIELD_PRIORITY:
						printf("優先度:%d\n", adwData[0]);
						break;
					case JOB_NOTIFY_FIELD_POSITION:
						printf("順番:%d\n", adwData[0]);
						break;
					case JOB_NOTIFY_FIELD_SUBMITTED:
						//SYSTEMTIME
						break;
					case JOB_NOTIFY_FIELD_START_TIME:
						printf("印刷開始時間: %d:%d\n", adwData[0]/60, adwData[0]%60);
						break;
					case JOB_NOTIFY_FIELD_UNTIL_TIME:
						printf("印刷終了時間: %d:%d\n", adwData[0]/60, adwData[0]%60);
						break;
					case JOB_NOTIFY_FIELD_TIME:
						printf("経過時間: %d: %d\n", adwData[0]/60, adwData[0]%60);
						break;
					case JOB_NOTIFY_FIELD_TOTAL_PAGES:
						printf("印刷総枚数: %d\n", adwData[0]);
						break;
					case JOB_NOTIFY_FIELD_PAGES_PRINTED:
						printf("印刷枚数: %d\n", adwData[0]);
						break;
					case JOB_NOTIFY_FIELD_TOTAL_BYTES:
						printf("総バイト数: %d\n", adwData[0]);
						break;
					case JOB_NOTIFY_FIELD_BYTES_PRINTED:
						printf("印刷バイト数: %d\n", adwData[0]);
						break;
					}
					break;
				}
			}
			b = FreePrinterNotifyInfo(p);
			if(!b) printf("free error:%d\n", GetLastError());
		}
	}
	if(hPrinter!=INVALID_HANDLE_VALUE) {
		ClosePrinter(hPrinter);
		FindClosePrinterChangeNotification(hNotify);
	}
}
(original text:1998/12/25 更新)

本ドキュメントの内容は保証しません。本ドキュメントによって生じた結果について、一切の責任を負いません。