Создать ярлык на рабочем столе


106

Я хочу создать ярлык, указывающий на какой-нибудь EXE-файл на рабочем столе, используя .NET Framework 3.5 и полагаясь на официальный Windows API. Как я могу это сделать?


1
Использование объектной модели хоста сценария Windows от Рустама Ирзаева - единственное надежное средство для создания правильного ярлыка. ayush: В этом методе отсутствует ряд функций, таких как горячие клавиши и описания. Торарин: ShellLink работает хорошо в большинстве случаев, но, в частности, он не работает в Windows XP и создает недопустимые ярлыки. Саймон Мурье: Это было многообещающе, но в Windows 8 создаются недопустимые ярлыки.
— BrutalDev

Ответ Саймона Мурье - лучший ответ здесь. Единственный правильный и надежный способ создания ярлыков - использовать тот же API, который использует операционная система, и это интерфейс IShellLink. Не используйте Windows Script Host и не создавайте веб-ссылки! Саймон Мурье показывает, как это сделать с помощью 6 строк кода. Все, у кого были проблемы с этим методом, ОБЯЗАТЕЛЬНО передавали неверные пути. Я тестировал его код в Windows XP, 7 и 10. Скомпилируйте свое приложение как «Любой процессор», чтобы избежать проблем с 32- или 64-битной Windows, которые используют разные папки для Program Files и др.
— Elmue

Ответы:


120

С дополнительными опциями, такими как горячая клавиша, описание и т. Д.

Сначала выберите Project > Add Reference > COM > Windows Script Host Object Model.

using IWshRuntimeLibrary;

private void CreateShortcut()
{
  object shDesktop = (object)"Desktop";
  WshShell shell = new WshShell();
  string shortcutAddress = (string)shell.SpecialFolders.Item(ref shDesktop) + @"\Notepad.lnk";
  IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutAddress);
  shortcut.Description = "New shortcut for a Notepad";
  shortcut.Hotkey = "Ctrl+Shift+N";
  shortcut.TargetPath = Environment.GetFolderPath(Environment.SpecialFolder.System) + @"\notepad.exe";
  shortcut.Save();
}

2
Это было действительно близко для меня. Мне нужно было добавить каталог .exe в свойство «WorkingDirectory» на ярлыке. (shortcut.WorkingDirectory) +1
— samuelesque

4
Чтобы указать индекс значка (в IconLocation), используйте значение типа «path_to_icon_file, #», где # - это индекс значка. См. Msdn.microsoft.com/en-us/library/xsy6k3ys(v=vs.84).aspx
— Крис,

1
для аргумента: shortcut.Arguments = "Seta Map mp_crash"; stackoverflow.com/a/18491229/2155778
— Золфагари

7
Environment.SpecialFolders.System - не существует ... Environment.SpecialFolder.System - работает.
— JSWulf

на некоторое время вам также нужно добавить Microsoft.CSharp в качестве ссылки.
— l1nuxuser 01

76

Ярлык URL

private void urlShortcutToDesktop(string linkName, string linkUrl)
{
    string deskDir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);

    using (StreamWriter writer = new StreamWriter(deskDir + "\\" + linkName + ".url"))
    {
        writer.WriteLine("[InternetShortcut]");
        writer.WriteLine("URL=" + linkUrl);
    }
}

Ярлык приложения

private void appShortcutToDesktop(string linkName)
{
    string deskDir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);

    using (StreamWriter writer = new StreamWriter(deskDir + "\\" + linkName + ".url"))
    {
        string app = System.Reflection.Assembly.GetExecutingAssembly().Location;
        writer.WriteLine("[InternetShortcut]");
        writer.WriteLine("URL=file:///" + app);
        writer.WriteLine("IconIndex=0");
        string icon = app.Replace('\\', '/');
        writer.WriteLine("IconFile=" + icon);
    }
}

Также проверьте этот пример .

Если вы хотите использовать какие-то специфические функции API, тогда вы захотите использовать IShellLink interfaceкак IPersistFile interface(через COM-взаимодействие).

Вот статья, в которой подробно описано, что вам нужно для этого, а также пример кода.


Эти выше работают нормально. Но я хочу создать ярлык с помощью некоторых функций API, таких как DllImport ("coredll.dll")] public static extern int SHCreateShortcut (StringBuilder szShortcut, StringBuilder szTarget);
— Випин Арора

@Vipin почему? Есть ли причина, по которой любое из вышеперечисленных решений недостаточно хорошо?
— Alex

8
придирки: вы можете удалить строку flush (), поскольку завершение блока Using должно позаботиться об этом за вас
— Newtopian

3
У меня было много проблем с этим методом ... Windows имеет тенденцию кэшировать определение ярлыка где-то ... создать ярлык, подобный этому, удалить его, а затем создать его с тем же именем, но другим URL ... скорее всего, окна при нажатии на ярлык откроет старый удаленный URL. Ответ Рустама ниже (с использованием .lnk вместо .url) решил эту проблему для меня
— TCC

1
Отличный ответ. Намного лучше, чем ужасная система COM, с которой вам приходится иметь дело при использовании файлов .lnk.
— Джеймс Ко

61

Вот фрагмент кода, который не зависит от внешнего COM-объекта (WSH) и поддерживает 32-разрядные и 64-разрядные программы:

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;

namespace TestShortcut
{
    class Program
    {
        static void Main(string[] args)
        {
            IShellLink link = (IShellLink)new ShellLink();

            // setup shortcut information
            link.SetDescription("My Description");
            link.SetPath(@"c:\MyPath\MyProgram.exe");

            // save it
            IPersistFile file = (IPersistFile)link;
            string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
            file.Save(Path.Combine(desktopPath, "MyLink.lnk"), false);
        }
    }

    [ComImport]
    [Guid("00021401-0000-0000-C000-000000000046")]
    internal class ShellLink
    {
    }

    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("000214F9-0000-0000-C000-000000000046")]
    internal interface IShellLink
    {
        void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out IntPtr pfd, int fFlags);
        void GetIDList(out IntPtr ppidl);
        void SetIDList(IntPtr pidl);
        void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName);
        void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
        void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
        void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
        void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
        void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
        void GetHotkey(out short pwHotkey);
        void SetHotkey(short wHotkey);
        void GetShowCmd(out int piShowCmd);
        void SetShowCmd(int iShowCmd);
        void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon);
        void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
        void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved);
        void Resolve(IntPtr hwnd, int fFlags);
        void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
    }
}

@BrutalDev - Что не работает? Я тестировал его на Windows 8 x64, и он работает.
— Саймон Мурье

Также под управлением Win8 x64, скопировал приведенный выше образец кода в точности как есть, он создает значок на моем рабочем столе без пути. Выполнение ссылки просто открывает проводник на рабочий стол. Аналогичная проблема была у меня с ShellLink.cs, но в Windows XP / 2003. Единственным примером, который окончательно работает во всех версиях Windows, было использование Рустамом Ирзаевым WSHOM, как я уже упоминал в своем комментарии к основному вопросу: «Это было многообещающе, но создает недопустимые ярлыки в Windows 8»
— BrutalDev

Я получил это для работы в Windows 8.1 x64, но код, приведенный здесь прямо сейчас, не имеет определения IPersistFile. Мне пришлось скопировать это из сообщения ShellLink.cs, чтобы заставить его работать.
— Уолтер Уилфингер,

Я не вижу ощутимой причины, почему это не сработает. Как бы то ни было, IPersistFile доступен прямо из коробки в System.Runtime.InteropServices.ComTypes
— Саймон Мурье

1
Это решение не устанавливает правильный значок при использовании SetIconLocationв 64-битной Windows 10 с 32-битным исполняемым файлом. Решение описано здесь: stackoverflow.com/a/39282861, и я также подозреваю, что это та же проблема с Windows 8, на которую ссылаются все остальные. Это может быть связано с 32-битными exe-файлами в 64-битной Windows.
— Maris B.

26

Вы можете использовать этот класс ShellLink.cs для создания ярлыка.

Чтобы получить каталог рабочего стола, используйте:

var dir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);

или используйте, Environment.SpecialFolder.CommonDesktopDirectoryчтобы создать его для всех пользователей.


6
@Vipin: если решение работает для вас, принято голосовать за него. Кроме того, вам следует выбрать лучшее решение и принять его как ответ на вашу проблему.
— Thorarin

Это перезапишет существующий exe файлом lnk. Проверено на Win10.
— zwcloud

@zwcloud Этот код ничего не перезаписывает, потому что ничего не делает. Он просто сообщает вам, какие классы и методы использовать для работы с ярлыками. Если ваш код перезаписывает исполняемый файл, который находится на вас. Я бы посмотрел, как вы на самом деле создаете файл lnk, чтобы понять, почему он разрушает ваш exe.
— Cdaragorn

15

Без дополнительной ссылки:

using System;
using System.Runtime.InteropServices;

public class Shortcut
{

private static Type m_type = Type.GetTypeFromProgID("WScript.Shell");
private static object m_shell = Activator.CreateInstance(m_type);

[ComImport, TypeLibType((short)0x1040), Guid("F935DC23-1CF0-11D0-ADB9-00C04FD58A0B")]
private interface IWshShortcut
{
    [DispId(0)]
    string FullName { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0)] get; }
    [DispId(0x3e8)]
    string Arguments { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3e8)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3e8)] set; }
    [DispId(0x3e9)]
    string Description { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3e9)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3e9)] set; }
    [DispId(0x3ea)]
    string Hotkey { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3ea)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ea)] set; }
    [DispId(0x3eb)]
    string IconLocation { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3eb)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3eb)] set; }
    [DispId(0x3ec)]
    string RelativePath { [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ec)] set; }
    [DispId(0x3ed)]
    string TargetPath { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3ed)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ed)] set; }
    [DispId(0x3ee)]
    int WindowStyle { [DispId(0x3ee)] get; [param: In] [DispId(0x3ee)] set; }
    [DispId(0x3ef)]
    string WorkingDirectory { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3ef)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ef)] set; }
    [TypeLibFunc((short)0x40), DispId(0x7d0)]
    void Load([In, MarshalAs(UnmanagedType.BStr)] string PathLink);
    [DispId(0x7d1)]
    void Save();
}

public static void Create(string fileName, string targetPath, string arguments, string workingDirectory, string description, string hotkey, string iconPath)
{
    IWshShortcut shortcut = (IWshShortcut)m_type.InvokeMember("CreateShortcut", System.Reflection.BindingFlags.InvokeMethod, null, m_shell, new object[] { fileName });
    shortcut.Description = description;
    shortcut.Hotkey = hotkey;
    shortcut.TargetPath = targetPath;
    shortcut.WorkingDirectory = workingDirectory;
    shortcut.Arguments = arguments;
    if (!string.IsNullOrEmpty(iconPath))
        shortcut.IconLocation = iconPath;
    shortcut.Save();
}
}

Чтобы создать ярлык на рабочем столе:

    string lnkFileName = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Notepad.lnk");
    Shortcut.Create(lnkFileName,
        System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "notepad.exe"),
        null, null, "Open Notepad", "Ctrl+Shift+N", null);

11

Я использую просто для своего приложения:

using IWshRuntimeLibrary; // > Ref > COM > Windows Script Host Object  
...   
private static void CreateShortcut()
    {
        string link = Environment.GetFolderPath( Environment.SpecialFolder.Desktop ) 
            + Path.DirectorySeparatorChar + Application.ProductName + ".lnk";
        var shell = new WshShell();
        var shortcut = shell.CreateShortcut( link ) as IWshShortcut;
        shortcut.TargetPath = Application.ExecutablePath;
        shortcut.WorkingDirectory = Application.StartupPath;
        //shortcut...
        shortcut.Save();
    }

Работает из коробки, просто скопируйте и вставьте его
— rluks

9

Используйте ShellLink.cs в vbAccelerator, чтобы легко создать ярлык!

private static void AddShortCut()
{
using (ShellLink shortcut = new ShellLink())
{
    shortcut.Target = Application.ExecutablePath;
    shortcut.WorkingDirectory = Path.GetDirectoryName(Application.ExecutablePath);
    shortcut.Description = "My Shorcut";
    shortcut.DisplayMode = ShellLink.LinkDisplayMode.edmNormal;
    shortcut.Save(SHORTCUT_FILEPATH);
}
}

3
Эта ссылка теперь мертва, но вы можете найти ее заархивированную версию здесь .
— pswg

7

Вот мой код:

public static class ShortcutHelper
{
    #region Constants
    /// <summary>
    /// Default shortcut extension
    /// </summary>
    public const string DEFAULT_SHORTCUT_EXTENSION = ".lnk";

    private const string WSCRIPT_SHELL_NAME = "WScript.Shell";
    #endregion

    /// <summary>
    /// Create shortcut in current path.
    /// </summary>
    /// <param name="linkFileName">shortcut name(include .lnk extension.)</param>
    /// <param name="targetPath">target path</param>
    /// <param name="workingDirectory">working path</param>
    /// <param name="arguments">arguments</param>
    /// <param name="hotkey">hot key(ex: Ctrl+Shift+Alt+A)</param>
    /// <param name="shortcutWindowStyle">window style</param>
    /// <param name="description">shortcut description</param>
    /// <param name="iconNumber">icon index(start of 0)</param>
    /// <returns>shortcut file path.</returns>
    /// <exception cref="System.IO.FileNotFoundException"></exception>
    public static string CreateShortcut(
        string linkFileName,
        string targetPath,
        string workingDirectory = "",
        string arguments = "",
        string hotkey = "",
        ShortcutWindowStyles shortcutWindowStyle = ShortcutWindowStyles.WshNormalFocus,
        string description = "",
        int iconNumber = 0)
    {
        if (linkFileName.Contains(DEFAULT_SHORTCUT_EXTENSION) == false)
        {
            linkFileName = string.Format("{0}{1}", linkFileName, DEFAULT_SHORTCUT_EXTENSION);
        }

        if (File.Exists(targetPath) == false)
        {
            throw new FileNotFoundException(targetPath);
        }

        if (workingDirectory == string.Empty)
        {
            workingDirectory = Path.GetDirectoryName(targetPath);
        }

        string iconLocation = string.Format("{0},{1}", targetPath, iconNumber);

        if (Environment.Version.Major >= 4)
        {
            Type shellType = Type.GetTypeFromProgID(WSCRIPT_SHELL_NAME);
            dynamic shell = Activator.CreateInstance(shellType);
            dynamic shortcut = shell.CreateShortcut(linkFileName);

            shortcut.TargetPath = targetPath;
            shortcut.WorkingDirectory = workingDirectory;
            shortcut.Arguments = arguments;
            shortcut.Hotkey = hotkey;
            shortcut.WindowStyle = shortcutWindowStyle;
            shortcut.Description = description;
            shortcut.IconLocation = iconLocation;

            shortcut.Save();
        }
        else
        {
            Type shellType = Type.GetTypeFromProgID(WSCRIPT_SHELL_NAME);
            object shell = Activator.CreateInstance(shellType);
            object shortcut = shellType.InvokeMethod("CreateShortcut", shell, linkFileName);
            Type shortcutType = shortcut.GetType();

            shortcutType.InvokeSetMember("TargetPath", shortcut, targetPath);
            shortcutType.InvokeSetMember("WorkingDirectory", shortcut, workingDirectory);
            shortcutType.InvokeSetMember("Arguments", shortcut, arguments);
            shortcutType.InvokeSetMember("Hotkey", shortcut, hotkey);
            shortcutType.InvokeSetMember("WindowStyle", shortcut, shortcutWindowStyle);
            shortcutType.InvokeSetMember("Description", shortcut, description);
            shortcutType.InvokeSetMember("IconLocation", shortcut, iconLocation);

            shortcutType.InvokeMethod("Save", shortcut);
        }

        return Path.Combine(System.Windows.Forms.Application.StartupPath, linkFileName);
    }

    private static object InvokeSetMember(this Type type, string methodName, object targetInstance, params object[] arguments)
    {
        return type.InvokeMember(
            methodName,
            BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty,
            null,
            targetInstance,
            arguments);
    }

    private static object InvokeMethod(this Type type, string methodName, object targetInstance, params object[] arguments)
    {
        return type.InvokeMember(
            methodName,
            BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod,
            null,
            targetInstance,
            arguments);
    }

    /// <summary>
    /// windows styles
    /// </summary>
    public enum ShortcutWindowStyles
    {
        /// <summary>
        /// Hide
        /// </summary>
        WshHide = 0,
        /// <summary>
        /// NormalFocus
        /// </summary>
        WshNormalFocus = 1,
        /// <summary>
        /// MinimizedFocus
        /// </summary>
        WshMinimizedFocus = 2,
        /// <summary>
        /// MaximizedFocus
        /// </summary>
        WshMaximizedFocus = 3,
        /// <summary>
        /// NormalNoFocus
        /// </summary>
        WshNormalNoFocus = 4,
        /// <summary>
        /// MinimizedNoFocus
        /// </summary>
        WshMinimizedNoFocus = 6,
    }
}

5

EDIT: я больше не рекомендую это решение. Если все еще нет лучшего метода, чем использование механизма сценариев Windows, по крайней мере, используйте решение @ Mehmet, которое вызывает механизм напрямую, а не создает простой текстовый сценарий в памяти.

Мы использовали VBScript для создания ярлыка. Не требует p / Invoke, COM Interop и дополнительных DLL. Это работает так:

  • Создание сценария VBScript во время выполнения с указанными параметрами метода CreateShortcut C #
  • Сохраните этот VBScript во временном файле
  • Дождитесь завершения сценария
  • Удалить временный файл

Ну вот:

static string _scriptTempFilename;

/// <summary>
/// Creates a shortcut at the specified path with the given target and
/// arguments.
/// </summary>
/// <param name="path">The path where the shortcut will be created. This should
///     be a file with the LNK extension.</param>
/// <param name="target">The target of the shortcut, e.g. the program or file
///     or folder which will be opened.</param>
/// <param name="arguments">The additional command line arguments passed to the
///     target.</param>
public static void CreateShortcut(string path, string target, string arguments)
{
    // Check if link path ends with LNK or URL
    string extension = Path.GetExtension(path).ToUpper();
    if (extension != ".LNK" && extension != ".URL")
    {
        throw new ArgumentException("The path of the shortcut must have the extension .lnk or .url.");
    }

    // Get temporary file name with correct extension
    _scriptTempFilename = Path.GetTempFileName();
    File.Move(_scriptTempFilename, _scriptTempFilename += ".vbs");

    // Generate script and write it in the temporary file
    File.WriteAllText(_scriptTempFilename, String.Format(@"Dim WSHShell
Set WSHShell = WScript.CreateObject({0}WScript.Shell{0})
Dim Shortcut
Set Shortcut = WSHShell.CreateShortcut({0}{1}{0})
Shortcut.TargetPath = {0}{2}{0}
Shortcut.WorkingDirectory = {0}{3}{0}
Shortcut.Arguments = {0}{4}{0}
Shortcut.Save",
        "\"", path, target, Path.GetDirectoryName(target), arguments),
        Encoding.Unicode);

    // Run the script and delete it after it has finished
    Process process = new Process();
    process.StartInfo.FileName = _scriptTempFilename;
    process.Start();
    process.WaitForExit();
    File.Delete(_scriptTempFilename);
}

3

Вот (протестированный) метод расширения с комментариями, которые помогут вам.

using IWshRuntimeLibrary;
using System;

namespace Extensions
{
    public static class XShortCut
    {
        /// <summary>
        /// Creates a shortcut in the startup folder from a exe as found in the current directory.
        /// </summary>
        /// <param name="exeName">The exe name e.g. test.exe as found in the current directory</param>
        /// <param name="startIn">The shortcut's "Start In" folder</param>
        /// <param name="description">The shortcut's description</param>
        /// <returns>The folder path where created</returns>
        public static string CreateShortCutInStartUpFolder(string exeName, string startIn, string description)
        {
            var startupFolderPath = Environment.SpecialFolder.Startup.GetFolderPath();
            var linkPath = startupFolderPath + @"\" + exeName + "-Shortcut.lnk";
            var targetPath = Environment.CurrentDirectory + @"\" + exeName;
            XFile.Delete(linkPath);
            Create(linkPath, targetPath, startIn, description);
            return startupFolderPath;
        }

        /// <summary>
        /// Create a shortcut
        /// </summary>
        /// <param name="fullPathToLink">the full path to the shortcut to be created</param>
        /// <param name="fullPathToTargetExe">the full path to the exe to 'really execute'</param>
        /// <param name="startIn">Start in this folder</param>
        /// <param name="description">Description for the link</param>
        public static void Create(string fullPathToLink, string fullPathToTargetExe, string startIn, string description)
        {
            var shell = new WshShell();
            var link = (IWshShortcut)shell.CreateShortcut(fullPathToLink);
            link.IconLocation = fullPathToTargetExe;
            link.TargetPath = fullPathToTargetExe;
            link.Description = description;
            link.WorkingDirectory = startIn;
            link.Save();
        }
    }
}

И пример использования:

XShortCut.CreateShortCutInStartUpFolder(THEEXENAME, 
    Environment.CurrentDirectory,
    "Starts some executable in the current directory of application");

1-й параметр устанавливает имя exe (находится в текущем каталоге) 2-й параметр - это папка «Начать в», а 3-й параметр - это описание ярлыка.

Пример использования этого кода

Соглашение об именах ссылки не оставляет двусмысленности относительно того, что она будет делать. Чтобы проверить ссылку, просто дважды щелкните по ней.

Заключительное примечание: само приложение (цель) должно иметь связанный с ним ICON-образ. По ссылке можно легко найти ЗНАЧОК в exe. Если целевое приложение имеет более одного значка, вы можете открыть свойства ссылки и изменить значок на любой другой, найденный в exe.


Я получаю сообщение об ошибке, что .GetFolderPath () не существует. То же самое для XFile.Delete. Что мне не хватает?
— RalphF

Здесь происходит ошибка? Environment.SpecialFolder.Startup.GetFolderPath ();
— Джон Питерс

2

Я использую ссылку «Windows Script Host Object Model» для создания ярлыка.

Добавление "объектной модели хоста сценария Windows" к ссылкам на проект

и создать ярлык в определенном месте:

    void CreateShortcut(string linkPath, string filename)
    {
        // Create shortcut dir if not exists
        if (!Directory.Exists(linkPath))
            Directory.CreateDirectory(linkPath);

        // shortcut file name
        string linkName = Path.ChangeExtension(Path.GetFileName(filename), ".lnk");

        // COM object instance/props
        IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
        IWshRuntimeLibrary.IWshShortcut sc = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(linkName);
        sc.Description = "some desc";
        //shortcut.IconLocation = @"C:\..."; 
        sc.TargetPath = linkPath;
        // save shortcut to target
        sc.Save();
    }

0
private void CreateShortcut(string executablePath, string name)
    {
        CMDexec("echo Set oWS = WScript.CreateObject('WScript.Shell') > CreateShortcut.vbs");
        CMDexec("echo sLinkFile = '" + Environment.GetEnvironmentVariable("homedrive") + "\\users\\" + Environment.GetEnvironmentVariable("username") + "\\desktop\\" + name + ".ink' >> CreateShortcut.vbs");
        CMDexec("echo Set oLink = oWS.CreateShortcut(sLinkFile) >> CreateShortcut.vbs");
        CMDexec("echo oLink.TargetPath = '" + executablePath + "' >> CreateShortcut.vbs");
        CMDexec("echo oLink.Save >> CreateShortcut.vbs");
        CMDexec("cscript CreateShortcut.vbs");
        CMDexec("del CreateShortcut.vbs");
    }

0

Я создал класс-оболочку на основе ответа Рустама Ирзаева с использованием IWshRuntimeLibrary.

IWshRuntimeLibrary -> Ссылки -> COM> Windows Script Host Object Model

using System;
using System.IO;
using IWshRuntimeLibrary;
using File = System.IO.File;

public static class Shortcut
{
    public static void CreateShortcut(string originalFilePathAndName, string destinationSavePath)
    {
        string fileName = Path.GetFileNameWithoutExtension(originalFilePathAndName);
        string originalFilePath = Path.GetDirectoryName(originalFilePathAndName);

        string link = destinationSavePath + Path.DirectorySeparatorChar + fileName + ".lnk";
        var shell = new WshShell();
        var shortcut = shell.CreateShortcut(link) as IWshShortcut;
        if (shortcut != null)
        {
            shortcut.TargetPath = originalFilePathAndName;
            shortcut.WorkingDirectory = originalFilePath;
            shortcut.Save();
        }
    }

    public static void CreateStartupShortcut()
    {
        CreateShortcut(System.Reflection.Assembly.GetEntryAssembly()?.Location, Environment.GetFolderPath(Environment.SpecialFolder.Startup));
    }

    public static void DeleteShortcut(string originalFilePathAndName, string destinationSavePath)
    {
        string fileName = Path.GetFileNameWithoutExtension(originalFilePathAndName);
        string originalFilePath = Path.GetDirectoryName(originalFilePathAndName);

        string link = destinationSavePath + Path.DirectorySeparatorChar + fileName + ".lnk";
        if (File.Exists(link)) File.Delete(link);
    }

    public static void DeleteStartupShortcut()
    {
        DeleteShortcut(System.Reflection.Assembly.GetEntryAssembly()?.Location, Environment.GetFolderPath(Environment.SpecialFolder.Startup));
    }
}

-2

В Windows Vista / 7/8/10 вы можете вместо этого создать символическую ссылку через mklink.

Process.Start("cmd.exe", $"/c mklink {linkName} {applicationPath}");

Или позвоните CreateSymbolicLinkчерез P / Invoke.


Это не имеет ничего общего с ярлыком.
— Мэтт
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.