I am using Inno Setup. The installed application can have multiple installs so multiple Start Menu shortcuts are created. The trouble I am running into is that multiple icons are created to the same application location (duplicates). My solution is in the install process to check existing Start Menu shortcuts, read the Working or Target directory property of the shortcut, and check it against the current install directory. If one of the shortcuts has a match then don't install a shortcut.
I am using the example file "CodeAutomation2.iss" as a starting point to read the Working Directory on the shortcut link. The IShellLink code in the example file is what I have been using but when I try to use "GetWorkingDirectory" I get the following error.
Below is the code I am using. What am I doing wrong with "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);
You need to allocate memory for WorkingDir
before you pass it in. You've told IShellLinkW.GetWorkingDir
that you're allocating 250 chars of space for it to use, but not actually done so.
SetLength(WorkingDir, 250);
OleCheck(SL.GetWorkingDir(WorkingDir, 250));
A better solution might be to actually populate the return buffer first, to remove the possibility of extra stuff after the end of the string. Prefill it with null (#0) characters first, and then GetWorkingDir
will populate from the left side:
WorkingDir := StringOfChar(#0, 250);
OleCheck(SL.GetWorkingDir(WorkingDir, 250);
WorkingDir := Trim(WorkingDir);