How do I programmatically change a .lnk to change its target?
Asked Answered
R

2

8

Is there any way to open a windows shortcut (.lnk file) and change it's target? I found the following snippet which allows me to find the current target, but it's a read-only property:

Shell32::Shell^ shl = gcnew Shell32::Shell();
String^ shortcutPos = "C:\\some\\path\\to\\my\\link.lnk";
String^ lnkPath = System::IO::Path::GetFullPath(shortcutPos);
Shell32::Folder^ dir = shl->NameSpace(System::IO::Path::GetDirectoryName(lnkPath));
Shell32::FolderItem^ itm = dir->Items()->Item(System::IO::Path::GetFileName(lnkPath));
Shell32::ShellLinkObject^ lnk = (Shell32::ShellLinkObject^)itm->GetLink;
String^ target = lnk->Target->Path;

I can't find anything to alter the target. Is my only option to create a new shortcut to overwrite the current one? ..and if so, how do I do that?

Ryurik answered 29/9, 2010 at 15:3 Comment(0)
S
13

It isn't read-only, use lnk->Path instead, followed by lnk->Save(). Assuming you have write privileges to the file. C# code that does the same thing is in my answer in this thread.

Shumate answered 29/9, 2010 at 16:5 Comment(3)
This worked great for C# too, though to access the Shell32.Shell class I had to add C:\Windows\system32\shell32.dll as a reference in my project.Medic
This is nice, but how can I use it to read only for files that are protected?Egotist
URL is dead, maybe you can fix it?Selfimmolation
A
14

Recreating a shortcut with WSH

You can remove an existing shortcut and create a new one with the new target. To create a new one, you can use the following snippet:

public void CreateLink(string shortcutFullPath, string target)
{
    WshShell wshShell = new WshShell();
    IWshRuntimeLibrary.IWshShortcut newShortcut = (IWshRuntimeLibrary.IWshShortcut)wshShell.CreateShortcut(shortcutFullPath);
    newShortcut.TargetPath = target;
    newShortcut.Save();
}

For the moment, I don't see any way to change the target without recreating the shortcut.

Note: to use the snippet, you must add Windows Script Host Object Model COM to the project references.

Changing the target path with Shell32

Here's the snippet which changes the target of a shortcut without removing and recreating it:

public void ChangeLinkTarget(string shortcutFullPath, string newTarget)
{
    // Load the shortcut.
    Shell32.Shell shell = new Shell32.Shell();
    Shell32.Folder folder = shell.NameSpace(Path.GetDirectoryName(shortcutFullPath));
    Shell32.FolderItem folderItem = folder.Items().Item(Path.GetFileName(shortcutFullPath));
    Shell32.ShellLinkObject currentLink = (Shell32.ShellLinkObject)folderItem.GetLink;

    // Assign the new path here. This value is not read-only.
    currentLink.Path = newTarget;

    // Save the link to commit the changes.
    currentLink.Save();
}

The second one is probably what you need.

Note: sorry, the snippets are in C# since I don't know C++/CLI. If somebody wants to rewrite those snippets for C++/CLI, feel free to edit my answer.

Adulteress answered 29/9, 2010 at 15:31 Comment(1)
See here for info how to reference Shell32Humic
S
13

It isn't read-only, use lnk->Path instead, followed by lnk->Save(). Assuming you have write privileges to the file. C# code that does the same thing is in my answer in this thread.

Shumate answered 29/9, 2010 at 16:5 Comment(3)
This worked great for C# too, though to access the Shell32.Shell class I had to add C:\Windows\system32\shell32.dll as a reference in my project.Medic
This is nice, but how can I use it to read only for files that are protected?Egotist
URL is dead, maybe you can fix it?Selfimmolation

© 2022 - 2024 — McMap. All rights reserved.