【问题标题】:Create a shortcut on Desktop在桌面上创建快捷方式
【发布时间】:2011-06-21 07:47:28
【问题描述】:

我想在桌面上创建一个指向某个 EXE 文件的快捷方式,使用 .NET Framework 3.5 并依赖官方 Windows API。我怎样才能做到这一点?

【问题讨论】:

  • 使用 Rustam Irzaev 的 Windows 脚本宿主对象模型是正确快捷方式的唯一可靠模型。 ayush:这项技术遗漏了许多功能,例如热键和描述。 Thorarin:ShellLink 在大多数情况下运行良好,但值得注意的是它在 Windows XP 中无法运行,并且会创建无效的快捷方式。 Simon Mourier:这很有前途,但在 Windows 8 中创建了无效的快捷方式。
  • Simon Mourier 的回答是这里的最佳答案。创建快捷方式的唯一正确且防弹的方法是使用操作系统使用的相同 API,这就是 IShellLink 接口。不要使用 Windows 脚本宿主或创建 Web 链接! Simon Mourier 用 6 行代码展示了如何做到这一点。任何对此方法有问题的人肯定会通过无效路径。我在 Windows XP、7 和 10 上测试了他的代码。将您的应用程序编译为“任何 CPU”以避免 32/64 位 Windows 出现问题,这些 Windows 对 Program Files 等使用不同的文件夹。
  • 我可以证明 Simon Mourier 的回答对我不起作用的原因是我的路径无效。确保检查额外或缺失的“\\”。修复该错误后工作。

标签: c#


【解决方案1】:

带有附加选项,例如热键、描述等。

首先,项目 > 添加引用 > 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();
}

【讨论】:

  • 这对我来说真的很接近。我需要将 .exe 的目录添加到快捷方式的“WorkingDirectory”属性中。 (shortcut.WorkingDirectory) +1
  • 要指定图标索引(在 IconLocation 中),请使用类似“path_to_icon_file,#”的值,其中 # 是图标索引。见msdn.microsoft.com/en-us/library/xsy6k3ys(v=vs.84).aspx
  • for 参数:shortcut.Arguments = "Seta Map mp_crash"; stackoverflow.com/a/18491229/2155778
  • Environment.SpecialFolders.System -- 不存在... Environment.SpecialFolder.System -- 有效。
  • 要使用开始菜单的链接,请使用代码object shStartMenu = (object)"StartMenu";。还可以选择为所有用户提供链接,使用关键字“common”作为前缀。
【解决方案2】:

网址快捷方式

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

也可以查看example。

如果您想使用一些特定于 API 的函数,那么您将需要使用 IShellLink interface 以及 IPersistFile interface(通过 COM 互操作)。

Here is an article that goes into detail what you need to do it, as well as sample code.

【讨论】:

  • 以上这些工作正常。但我想通过一些 API 函数创建快捷方式,例如 DllImport("coredll.dll")] public static extern int SHCreateShortcut(StringBuilder szShortcut, StringBuilder szTarget);
  • 挑剔:您可以删除 flush() 行,因为 Using 块的终止应该为您处理它
  • 我在使用这种方法时遇到了很多问题... Windows 倾向于将快捷方式定义缓存在某处... 创建这样的快捷方式,删除它,然后创建一个具有相同名称但不同的 URL ...当您单击快捷方式时,Windows 可能会打开旧的已删除 URL。 Rustam 在下面的回答(使用 .lnk 而不是 .url)为我解决了这个问题
  • 很棒的答案。比使用 .lnk 文件时必须处理的可怕的 COM 管道要好得多。
  • 如果您有参数,则不起作用。例如:myprogram.exe Param1 Param2
【解决方案3】:

这是一段不依赖外部 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 版本中明确工作的例子是 Rustam Irzaev 使用 WSHOM:“这很有前途,但在 Windows 8 中创建了无效的快捷方式”
  • 我看不出这不起作用的任何切实原因。无论如何,IPersistFile 在 System.Runtime.InteropServices.ComTypes 中是开箱即用的
  • 此解决方案未在具有 32 位可执行文件的 64 位 Windows 10 上使用 SetIconLocation 设置正确的图标。此处描述了解决方案:stackoverflow.com/a/39282861,我也怀疑这与 Windows 8 的所有其他问题相同。可能与 64 位 Windows 上的 32 位 exe 文件有关。
  • @MarisB。就像我说的,我已经用上面的代码测试了你所说的 SetIconLocation, 64 vs 32,它工作正常。如果您对路径有疑问,那就是另一回事了。此问题与 Program Files 无关。
【解决方案4】:

您可以使用这个ShellLink.cs 类来创建快捷方式。

要获取桌面目录,请使用:

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

或使用Environment.SpecialFolder.CommonDesktopDirectory 为所有用户创建它。

【讨论】:

  • @Vipin:如果某个解决方案对您有用,通常会对其进行投票。此外,您应该选择最佳解决方案并将其作为您问题的答案。
  • 这将用 lnk 文件覆盖现有的 exe。在 Win10 上测试。
  • @zwcloud 这段代码不会覆盖任何东西,因为它什么都不做。它只是告诉您使用哪些类和方法来处理快捷方式。如果您的代码正在覆盖您身上的 exe。我会看看你是如何实际创建 lnk 文件的,看看它为什么会破坏你的 exe。
【解决方案5】:

无需额外参考:

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

【讨论】:

    【解决方案6】:

    我仅用于我的应用程序:

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

    【讨论】:

    • 开箱即用,只需复制粘贴即可
    【解决方案7】:

    在 vbAccelerator 使用ShellLink.cs 轻松创建您的快捷方式!

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

    【讨论】:

    • 该链接现已失效,但您可以找到它的存档版本here。
    【解决方案8】:

    这是我的代码:

    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,
        }
    }
    

    【讨论】:

      【解决方案9】:

      这是一个(经过测试的)扩展方法,cmets 可以帮助您。

      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");
      

      第一个参数设置 exe 名称(在当前目录中找到)第二个参数是“开始”文件夹,第三个参数是快捷方式描述。

      链接的命名约定对于它的作用没有任何歧义。要测试链接,只需双击它。

      最后说明:应用程序本身(目标)必须有一个与之关联的 ICON 图像。该链接很容易在 exe 中找到 ICON。如果目标应用程序有多个图标,您可以打开链接的属性并将图标更改为 exe 中的任何其他图标。

      【讨论】:

      • 我收到一条错误消息,指出 .GetFolderPath() 不存在。 XFile.Delete 也一样。我错过了什么?
      • 这里是否发生错误? Environment.SpecialFolder.Startup.GetFolderPath();
      【解决方案10】:

      我使用“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();
          }
      

      【讨论】:

        【解决方案11】:

        如果您希望将简单代码放在其他位置,请使用以下代码:

        using IWshRuntimeLibrary;
        
        WshShell shell = new WshShell();
        IWshShortcut shortcut = shell.CreateShortcut(@"C:\FOLDER\SOFTWARENAME.lnk");
        shortcut.TargetPath = @"C:\FOLDER\SOFTWARE.exe";
        shortcut.Save();
        

        【讨论】:

        • 这不是和5中的代码一样吗? 6?现有答案?
        • @MarcGravell 再读一遍。我说“如果你想要一个简单的代码”。比其他几行。
        • 我喜欢这个简洁的。其他的太吵了。你们 c# 的人总是那么吵吗?
        【解决方案12】:

        我使用 IWshRuntimeLibrary 根据 Rustam Irzaev 的回答创建了一个包装类。

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

        【讨论】:

          【解决方案13】:

          Windows API IShellLink 接口的VB 重写:

          <ComImport(), Guid("00021401-0000-0000-C000-000000000046")>
          Private Class ShellLink
          End Class
          
          <ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214F9-0000-0000-C000-000000000046")>
          Private Interface IShellLink
              Sub GetPath(<Out, MarshalAs(UnmanagedType.LPWStr)> ByVal pszFile As StringBuilder, ByVal cchMaxPath As Integer, <Out> ByRef pfd As IntPtr, ByVal fFlags As Integer)
              Sub GetIDList(<Out> ByRef ppidl As IntPtr)
              Sub SetIDList(ByVal pidl As IntPtr)
              Sub GetDescription(<Out, MarshalAs(UnmanagedType.LPWStr)> ByVal pszName As StringBuilder, ByVal cchMaxName As Integer)
              Sub SetDescription(<MarshalAs(UnmanagedType.LPWStr)> ByVal pszName As String)
              Sub GetWorkingDirectory(<Out, MarshalAs(UnmanagedType.LPWStr)> ByVal pszDir As StringBuilder, ByVal cchMaxPath As Integer)
              Sub SetWorkingDirectory(<MarshalAs(UnmanagedType.LPWStr)> ByVal pszDir As String)
              Sub GetArguments(<Out, MarshalAs(UnmanagedType.LPWStr)> ByVal pszArgs As StringBuilder, ByVal cchMaxPath As Integer)
              Sub SetArguments(<MarshalAs(UnmanagedType.LPWStr)> ByVal pszArgs As String)
              Sub GetHotkey(<Out> ByRef pwHotkey As Short)
              Sub SetHotkey(ByVal wHotkey As Short)
              Sub GetShowCmd(<Out> ByRef piShowCmd As Integer)
              Sub SetShowCmd(ByVal iShowCmd As Integer)
              Sub GetIconLocation(<Out, MarshalAs(UnmanagedType.LPWStr)> ByVal pszIconPath As StringBuilder, ByVal cchIconPath As Integer, <Out> ByRef piIcon As Integer)
              Sub SetIconLocation(<MarshalAs(UnmanagedType.LPWStr)> ByVal pszIconPath As String, ByVal iIcon As Integer)
              Sub SetRelativePath(<MarshalAs(UnmanagedType.LPWStr)> ByVal pszPathRel As String, ByVal dwReserved As Integer)
              Sub Resolve(ByVal hwnd As IntPtr, ByVal fFlags As Integer)
              Sub SetPath(<MarshalAs(UnmanagedType.LPWStr)> ByVal pszFile As String)
          End Interface
          
          'How to use:
          Public Shared Sub CreateNewShortcut(LNKLocation As String, LNKTarget As String, Optional TargetArgs As String = Nothing, Optional StartFolder As String = Nothing,Optional Description As String = Nothing, Optional IconFile As String = "c:\windows\System32\SHELL32.dll", Optional IconIndex As Integer = 21)
              Dim link As IShellLink = CType(New ShellLink(), IShellLink)
              If Description <> Nothing Then link.SetDescription(Description)
              If TargetArgs <> Nothing Then link.SetArguments(TargetArgs)
              If IconFile <> Nothing Then link.SetIconLocation(IconFile, IconIndex)
              link.SetPath(LNKTarget)
              Dim file As System.Runtime.InteropServices.ComTypes.IPersistFile = CType(link, System.Runtime.InteropServices.ComTypes.IPersistFile)
              file.Save(LNKLocation, False)
          End Sub
          

          【讨论】:

            【解决方案14】:
            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");
                }
            

            【讨论】:

              【解决方案15】:

              对于 Windows Vista/7/8/10,您可以通过 mklink 创建符号链接。

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

              或者,通过 P/Invoke 致电 CreateSymbolicLink。

              【讨论】:

              • 这与快捷方式无关。
              猜你喜欢
              • 2013-03-14
              • 2013-07-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-01-21
              • 2012-08-05
              • 1970-01-01
              相关资源
              最近更新 更多