在我的应用程序模拟用户后,我需要获取打印机 DEVMODE 结构。只要我的体系结构与在 32 位操作系统上运行的 32 位应用程序的 Windows 体系结构相匹配,它就可以正常工作,反之亦然。但是,我对 DocumentProperties 的任何调用都失败,在 Windows 10 上出现错误代码:5(访问被拒绝),或者在 Windows 7 上模拟运行在 64 位操作系统上的应用程序的 32 位版本后出现 RPC 错误。不幸的是,由于需要与之交互的其他遗留应用程序,客户无法运行我的应用程序的 64 位版本。
有谁知道解决这个问题的方法?
这是一个演示该问题的小示例代码。您需要将其构建为 x86 应用程序并在 64 位操作系统上运行以查看问题。
// DocumentPropertiesTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <string>
#include <iostream>
#include "Winspool.h"
#include "DocumentPropertiesTest.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// The one and only application object
CWinApp theApp;
using namespace std;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
HMODULE hModule = ::GetModuleHandle(NULL);
if (hModule != NULL)
{
// initialize MFC and print and error on failure
if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
wstring username;
wstring domainName;
wstring password;
wstring printername;
int lastError;
cout << "Please specify a valid username: ";
wcin >> username;
cout << "Please specify the computer or domain name for the user. Use \".\" for this computer: ";
wcin >> domainName;
cout << "Please specify the users password: ";
wcin >> password;
cout << "Please give the printer name: ";
wcin.ignore();
getline (wcin, printername);
HANDLE pHandle;
HANDLE pPrinter;
if (LogonUser(username.c_str(), domainName.c_str(), password.c_str(), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &pHandle) != 0)
{
if (ImpersonateLoggedOnUser(pHandle) != 0)
{
PRINTER_DEFAULTS printerDefaults;
printerDefaults.pDatatype = NULL;
printerDefaults.pDevMode = NULL;
printerDefaults.DesiredAccess = PRINTER_ALL_ACCESS;
if (::OpenPrinter((LPWSTR)(printername.c_str()), &pPrinter, NULL))
{
int dSize = ::DocumentPropertiesW(NULL, pPrinter, (LPWSTR)(printername.c_str()), NULL, NULL, 0);
if (dSize > 0)
{
}
else
{
lastError = ::GetLastError();
cout << "Failed DocumentProperties with Error code: " << lastError << endl;
}
::ClosePrinter(pPrinter);
}
else
{
lastError = ::GetLastError();
cout << "Failed OpenPrinter with Error code: " << lastError << endl;
}
RevertToSelf();
}
else
{
lastError = ::GetLastError();
cout << "Failed ImpersonateLogonUser with Error code: " << lastError << endl;
}
}
else
{
lastError = ::GetLastError();
cout << "Failed LogonUser with Error code: " << lastError << endl;
}
system("pause");
}
}
else
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: GetModuleHandle failed\n"));
nRetCode = 1;
}
return nRetCode;
}