Створіть ярлик на робочому столі


106

Я хочу створити ярлик, який вказує на якийсь файл EXE на робочому столі, використовуючи .NET Framework 3.5 і спираючись на офіційний API Windows. Як я можу це зробити?


1
Використання об'єктної моделі хост-скриптів Windows від Рустама Ірзаєва є єдиною надійною для правильного ярлика. ayush: у цій техніці пропущено купу функцій, як гарячі клавіші та описи. Торарін: ShellLink працює в більшості випадків, але особливо це не працює в Windows XP і створює недійсні ярлики. Саймон Мур'є: Це було дуже перспективно, але створює недійсні ярлики в Windows 8.
BrutalDev

Тут найкраща відповідь від Сімона Мур’є. Єдиний правильний і непоказний спосіб створення ярликів - це використання того ж API, який використовує операційна система, і це інтерфейс IShellLink. Не використовуйте хост сценарію Windows і не створюйте веб-посилання! Саймон Мур’є показує, як це зробити за допомогою 6 рядків коду. Усі, хто мав проблеми з цим методом, НАДІЙНО пройшли недійсні шляхи. Я протестував його код на Windows XP, 7 та 10. Складіть додаток як "Будь-який процесор", щоб уникнути проблем із 32/64 бітовою Windows, яка використовує різні папки для програмних файлів та ін.
Елмуе

Відповіді:


120

З додатковими параметрами, такими як швидка клавіша, опис тощо.

Спочатку Project > Додати довідку > COM > Модель об'єкта хост-сценарію Windows.

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" у ярлику. (ярлик.
Робочий довідник

4
Щоб вказати індекс значка (у IconLocation), використовуйте таке значення, як "path_to_icon_file, #", де # - індекс значка. Дивіться msdn.microsoft.com/en-us/library/xsy6k3ys(v=vs.84).aspx
Кріс

1
для аргументу: ярлик. Аргументи = "Карта сети mp_crash"; stackoverflow.com/a/18491229/2155778
Zolfaghari

7
Environment.SpecialFolders.System - не існує ... Environment.SpecialFolder.System - працює.
JSWulf

обов'язково потрібно також додати Microsoft.CSharp в якості посилання.
l1nuxuser

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")] публічний статичний зовнішній код int SHCreateShortcut (StringBuilder szShortcut, StringBuilder szTarget);
Vipin Arora

@Vipin чому? Чи є якась причина, чому будь-яке з перерахованих вище рішень недостатньо добре?
alex

8
nitpicking: ви можете видалити рядок flush (), оскільки припинення блоку використання повинне піклуватися про вас
Newtopian

3
У мене було багато проблем з цим методом ... Windows, як правило, десь кешує визначення ярлика ... створити ярлик, як цей, видалити його, а потім створити його з тим же ім'ям, але іншою URL-адресою ... швидше за все, Windows відкриє стару видалену 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, і він працює.
Simon Mourier

Також запускаючи Win8 x64, скопіювавши зразок коду вище, як є, він створює піктограму на моєму робочому столі без шляху. Виконання посилання просто відкриває провідник на робочий стіл. Це аналогічне питання, яке було у ShellLink.cs, але в Windows XP / 2003. Єдиний приклад, який остаточно працює у всіх версіях Windows, - це використання WSHOM Рустама Ірзаєва, як я згадував у своєму коментарі до головного питання: "Це було дуже перспективно, але створюються недійсні ярлики в Windows 8"
BrutalDev

Я отримав це для роботи в Windows 8.1 x64, але код, наведений зараз, не має визначення для IPersistFile. Мені довелося скопіювати це з публікації ShellLink.cs, щоб змусити його працювати.
Уолтер Вільфінгер

Я не бачу жодної відчутної причини, чому це не спрацювало б. У будь-якому випадку, IPersistFile доступний поза системою у System.Runtime.InteropServices.ComTypes
Simon Mourier

1
Це рішення не встановлює правильну піктограму, використовуючи SetIconLocation64-бітну Windows 10 з 32-бітним виконуваним файлом. Тут описано рішення: stackoverflow.com/a/39282861, і я також підозрюю, що це та сама проблема з Windows 8, з якою ставляться всі інші. Це може бути пов’язано з 32-розрядними файлами EXE в 64-розрядної Windows.
Маріс Б.

26

Ви можете використовувати цей клас ShellLink.cs для створення ярлика.

Щоб отримати каталог робочого столу, використовуйте:

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

або використовувати Environment.SpecialFolder.CommonDesktopDirectoryйого для створення всіх користувачів.


6
@Vipin: якщо рішення працює для вас, прийнято його прийняти. Також слід вибрати найкраще рішення та прийняти його як відповідь на свою проблему.
Торарін

Це замінить існуючий exe з файлом lnk. Тестовано на Win10.
zwcloud

@zwcloud Цей код нічого не перезаписує, оскільки він нічого не робить. Це просто розповісти, які класи та методи використовувати для роботи з ярликами. Якщо ваш код перезаписав exe, яке на вас. Я хотів би подивитися на те, як ви насправді створюєте файл 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

РЕДАКТУВАТИ: Я більше не рекомендую це рішення. Якщо поки що немає кращого методу, ніж використання сценарію Windows, використовуйте рішення @ Мехмета, яке викликає двигун безпосередньо, а не створює звичайний текстовий скрипт у пам'яті.

Ми використовували 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. Що я пропускаю?
РальфФ

Чи трапляється помилка тут? Environment.SpecialFolder.Startup.GetFolderPath ();
Джон Петерс

2

Для створення ярлика я використовую посилання "Модель об'єкта хост сценарію Windows".

Додавання "Модель об'єкта хост-скрипта 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

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.