Adobe X Включить защищенный режим при запуске - отключить с помощью кода - PullRequest
6 голосов
/ 29 марта 2011

Наше приложение, написанное на 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;

Из-за этой новой настройки Adobe Reader в Win 7 или Vista мы получаем сообщение об ошибке при открытии документа. Двойной щелчок на документе, чтобы открыть его, не доставляет никаких проблем. Есть ли способ отключить защищенный метод - или другой способ открыть документ без получения ошибки (обходной путь)?

* Дополнительная информация *

Файл PDF создается в нашем серверном приложении, передается клиенту, а клиент создает файл PDF (используя запись) - сначала я подумал, что это может быть проблемой, - но опять же, почему двойной щелчок работает нормально.

Я создал фиктивное приложение, которое ничего не делает, но использует тот же код выше, чтобы открыть PDF, и это работает. Я проверил привилегии приложения - все то же самое - единственное отличие состоит в том, что тот, который не работает, устанавливается в ОС с помощью правильного установщика - другой (фиктивный), который я только что создал и удалил там.

В одном из комментариев спрашивается об ассоциации файлов - это не должно быть проблемой, поскольку приложение успешно запускает Adobe Reader - Adobe Reader затем выдает мне сообщение об ошибке «Отказано в доступе». Двойной щелчок по тому же файлу отлично работает.

Новая информация - 30/03/2011 - 14:50 - новозеландское время

Я внес изменения в код, чтобы проверить единственное различие между самим приложением и фиктивным приложением. Вместо того, чтобы автоматически получать путь к файлу и имя файла, теперь он открывает OpenDialog - свойство Filename в opendialog используется в качестве параметра для ShellExecute (как комментарий после ответа Кена) - это работает. Почему, когда вы получаете имя файла из открытого диалога, оно работает - обратите внимание, что я не открываю файл из диалогового окна - я получаю имя файла и использую его как параметр для 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

Ответы [ 2 ]

3 голосов
/ 30 марта 2011

Я не думаю, что вы можете полностью отключить это в коде; если бы вы могли, это бы победило всю цель защищенного режима (предотвращение использования вредоносного программного обеспечения .pdf). Возможно, вы сможете обойти это законным путем. :)

Я подозреваю, что это связано с глаголом open, который вы используете с ShellExecute. Вы предполагаете (возможно, неправильно), что глагол open делает в защищенном режиме на Win7 то же самое, что и в предыдущих версиях Adobe Reader и Windows. ( ПРИМЕЧАНИЕ : у меня не установлена ​​эта версия Acrobat в моей системе; это все предположения.)

Первое, что я попробую, это изменить вызов на ShellExecute следующим образом:

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

Первое изменение - передать nil в качестве второго параметра. Это говорит Windows, что вы хотите выполнить любое действие по умолчанию. Например, это может быть view вместо open.

Я также изменил два параметра после имени файла на ноль. Это более читабельно, чем использование пустой строки ('').

Последнее изменение в последнем параметре; Я обычно использую SW_NORMAL вместо SW_SHOW просто потому, что это говорит Windows показывать его в любом размере и положении по умолчанию; это может быть что-то, сохраненное приложением, и оно будет учитывать настройки пользователя (если есть).

Если это не сработает, пора бродить ( осторожно !! ) в реестре Windows. Откройте regedit в элементе управления поиска в меню «Пуск» и перейдите к HKEY_CLASSES_ROOT. Прокручивайте расширения файлов до тех пор, пока не найдете запись для .pdf, и дважды щелкните эту ветку. Вы увидите Default, который (в любом случае, в моей системе) AcroExch.Document с Content Type из application/pdf.

Продолжайте идти вниз по дереву на левой панели, пока не найдете AcroExch.Document, и разверните его. Там вы увидите несколько значений (опять же, с моей машины), как вы можете видеть на изображении ниже. Разверните ветку Shell, и вы увидите определенные глаголы, а также команду, связанную с ними. На моей машине (снова) у меня есть один глагол Open, команда которого установлена ​​на "C:\Program Files (x86)\Adobe\Reader 9.0\Reader\AcroRd32.exe" "%1".

RegEdit Left PaneRegEdit Value Pane

(Потерпи меня - мы почти на месте. Обещаю.)

Вы можете увидеть, что двойной щелчок делает по-другому, изучив значение по умолчанию (щелкните Shell на левой панели, а затем посмотрите, что установлено как (Default) справа. Затем изучите командную строку (в второе изображение выше, это Open), чтобы увидеть, какие переключатели, если таковые имеются, передаются в приложение Acrobat Reader (если вы не можете выяснить, какой из них используется по умолчанию, щелкните правой кнопкой мыши файл .pdf в проводнике Windows и посмотрите, что выделенный жирным шрифтом пункт находится в контекстном меню.)

Если передан параметр, отличный от "%1", вам нужно добавить тот же параметр в командную строку, предоставленную для ShellExecute. Например, если параметр /v, вы бы изменили свой вызов на ShellExcute на что-то вроде этого:

ShellExecute(0, nil, PChar(pdfFile), PChar('/v'), nil, SW_NORMAL);
1 голос
/ 04 мая 2011

Я оставил это позади, но теперь у меня есть время, когда я вернулся, чтобы попытаться решить проблему.

Я обнаружил, что клиентское приложение использует GetEnvironmentVariable ('USERPROFILE'), чтобы получить часть папки, в которой находятся отчеты. Это дает мне что-то вроде «c: \ users \ user_name \» в Windows 7 - и затем добавляется константа с чем-то вроде «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).

Спасибо всем за то, что у вас есть время оставлять комментарии и ответы.

Просто хочу добавить, что этот ответ является правильным ответом в моем случае. Это может быть случай. @ Кен Уайт - правильный ответ для кого-то другого.

...