Как программно изменить .lnk, чтобы изменить его цель?

Есть ли способ открыть ярлык Windows (файл .lnk) и изменить его цель? Я нашел следующий фрагмент, который позволяет мне найти текущую цель, но это свойство только для чтения:

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;

Я не могу найти ничего, что могло бы изменить цель. Единственный ли у меня вариант - создать новый ярлык для перезаписи текущего? ..и если да, то как мне это сделать?


person Jon Cage    schedule 29.09.2010    source источник


Ответы (2)


Это не только для чтения, используйте вместо этого lnk-> Path, а затем lnk-> Save (). Предполагая, что у вас есть права на запись в файл. Код C #, который делает то же самое, находится в моем ответе на эта тема.

person Hans Passant    schedule 29.09.2010
comment
Это отлично сработало и для C #, хотя для доступа к классу Shell32.Shell мне пришлось добавить C: \ Windows \ system32 \ shell32.dll в качестве ссылки в моем проекте. - person Gabe Halsmer; 21.02.2014
comment
Это хорошо, но как я могу использовать его только для чтения защищенных файлов? - person Adam L. S.; 10.02.2015

Создание ярлыка с помощью WSH

Вы можете удалить существующий ярлык и создать новый с новой целью. Чтобы создать новый, вы можете использовать следующий фрагмент:

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

На данный момент я не вижу возможности изменить цель без воссоздания ярлыка.

Примечание. Для использования фрагмента необходимо добавить COM объектной модели хоста сценария Windows к ссылкам на проект.

Изменение целевого пути с помощью Shell32

Вот фрагмент, который изменяет цель ярлыка, не удаляя и не воссоздавая его:

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();
}

Второй, наверное, то, что вам нужно.

Примечание: извините, фрагменты написаны на C #, так как я не знаю C ++ / CLI. Если кто-то хочет переписать эти фрагменты для C ++ / CLI, не стесняйтесь редактировать мой ответ.

person Arseni Mourzenko    schedule 29.09.2010
comment
См. здесь для получения информации о том, как ссылаться на Shell32. - person huha; 13.06.2019