项目场景:
使用C#创建快捷方式就是要创建一个lnk文件,并设置相关的属性。.NET框架本身是没有提供方法的。
查找全网大多数写法需要引入IWshRuntimeLibrary。在添加引用对话框中搜索Windows Script Host Object Model,选择之后添加到Project的引用中(笔者之前也是这么用的)。
问题描述
但是出现了部分电脑无法引用IWshRuntimeLibrary.dll。如下图:
所以有了这篇文章。
解决方案:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
class AutoStart
{
/// <summary>
/// 快捷方式名称-任意自定义
/// </summary>
private const string QuickName = "VisionProSystem";
/// <summary>
/// 自动获取系统自动启动目录
/// </summary>
private string systemStartPath { get { return Environment.GetFolderPath(Environment.SpecialFolder.Startup); } }
/// <summary>
/// 自动获取程序完整路径
/// </summary>
private string appAllPath
{
get
{
string path = Process.GetCurrentProcess().MainModule.FileName;
if (path.Contains(".vshost"))
{
path = path.Replace(".vshost", "");
}
return path;
}
}
/// <summary>
/// 自动获取桌面目录
/// </summary>
private string desktopPath { get { return Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); } }
/// <summary>
/// 设置开机自动启动和桌面快捷方式,默认创建
/// --只需要调用改方法就可以了
/// </summary>
/// <param name="onOff">自启开关</param>
public void SetMeAutoStart(bool autostart = true, bool desktop = true)
{
if (autostart)//开机启动
{
//获取启动路径应用程序快捷方式的路径集合
List<string> shortcutPaths = GetQuickFromFolder(systemStartPath, appAllPath);
//存在2个以快捷方式则保留一个快捷方式-避免重复多于
if (shortcutPaths.Count >= 2)
{
for (int i = 1; i < shortcutPaths.Count; i++)
{
DeleteFile(shortcutPaths[i]);
}
}
else if (shortcutPaths.Count < 1)//不存在则创建快捷方式
{
CreatShortcut(systemStartPath, QuickName, appAllPath, "Alley@NOVO");
}
}
else//开机不启动
{
//获取启动路径应用程序快捷方式的路径集合
List<string> shortcutPaths = GetQuickFromFolder(systemStartPath, appAllPath);
//存在快捷方式则遍历全部删除
if (shortcutPaths.Count > 0)
{
for (int i = 0; i < shortcutPaths.Count; i++)
{
DeleteFile(shortcutPaths[i]);
}
}
}
if (desktop)
{
//创建桌面快捷方式
CreateDesktopQuick(desktopPath, QuickName, appAllPath);
}
}
/// <summary>
/// 获取指定文件夹下指定应用程序的快捷方式路径集合
/// </summary>
/// <param name="directory">文件夹</param>
/// <param name="targetPath">目标应用程序路径</param>
/// <returns>目标应用程序的快捷方式</returns>
private List<string> GetQuickFromFolder(string directory, string targetPath)
{
List<string> tempStrs = new List<string>();
tempStrs.Clear();
string tempStr = null;
string[] files = Directory.GetFiles(directory, "*.lnk");
if (files == null || files.Length < 1)
{
return tempStrs;
}
for (int i = 0; i < files.Length; i++)
{
tempStr = GetAppPathFromQuick(files[i]);
if (tempStr == targetPath)
{
tempStrs.Add(files[i]);
}
}
return tempStrs;
}
/// <summary>
/// 获取快捷方式的目标文件路径-用于判断是否已经开启了自动启动
/// </summary>
/// <param name="shortcutPath"></param>
/// <returns></returns>
private string GetAppPathFromQuick(string shortcutPath)
{
string sfile = Path.Combine(desktopPath, QuickName + ".lnk");
IShellLink link = (IShellLink)new ShellLink();
IPersistFile file = (IPersistFile)link;
try
{
file.Load(sfile, 2);
}
catch (Exception)
{
return null;
}
StringBuilder sb = new StringBuilder(256);
link.GetPath(sb, sb.Capacity, IntPtr.Zero, 2);
return sb.ToString();
}
/// <summary>
/// 根据路径删除文件-用于取消自启时从计算机自启目录删除程序的快捷方式
/// </summary>
/// <param name="path">路径</param>
private void DeleteFile(string path)
{
FileAttributes attr = System.IO.File.GetAttributes(path);
if (attr == FileAttributes.Directory)
{
Directory.Delete(path, true);
}
else
{
System.IO.File.Delete(path);
}
}
/// <summary>
/// 在桌面上创建快捷方式
/// </summary>
/// <param name="desktopPath">桌面地址</param>
/// <param name="appPath">应用路径</param>
private void CreateDesktopQuick(string DesktopPath = "", string quickName = QuickName, string AppPath = "")
{
DesktopPath = desktopPath;
AppPath = appAllPath;
List<string> shortcutPaths = GetQuickFromFolder(desktopPath, AppPath);
//如果没有则创建
if (shortcutPaths.Count < 1)
{
CreatShortcut(desktopPath, quickName, AppPath, "Alley@NOVO");
}
}
[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, 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);
}
/// <summary>
/// 向目标路径创建指定文件的快捷方式
/// </summary>
/// <param name="desktopPath">快捷方式路径</param>
/// <param name="quickname">快捷方式名</param>
/// <param name="apppath">App路径</param>
/// <param name="description">提示信息</param>
private void CreatShortcut(string desktopPath, string quickname, string apppath, string description)
{
IShellLink link = (IShellLink)new ShellLink();
link.SetDescription(description);
link.SetPath(apppath); //指定文件路径
IPersistFile file = (IPersistFile)link;
string sfile = Path.Combine(desktopPath, quickname + ".lnk");
if (File.Exists(sfile))
File.Delete(sfile);
file.Save(sfile, false); //快捷方式保存到桌面
}
}
}