ron*_*ana 6 delphi adobe-reader windows-vista windows-7
我们的应用程序在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;
Run Code Online (Sandbox Code Playgroud)
由于这个新的Adobe Reader新设置,在Win 7或Vista下,我们在打开文档时收到错误消息.双击文档打开它没有任何问题.有没有办法禁用受保护的方法 - 或打开文档的另一种方法,而不会得到错误(解决方法)?
*更多信息*
PDF文件正在我们的服务器应用程序上生成,流式传输到客户端,客户端生成pdf(使用Write) - 首先我虽然这可能是问题 - 但同样,为什么双击工作正常.
我创建了一个虚拟应用程序,除了使用相同的上述代码打开pdf之外什么都不做,它可以工作.我已经检查了应用程序的权限 - 完全相同 - 唯一的区别是,使用适当的安装程序在操作系统上安装了无效的安装程序 - 我刚创建的另一个(虚拟安装程序)并将其放在那里.
其中一条评论询问文件关联 - 这应该不是一个问题,因为应用程序成功启动Adobe阅读器 - Adobe阅读器然后给我"访问被拒绝"错误消息.双击同一文件可以正常工作.
新信息 - 30/03/2011 - 下午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;
Run Code Online (Sandbox Code Playgroud)
我对Opendialog工作的第一个猜测是,打开的对话框改变了CurrentDir - 所以我尝试使用SetCurrentDir和ChDir将当前目录更改为文件所在的目录.没有成功.
在Win 7下,文件路径转换为C:\ Users\Ronaldo\Documents\CompanyName\AppName
我已经把这个抛在了后面,但现在我有时间回去尝试解决问题。
我发现,客户端应用程序正在使用 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;
Run Code Online (Sandbox Code Playgroud)
并调用 GetSpecialFolderPath(CSIDL_Personal) 等函数。
感谢大家抽出宝贵的时间发表评论和答案。
只是想补充一点,这个答案对于我来说是正确的答案。@Ken White 的答案可能是其他人的正确答案。