如何在PowerShell中为含特殊字符文件名的文件创建Windows快捷方式
PowerShell创建支持Unicode特殊字符的Windows快捷方式方案
WScript.Shell组件天生不支持Unicode路径,无法处理带表情符号、多语言字符的文件名,以下方案直接调用Windows底层Shell32的Unicode接口实现,兼容Windows 10/11全版本,和系统右键创建的快捷方式完全一致。
# 嵌入Shell32快捷方式实现代码 Add-Type @' using System; using System.Runtime.InteropServices; using System.Text; public class ShellShortcut { [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct WIN32_FIND_DATAW { public uint dwFileAttributes; public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime; public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime; public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime; public uint nFileSizeHigh; public uint nFileSizeLow; public uint dwReserved0; public uint dwReserved1; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string cFileName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)] public string cAlternateFileName; } [Guid("000214F9-0000-0000-C000-000000000046")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IShellLinkW { void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out WIN32_FIND_DATAW pfd, uint 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 ushort pwHotkey); void SetHotkey(ushort 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, uint dwReserved); void Resolve(IntPtr hwnd, uint fFlags); void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile); } [Guid("00021401-0000-0000-C000-000000000046")] [ClassInterface(ClassInterfaceType.None)] public class ShellLinkClass { } public static void Create(string shortcutPath, string targetPath, string workingDirectory = null, string arguments = null, string description = null) { IShellLinkW link = (IShellLinkW)new ShellLinkClass(); link.SetPath(targetPath); if (!string.IsNullOrEmpty(workingDirectory)) link.SetWorkingDirectory(workingDirectory); if (!string.IsNullOrEmpty(arguments)) link.SetArguments(arguments); if (!string.IsNullOrEmpty(description)) link.SetDescription(description); var persistFile = (System.Runtime.InteropServices.ComTypes.IPersistFile)link; persistFile.Save(shortcutPath, true); Marshal.ReleaseComObject(link); } } '@ # 调用示例 [ShellShortcut]::Create( "F:\path\to\保存的快捷方式.lnk", # 替换为你的快捷方式输出路径 "F:\目标文件路径\带表情😍的文件.txt" # 替换为带特殊字符的目标文件/文件夹路径 )
使用说明
- 该实现调用的是Windows官方公开的Win32接口,不存在版本兼容问题,Windows 10、Windows 11所有正式版均可正常运行
- 除了必填的两个路径参数外,还支持可选传入工作目录、启动参数、快捷方式描述三个参数,按需填写即可
- 所有路径均支持任意Unicode字符,包括表情符号、各国语言文字、特殊符号等,创建的快捷方式和系统右键生成的功能完全一致
- 如果需要自定义快捷方式图标,可在Create方法中扩展调用IShellLinkW的SetIconLocation方法即可实现
内容的提问来源于stack exchange,提问作者shox
相关产品推荐
相关产品推荐

