Inno Setup:使用IShellLink GetWorkingDirectory进行访问冲突

时间:2014-12-10 19:13:25

标签: inno-setup pascalscript

我正在使用Inno Setup。已安装的应用程序可以有多个安装,因此可以创建多个“开始”菜单快捷方式。我遇到的麻烦是在同一个应用程序位置创建了多个图标(重复)。我的解决方案是在安装过程中检查现有的“开始”菜单快捷方式,读取快捷方式的“工作”或“目标”目录属性,并根据当前安装目录进行检查。如果其中一个快捷方式匹配,则不要安装快捷方式。

我正在使用示例文件" CodeAutomation2.iss"作为快捷链接上的工作目录的起点。示例文件中的IShellLink代码是我一直在使用的,但当我尝试使用" GetWorkingDirectory"我收到以下错误。

Access violation

以下是我正在使用的代码。我和#34; 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);

1 个答案:

答案 0 :(得分:2)

在传递之前,您需要为WorkingDir分配内存。您已经告诉IShellLinkW.GetWorkingDir您要为其分配250个字符的空间,但实际上并没有这样做了。

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

更好的解决方案可能是首先实际填充返回缓冲区,以消除字符串结束后额外内容的可能性。首先使用null(#0)字符预填充,然后从左侧填充GetWorkingDir

WorkingDir := StringOfChar(#0, 250);
OleCheck(SL.GetWorkingDir(WorkingDir, 250);
WorkingDir := Trim(WorkingDir);