【问题标题】:Adobe X Enable Protected Mode at Startup - disable via codeAdobe X 在启动时启用保护模式 - 通过代码禁用
【发布时间】:2011-07-24 19:51:26
【问题描述】:

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

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 下,我们在打开文档时收到错误消息。双击文档打开它不会有任何问题。 有没有办法禁用受保护的方法 - 或另一种方法来打开文档而不会出现错误(解决方法)?

*更多信息*

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

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

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

新信息 - 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

【问题讨论】:

  • 打开此文档时出错。访问被拒绝。
  • 能不能加上ShelExecute这句你用来打开文件的语句?
  • var pdfFile: string;开始 pdfFile := 'C:\Users\Ronaldo\Documents\appName\reports\file.pdf'; ShellExecute(0, 'open', PChar(pdfFile), '', '', SW_SHOW);
  • @Ronaldo 在 cmets 中,您可以通过将代码括在“反引号”符号中来格式化代码:`。例如A := 1; 在美式键盘上,后引号通常位于左上角,并在制表键上方加上波浪号 ~。
  • 双击使用文件关联打开。它是如何成功的?它有什么不同?

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


【解决方案1】:

我已将其抛在脑后,但现在我有时间回去尝试解决问题。

我发现,客户端应用程序正在使用 GetEnvironmentVariable('USERPROFILE') 来获取报告所在文件夹的一部分。这给了我类似 Windows 7 上的 'c:\users\user_name\' 的信息 - 然后添加一个类似“My Documents\CompanyFolder\ProductFolder”的常量。

在 win XP 下这工作正常,但在 Win 7 下,由于某种原因,UAC 似乎不允许您直接并专门引用“我的文档” - 而您需要使用“文档”。

我已更改常量以删除“我的文档”部分,并添加了一个使用参数 CSIDL_Personal 和函数检索私人用户文档文件夹的函数:

function GetSpecialFolderPath(folder : integer) : string;
const
  SHGFP_TYPE_CURRENT = 0;
var
  path: array [0..MAX_PATH] of char;
begin
  if SUCCEEDED(SHGetFolderPath(0,folder,0,SHGFP_TYPE_CURRENT,@path[0])) then
    Result := path
  else
    Result := '';
end;

并调用 GetSpecialFolderPath(CSIDL_Personal) 等函数。

感谢大家花时间发布 cmets 和答案。

只是想补充一点,这个答案在我的情况下是正确的答案。 @Ken White 的答案可能是其他人的正确答案。

【讨论】:

  • 很高兴你把它整理好了。这些类型的问题持续存在时真的很烦人。 :)
【解决方案2】:

我不认为你可以在代码中完全禁用它;如果可以的话,它将破坏保护模式的全部目的(防止恶意软件利用 .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.DocumentContent Typeapplication/pdf

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

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

您可以通过检查默认值来查看双击的不同之处(单击左侧窗格中的Shell,然后查看右侧设置为(Default) 的内容。然后检查命令行(在上面的第二张图片,它是Open)查看传递给 Acrobat Reader 应用程序的开关。(如果您无法确定哪个是默认开关,请右键单击 Windows 资源管理器中的 .pdf 文件并查看加粗的项目在上下文菜单中。)

如果传递了"%1" 以外的参数,则需要将相同的参数添加到提供给ShellExecute 的命令行中。例如,如果参数是 /v,您可以将对 ShellExcute 的调用修改为:

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

【讨论】:

  • 嘿@Ken White,感谢您花时间进行长时间的解释。我尝试了这两种方法 - 没有成功。我对代码进行了更改-当用户选择要生成的报告或从生成的报告的网格中选择它时,系统会自动抓取pdf文件的路径和pdf文件名,并执行命令。我所做的:用户现在需要从 opendialog 中选择要打开的文件 - 然后我得到 OpenDialog.FileName 并将其用作 ShellExecute 的参数 - 它可以工作。为什么会这样??????
  • @罗纳尔多:我不知道。您可以编辑原始问题以显示更多代码吗?这里发生了一些与用户权限有关的事情,或者从您目前所说的内容中不清楚的事情。
  • 如果您获得 OpenDialog 的文件名并将其传递给 ShellExecute 并且 这是唯一的区别,那么接下来要做的就是比较两个完整的路径和文件名。一些令人惊讶的事情有时会导致错误 - 我刚刚修复了一个错误,其中像 c:\foo\.\bar.txt(注意 `\.`)这样的路径会导致 Vista 的标准保存对话框中出现错误。
  • 我不知道我是否在关注你——但打开 PDF 的粗体项是“使用 Adob​​e Reader X 打开”——这是我在第四个参数中添加的内容。关于路径,它是相同的 - 我现在没有想法......
  • @Ronaldo:现在看看我解释的注册表,看看Open 命令行是什么样子的。它是否为文件名传递除“%1”以外的任何类型的参数?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-28
  • 2018-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-05
  • 1970-01-01
相关资源
最近更新 更多