Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在64位Windows 10上运行32位应用程序时,模拟后对DocumentProperties调用的访问被拒绝_C++_Windows_X86 64_Impersonation_Print Spooler Api - Fatal编程技术网

C++ 在64位Windows 10上运行32位应用程序时,模拟后对DocumentProperties调用的访问被拒绝

C++ 在64位Windows 10上运行32位应用程序时,模拟后对DocumentProperties调用的访问被拒绝,c++,windows,x86-64,impersonation,print-spooler-api,C++,Windows,X86 64,Impersonation,Print Spooler Api,在我的应用程序模拟用户之后,我需要获取打印机DEVMODE结构。只要我的体系结构与运行在32位操作系统上的32位Windows应用程序的体系结构相匹配,就可以正常工作,反之亦然。但是,在64位操作系统上运行的32位版本的应用程序上进行模拟后,我对DocumentProperties的任何调用都会失败,错误代码为:在Windows 10上为5(访问被拒绝),或者在Windows 7上为RPC错误。不幸的是,由于需要与其他遗留应用程序交互,客户无法运行64位版本的my application 有人知

在我的应用程序模拟用户之后,我需要获取打印机DEVMODE结构。只要我的体系结构与运行在32位操作系统上的32位Windows应用程序的体系结构相匹配,就可以正常工作,反之亦然。但是,在64位操作系统上运行的32位版本的应用程序上进行模拟后,我对DocumentProperties的任何调用都会失败,错误代码为:在Windows 10上为5(访问被拒绝),或者在Windows 7上为RPC错误。不幸的是,由于需要与其他遗留应用程序交互,客户无法运行64位版本的my application

有人知道这个问题的解决方法吗

下面是一个小示例代码,它将演示这个问题。您需要将其构建为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;
}
//DocumentPropertieTest.cpp:定义控制台应用程序的入口点。
//
#包括“stdafx.h”
#包括
#包括
#包括“Winspool.h”
#包括“DocumentPropertieTest.h”
#ifdef_调试
#定义新调试\u新
#恩迪夫
//唯一的应用程序对象
CWinApp-theApp;
使用名称空间std;
int_tmain(int-argc,TCHAR*argv[],TCHAR*envp[]
{
int nRetCode=0;
HMODULE HMODULE=::GetModuleHandle(NULL);
if(hModule!=NULL)
{
//初始化MFC并打印,失败时出错
如果(!AfxWinInit(hModule,NULL,::GetCommandLine(),0))
{
//TODO:更改错误代码以满足您的需要
_tprintf(_T(“致命错误:MFC初始化失败”);
nRetCode=1;
}
其他的
{
wstring用户名;
wstring域名;
wstring密码;
wstring printername;
int lastError;
cout>用户名;
cout>域名;
cout>密码;
cout(0)
{
}
其他的
{
lastError=::GetLastError();

我可以冒昧地猜测,这是特定打印机驱动程序的问题,而不是Windows的普遍问题。值得检查是否有更新的驱动程序可以修复它。否则,看起来唯一的解决方案可能是将程序分为两部分,一部分是32位组件,另一部分是64位组件通过IPC.Harry进行操作,这是我一开始的想法,但即使是Windows提供的驱动程序,甚至是“Microsoft XPS Document Writer”,其行为都是一样的printer.Win8及更高版本在打印过程中破坏了一些东西,据我所知,Microsoft无意修复它。例如,记事本和写字板都以某种方式将无效指针传递到打印驱动程序的StartDoc入口点,但Windows捕捉到访问冲突并返回错误。非常奇怪的行为。因此,这并不让我感到惊讶考虑到在64位WIndows上打印32位应用程序时涉及splwow64.exe,所有涉及splwow64的内容都很奇怪,无法正常工作。