3

我有一个重定向的打印机端口,它使用 redmon(重定向端口监视器)和 postscript 打印机驱动程序将 postscript 转换为 pdf 并应用一些其他效果,如水印、覆盖等。在 win 7 中一切正常,但在 windows 10 中,进程在系统用户帐户。在打印机端口的配置窗口中有一个名为“以用户身份运行”的标志,在win7中,选中此标志可以让作业在用户帐户下运行。在 Windows 10 中,它似乎不起作用。任何建议将不胜感激。谢谢你。罗伊

4

1 回答 1

2

我有一个类似的问题。我需要打印文档的用户选择文档类型和患者 ID。然后将文档以 PDF 格式打印到我们的 EHR 系统。在选中“以用户身份运行”时在 Windows 7 中工作,但在 Windows 10 上不工作。Redmon 始终以“系统”运行程序。所以我在程序的开头添加了一点来检查用户名。如果是“SYSTEM”,则程序通过查找 explorer.exe 的实例来查找系统上的交互式用户。如果超过一个交互式用户登录到系统,这将失败。对我的任务来说不是问题。然后,该程序启动另一个自身的实例,该实例以与 explorer.exe 相同的用户身份运行,并传递相同的命令行。使用管道,以便可以将来自第一个实例的标准输入通过管道传输到第二个实例上的标准输入。另一个限制是在 64 位操作系统上,必须使用 64 位版本的程序。否则可能找不到 explorer.exe。

以下代码是我放在程序开头的代码。不要被从 main() 开始的程序所迷惑。我正在使用一个包含 WinMain() 然后调用 main() 的 GUII 工具包。我只在 ASCII 程序上测试过代码。我尝试使用 ASCII 版本的调用,以便它可以与非 ASCII 程序一起使用,但我不确定我是否得到了所有这些。

LogInfoSys("Hello World"); 函数只是写入日志文件。

祝你好运。

#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <time.h>
#include <direct.h>
#include <process.h>
#include <sqlext.h>
#include <Psapi.h>
#include <tlhelp32.h>

int main(int argc, char *argv[])
{
    int                                         error;
    char                                        msg[1024];

    DWORD                                       *processIDs;
    int                                         processCount;
    HANDLE                                      hProcess = NULL;
    HANDLE                                      hToken;
    char                                        userName[64];
    char                                        progName[1024];
    int                                         i, j;
    char                                        nameMe[256];
    char                                        domainMe[256];
    PTOKEN_USER                                 ptuMe = NULL;
    PROCESS_INFORMATION                         procInfo;
    STARTUPINFO                                 startUpInfo;
    HMODULE                                     *hMod;
    DWORD                                       cbNeeded;
    SECURITY_ATTRIBUTES                         saAttr;
    HANDLE                                      hChildStd_IN_Rd = NULL;
    HANDLE                                      hChildStd_IN_Wr = NULL;

    i = 64;                                 // Get user name, if it is "SYSTEM" redirect input to output to a new instance of the program
    GetUserNameA(userName, &i);
    if (_stricmp(userName, "system") == 0)
    {
        LogInfoSys("Running as SYSTEM");
        processIDs = (DWORD *)calloc(16384, sizeof(DWORD));                             // Look for explorer.exe running.  If found that should be the user we want to run as.
        EnumProcesses(processIDs, sizeof(DWORD) * 16384, &i);                           // If there is more than one that is OK as long as they are both being run by the same
        processCount = i / sizeof(DWORD);                                               // user.  If more than one user is logged on, this will be a problem.

        hMod = (HMODULE *)calloc(4096, sizeof(HMODULE));

        hProcess = NULL;
        for (i = 0; (i < processCount) && (hProcess == NULL); i++)
        {
            if (processIDs[i] == 11276)
                Sleep(0);
            if (processIDs[i] != 0)
            {
                hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processIDs[i]);
                if (hProcess != NULL)
                {
                    cbNeeded = 0;
                    error = EnumProcessModules(hProcess, hMod, sizeof(HMODULE) * 4096, &cbNeeded);
                    if (error == 0)
                    {
                        error = GetLastError();
                        Sleep(0);
                    }
                    progName[0] = 0;
                    error = GetModuleBaseNameA(hProcess, hMod[0], progName, 1024);
                    if (error == 0)
                    {
                        error = GetLastError();
                        Sleep(0);
                    }
                    if (_stricmp(progName, "explorer.exe") != 0)
                    {
                        CloseHandle(hProcess);
                        hProcess = NULL;
                    }
                    else
                    {
                        LogInfoSys("Found explorer.exe");
                    }
                }
            }
        }

        LogInfoSys("After looking for processes.");
        nameMe[0] = domainMe[0] = 0;
        if (hProcess != NULL)
        {
            saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
            saAttr.bInheritHandle = TRUE;
            saAttr.lpSecurityDescriptor = NULL;

            if (!CreatePipe(&hChildStd_IN_Rd, &hChildStd_IN_Wr, &saAttr, 0))        // Create a pipe for the child process's STDIN.
                LogInfoSys("Stdin CreatePipe error");

            if (!SetHandleInformation(hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0))     // Ensure the write handle to the pipe for STDIN is not inherited. 
                LogInfoSys("Stdin SetHandleInformation errir");

            if (OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken) != 0)
            {
                GetStartupInfo(&startUpInfo);
                startUpInfo.cb = sizeof(STARTUPINFO);
                startUpInfo.lpReserved = NULL;
                startUpInfo.lpDesktop = NULL;
                startUpInfo.lpTitle = NULL;
                startUpInfo.dwX = startUpInfo.dwY = 0;
                startUpInfo.dwXSize = 0;
                startUpInfo.dwYSize = 0;
                startUpInfo.dwXCountChars = 0;
                startUpInfo.dwYCountChars = 0;
                startUpInfo.dwFillAttribute = 0;
                startUpInfo.dwFlags |= STARTF_USESTDHANDLES;
                startUpInfo.wShowWindow = 0;
                startUpInfo.cbReserved2 = 0;
                startUpInfo.lpReserved = NULL;
                startUpInfo.hStdInput = hChildStd_IN_Rd;
                startUpInfo.hStdOutput = NULL;
                startUpInfo.hStdError = NULL;

                GetModuleFileName(NULL, progName, 1024);
                i = CreateProcessAsUserA(hToken, progName, GetCommandLine(), NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startUpInfo, &procInfo);
                if (i == 0)
                {
                    i = GetLastError();
                }

                do
                {
                    i = (int)fread(msg, 1, 1024, stdin);
                    if (i > 0)
                        WriteFile(hChildStd_IN_Wr, msg, i, &j, NULL);
                } while (i > 0);
            }
        }
        LogInfoSys("End of running as SYSTEM.");
        exit(0);
    }


    /**********************************************************************************************************
    *
    *   End of running as SYSTEM and start of running as the user that printed the document (I hope).
    *
    **********************************************************************************************************/
    exit(0);
}
于 2018-02-15T20:23:01.733 回答