在使用Adobe Reader和CreateProcess打印PDF时,如何修复访问权限,而无需禁用受保护模式?

发布于 2025-01-28 12:49:55 字数 2276 浏览 4 评论 0原文

如果我手动创建shell并执行该命令,我可以使用以下命令行成功地将PDF自动打印到某些打印机。另外有效的是,例如,使用PDF和动词“打印”的上下文菜单在Windows Explorer中打印一些PDF。

"C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe" /h /n /o /s /t "C:\Users\[...]\some.pdf" "SomePrinter"

无效的是使用与createProcess的某些自定义Win32-App中完全相同的命令行。当Adobe Reader启动并试图读取文件时,不久之后就会显示出一个错误消息,因为访问被拒绝,因此无法打开该文件。当然,重要的是,我正在启动我的应用程序,该应用在同一用户下使用createProcess,例如手动从外壳成功打印时。使用Procmon,我还可以看到访问了正确的PDF,对于错误的路径或相似的路径没有问题。

解决该问题的方法是在Adobe Reader的sartup中禁用受保护的模式。但这在理论上不是必需的,因为当在外壳上手动执行时,使用上下文菜单以及不使用createProcess与某些命令行一起使用,但shellexecuteex也可以使用。 >使用动词打印。问题仅仅是Adobe阅读器需要打印不信任的PDF,因此使用受保护的模式是有道理的。此外,我的应用程序已部署到许多不同的系统上,我想避免将Adobe Reader重新配置为禁用受保护模式的管理任务。动词“打印”和shellexecuteex的缺点是我无法转发其他参数。

再次查看procmon,直到使用createProcess时,Adobe阅读器的行为似乎几乎是相同的。在这两种情况下,都创建了Acrobat.exe的实例,此后使用lowintegrity模式和一些附加的命令行参数产生了本身的附加实例:

"C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe" --type=renderer /prefetch:1  /h /n /o /s /t [...]

对我来说,这看起来像是有允许对交互式与非相互作用的使用或非相互作用的识别,而前者则被允许,第二次被拒绝。尽管我的Win32-App是32位,而Adobe Reader 64,但这似乎也不是问题所在。我用32位cmd.exe启动64位Adobe读取器进行了测试,并且事情如预期的。

以下是我启动过程的方式,除了Adobe Reader以外的任何事物:

STARTUPINFO         si;
PROCESS_INFORMATION pi;

ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);

LOG4CXX_TRACE(logger, L"Beginn CreateProcess");
if (!CreateProcess( NULL, const_cast<_TCHAR*>(cmdLine.c_str()),
                    NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
    DWORD error = GetLastError();
    LOG4CXX_ERROR(logger, L"CreateProcess: GetLastError: " << error << L"; " << cmdLine);
    return Result(cmdLine.c_str(), error);
}
LOG4CXX_TRACE(logger, L"Ende CreateProcess");

使启动命令行更加复杂,例如添加“ cmd.exe”,就像手动完成操作时一样,不会改变一件事情。最后,由于某种原因,Adobe Reader仍然被拒绝访问PDF:

"C:\WINDOWS\system32\cmd.exe" /C ""C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe" /h /n /o /s /t "\\?\C:\[...]\[...].pdf" "SomePrinter""

因此,我需要使用“ CreateProcess”来解决此问题?

谢谢!

I'm able to successfully print PDFs automatically to some printer using the following command line if I manually create the shell and execute that command. What additionally works is e.g. printing some PDf in Windows Explorer using the context menu of the PDF and the verb "print".

"C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe" /h /n /o /s /t "C:\Users\[...]\some.pdf" "SomePrinter"

What does NOT work is using the exact same command line in some custom WIN32-app with CreateProcess. While Adobe Reader starts and tries to read the file, shortly afterwards an error message is shown about that the file can't be opened because the access is denied. The important thing of course is that I'm starting my app which starts Adobe Reader using CreateProcess under the same user like when successfully printing from the shell manually. Using ProcMon I can additionally see that the correct PDF is accessed, to there's no problem with wrong paths or alike.

What resolves that issue is disabling the protected mode at sartup of Adobe Reader. BUT that shouldn't be necessary in theory, because things work when manually executed on the shell, using the context menu and as well when not using CreateProcess with some commandline, but ShellExecuteEx with the verb print instead. The problem simply is that Adobe Reader needs to print untrusted PDFs, so using protected mode makes sense. Additionally, my app is deployed to many different systems and I would like to avoid the adminitrative task of reconfiguring Adobe Reader to disable protected mode. The downside of the verb "print" and ShellExecuteEx is that I can't forward additional arguments.

Looking at ProcMon again, the behaviour of Adobe Reader seems to be pretty much the same up until a point where things not work anymore when using CreateProcess. In both cases an instance of Acrobat.exe is created, which afterwards spawns an additional instance of itself using LowIntegrity mode and some additional command line arguments:

"C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe" --type=renderer /prefetch:1  /h /n /o /s /t [...]

This looks to me like there's some recognition of interactive vs. non-interactive usage or alike and the former is allowed and the second denied. While my WIN32-app is 32 Bit and Adobe Reader 64, that doesn't seem to be the problem as well. I tested with a 32 Bit cmd.exe starting 64 Bit Adobe Reader and things work like expected.

The following is how I start processes, which works as expected for anything else than Adobe Reader:

STARTUPINFO         si;
PROCESS_INFORMATION pi;

ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);

LOG4CXX_TRACE(logger, L"Beginn CreateProcess");
if (!CreateProcess( NULL, const_cast<_TCHAR*>(cmdLine.c_str()),
                    NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
    DWORD error = GetLastError();
    LOG4CXX_ERROR(logger, L"CreateProcess: GetLastError: " << error << L"; " << cmdLine);
    return Result(cmdLine.c_str(), error);
}
LOG4CXX_TRACE(logger, L"Ende CreateProcess");

Making the started command line more complex and e.g. add "cmd.exe", like when things are done manually, doesn't change a thing. In the end Adobe Reader is still denied access to the PDF for some reason:

"C:\WINDOWS\system32\cmd.exe" /C ""C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe" /h /n /o /s /t "\\?\C:\[...]\[...].pdf" "SomePrinter""

So, what do I need to do with "CreateProcess" to fix this?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文