delphi - Adobe X 在启动时启用保护模式 - 通过代码禁用

标签 delphi windows-7 windows-vista adobe-reader

我们的应用程序用 Delphi 编写,生成一系列报告,其中大部分为 PDF 格式,生成后会自动打开。 Adobe X 引入了默认启用的功能“启动时启用保护模式”。 报告 pdf 文件使用“ShelExecute”打开。

var 
  pdfFile: string; 
begin 
  pdfFile := 'C:\Users\Ronaldo\Documents\appName\reports\file.pdf'; 
  ShellExecute(0, 'open', PChar(pdfFile), '', '', SW_SHOW);
  // 
end;

由于这个新的 Adob​​e Reader 新设置,在 Win 7 或 Vista 下,我们在打开文档时收到错误消息。双击该文档打开它不会出现任何问题。 有没有办法禁用 protected 方法 - 或者另一种打开文档而不出现错误的方法(解决方法)?

*更多信息*

PDF 文件正在我们的服务器应用程序上生成,流式传输到客户端,客户端生成 pdf(使用 Write) - 首先我认为这可能是问题 - 但同样,为什么双击工作正常。

我创建了一个虚拟应用程序,它什么也不做,只是使用上面相同的代码来打开 pdf,并且它可以工作。我已经检查了应用程序的权限 - 都是一样的 - 唯一的区别是,不工作的应用程序正在使用正确的安装程序安装在操作系统上 - 另一个(虚拟的)我刚刚创建并将其放在那里。

其中一条评论询问了文件关联 - 这不应该是问题,因为应用程序成功启动 Adob​​e reader - Adob​​e reader 然后给我“访问被拒绝”错误消息。双击同一个文件就可以正常工作。

新信息 - 2011 年 3 月 30 日 - 下午 2:50 - 新西兰时间

我对代码进行了更改,只是为了测试应用程序本身和虚拟应用程序之间的唯一区别。 现在,它不再自动获取文件路径和文件名,而是打开一个 OpenDialog - opendialog 的 Filename 属性用作 ShellExecute 的参数(如 Ken 回答后的注释所述) - 它可以工作。为什么当您从打开的对话框中获取文件名时,它会起作用 - 请注意,我没有从对话框中打开文件 - 我正在获取文件名,并将其用作 ShellExecute 的参数。

更新了代码示例

当用户点击“生成报告”按钮时,报告生成后会自动打开。除此之外,还有一个网格,显示到目前为止为该用户生成的所有报告 - 这是双击该网格的代码:

if GetSelectedReport <> nil then // this will check if the user selected an report
  if TReportItemState(GetSelectedReport.State)  in [risGenerated,risViewed] then // checks if the report selected is in the correct state to be displayed.
  begin
    fileName := TClientReportManager.Singleton.Directory+'\'+GetSelectedReport.Filename; // a string with the filePath + fileName
    ShellExecute(0, 'open', pchar(fileName), '','', SW_MAXIMIZE); // command to open the file
  end;

我对 Opendialog 工作的第一个猜测是,打开的对话框更改了 CurrentDir - 所以我已经尝试使用 SetCurrentDir 和 ChDir 将当前目录更改为文件所在的目录。没有成功。

在Win 7下,文件路径被转换为C:\Users\Ronaldo\Documents\CompanyName\AppName

最佳答案

我认为你不能在代码中完全禁用它;如果可以的话,它将破坏保护模式的全部目的(防止恶意软件利用 .pdf 文件关联)。不过,您也许可以通过合法的方式解决这个问题。 :)

我怀疑这与您在 ShellExecute 中使用的 open 动词有关。您假设(可能是错误的)open 动词在 Win7 的保护模式中的作用与在 Adob​​e Reader 和 Windows 的早期版本中的作用相同。 (注意:我的系统上没有安装该版本的 Acrobat;这都是猜测。)

我尝试的第一件事是更改对 ShellExecute 的调用,如下所示:

ShellExecute(0, nil, PChar(pdfFile), nil, nil, SW_NORMAL);

第一个更改是传递 nil 作为第二个参数。这告诉 Windows 您希望发生任何默认操作。例如,这可以是view而不是open

我还将文件名后面的两个参数也更改为 nil。这比使用空字符串 ('') 更具可读性。

最后的改变是在最后一个参数;我通常使用 SW_NORMAL 而不是 SW_SHOW,只是因为这告诉 Windows 以任何默认大小和位置显示它;这可能是应用程序保存的内容,并将影响用户的首选项(如果有)。

如果这不起作用,则需要在 Windows 注册表中仔细查找(小心!!)。在开始菜单的搜索控件中打开 regedit,然后导航到 HKEY_CLASSES_ROOT。向下滚动文件扩展名,直到找到 .pdf 条目,然后双击该分支。您将看到 Default,它(无论如何在我的系统上)是 AcroExch.Document,其 Content Typeapplication/pdf.

继续沿着左 Pane 中的树向下移动,直到找到 AcroExch.Document,然后将其展开。您会在那里看到一些值(同样,来 self 的机器),如下图所示。展开 Shell 分支,您将看到定义的动词以及与它们关联的命令。在我的机器上(再次),我有一个 Open 谓词,其命令设置为 "C:\Program Files (x86)\Adobe\Reader 9.0\Reader\AcroRd32.exe"“%1”

RegEdit Left Pane RegEdit Value Pane

(请耐心等待 - 我们就快到了。我保证。)

您可以通过检查默认值来了解双击的不同作用(单击左侧 Pane 中的 Shell,然后查看设置为 (Default) 的内容然后检查命令行(在上面的第二张图中,它是Open)以查看哪些开关(如果有)传递到 Acrobat Reader 应用程序。(如果您无法弄清楚是哪个开关)默认情况下,在 Windows 资源管理器中右键单击 .pdf 文件,然后查看上下文菜单中粗体项目的内容。)

如果传递的参数不是“%1”,则需要将相同的参数添加到提供给ShellExecute 的命令行中。例如,如果参数为 /v,您将对 ShellExcute 的调用修改为如下所示:

ShellExecute(0, nil, PChar(pdfFile), PChar('/v'), nil, SW_NORMAL);

关于delphi - Adobe X 在启动时启用保护模式 - 通过代码禁用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5465231/

相关文章:

c++ - 从 DLL 向 Vista 中另一个进程的窗口发送消息

javascript - 任何人都可以帮助我使用以下 JScript 吗?

multithreading - delphi 多线程文件搜索

Delphi:如果用户重新启动/关闭,Application.Run 之后的代码不会执行

git - TortoiseGit 无法在 Windows 7 上安装上下文菜单

git 命令在 git bash 中不起作用(windows 7 x64)

windows-vista - PowerEnumerate 函数返回哪些结构/数据

delphi - 即使子类定义了抽象函数,为什么我也会收到抽象错误?

mysql - delphi mysql ado连接

sqlite - 在 Win 7 上安装 SQLite ADO.NET 时出错