繁体   English   中英

如何将 Powershell 中的 Windows 快捷方式创建到文件名中包含特殊字符的文件?

[英]How to create a Windows Shortcut in Powershell to a file with special characters in filename?

我通常不会遇到编程问题,因为我可以轻松找到大多数问题的答案。 但我在这个问题上束手无策。

在 Powershell 中创建 Windows 快捷方式的众所周知的方法如下:

$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("F:\path\to\shortcut.lnk")
$Shortcut.TargetPath = "F:\some\other\path\to\targetfile.txt"
$Shortcut.Save()

然而,这种方法有一个缺点,我开始被越来越多的困扰:当文件名有特殊字符时它不起作用,例如文件名中的笑脸:

"targetfile 😍.txt"

我研究了这个问题并在这里发现 WshShortcut object 和 WScript 不能接受文件名中的 unicode。 它似乎只适用于一组简单的字符。 当然,当您右键单击 Windows 和 select 中的文件时,“创建快捷方式” Windows 在创建带有特殊字符的快捷方式时没有问题。

有人在 C# 中编写了另一种使用 Shell32 创建快捷方式的方法,但我不知道它是否可以在 Powershell 中完成。 它看起来像是一种旧方法,可能不适用于 Windows 的较新版本。

有人可以帮我解决这个问题吗? 如何将 Powershell 中的 Windows 快捷方式创建到文件名中包含特殊字符的文件?

如有疑问,请使用 C#:

$ShellLinkCSharp = @'
namespace Shox
{
    using System;
    using System.Runtime.InteropServices;
    using System.Runtime.InteropServices.ComTypes;
    using System.Text;

    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("000214F9-0000-0000-C000-000000000046")]
    [CoClass(typeof(CShellLinkW))]
    interface IShellLinkW
    {
        void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out IntPtr pfd, uint fFlags);
        IntPtr GetIDList();
        void SetIDList(IntPtr pidl);
        void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, 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);
        ushort GetHotKey();
        void SetHotKey(ushort wHotKey);
        uint GetShowCmd();
        void SetShowCmd(uint 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, [Optional] uint dwReserved);
        void Resolve(IntPtr hwnd, uint fFlags);
        void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
    }

    [ComImport]
    [Guid("00021401-0000-0000-C000-000000000046")]
    [ClassInterface(ClassInterfaceType.None)]
    class CShellLinkW { }

    public static class ShellLink
    {
        public static void CreateShortcut(string lnkPath, string targetPath, string description)
        {
            IShellLinkW link = new IShellLinkW();

            link.SetPath(targetPath);

            if (!string.IsNullOrWhiteSpace(description))
            {
                link.SetDescription(description);
            }

            IPersistFile file = (IPersistFile)link;
            file.Save(lnkPath, true);

            Marshal.FinalReleaseComObject(link);
        }
    }
}
'@

# Check if Shox.ShellLink class already exists; if not, import it:
if (-not ([System.Management.Automation.PSTypeName]'Shox.ShellLink').Type)
{
    Add-Type -TypeDefinition $ShellLinkCSharp
}


[Shox.ShellLink]::CreateShortcut('F:\path\to\shortcut1.lnk', 'F:\some\other\path\to\targetfile1 😍.txt', '😍😍')

[Shox.ShellLink]::CreateShortcut('F:\path\to\shortcut2.lnk', 'F:\some\other\path\to\targetfile2 😍.txt', $null)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM