Inno Setup: нарушение прав доступа с использованием IShellLink GetWorkingDirectory

Я использую Inno Setup. Установленное приложение может иметь несколько установок, поэтому создается несколько ярлыков меню «Пуск». Проблема, с которой я сталкиваюсь, заключается в том, что несколько значков создаются в одном и том же месте приложения (дубликаты). Мое решение заключается в том, чтобы в процессе установки проверить существующие ярлыки меню «Пуск», прочитать свойство рабочего или целевого каталога ярлыка и сравнить его с текущим каталогом установки. Если один из ярлыков совпадает, не устанавливайте ярлык.

Я использую пример файла «CodeAutomation2.iss» в качестве отправной точки для чтения рабочего каталога по ссылке быстрого доступа. Код IShellLink в файле примера — это то, что я использовал, но когда я пытаюсь использовать «GetWorkingDirectory», я получаю следующую ошибку.

Нарушение прав доступа

Ниже приведен код, который я использую. Что я делаю не так с «GetWorkingDirectory»?

var
  ShortcutFile: String;

  WorkingDir: String;
  Obj: IUnknown;
  SL: IShellLinkW;
  PF: IPersistFile;

begin
  { Create the main ShellLink COM Automation object }
  Obj := CreateComObject(StringToGuid(CLSID_ShellLink));

  { Set the shortcut properties }
  SL := IShellLinkW(Obj);
  PF := IPersistFile(Obj);

  NumFiles := 1
  ShortcutFile := ExpandConstant('{#MyAppName}');

  Log('File is: ' + ExpandConstant('{group}') + '\' + ShortcutFile + '.lnk');
  OleCheck(PF.Load(ExpandConstant(ExpandConstant('{group}') + '\' + ShortcutFile + '.lnk'), 0));
  OleCheck(SL.GetWorkingDirectory(WorkingDir, 250));
  Log('WorkingDir: ' + WorkingDir);

person Mark    schedule 10.12.2014    source источник


Ответы (1)


Вам нужно выделить память для WorkingDir, прежде чем передать его. Вы сказали IShellLinkW.GetWorkingDir, что выделяете 250 символов пространства для его использования, но на самом деле этого не сделали.

SetLength(WorkingDir, 250);  
OleCheck(SL.GetWorkingDir(WorkingDir, 250));

Лучшее решение может заключаться в том, чтобы сначала заполнить буфер возврата, чтобы исключить возможность лишнего материала после конца строки. Сначала заполните его нулевыми (#0) символами, а затем GetWorkingDir будет заполняться с левой стороны:

WorkingDir := StringOfChar(#0, 250);
OleCheck(SL.GetWorkingDir(WorkingDir, 250);
WorkingDir := Trim(WorkingDir);  
person Ken White    schedule 10.12.2014
comment
Большое спасибо! У вас есть какие-либо предложения о том, как удалить все нежелательные символы после пути? Я получаю путь, но оставшаяся неиспользуемая часть строки заполнена нежелательными символами. - person Mark; 10.12.2014
comment
@Ken: Предварительное заполнение нулевыми символами помогло. Спасибо вам обоим TLama, Кен за ваши знания и время. Очень признателен. Да, не стесняйтесь почистить эту тему! Спасибо! - person Mark; 11.12.2014