我正在尝试在我的 Windows 文件系统上创建一个快捷方式 (.lnk)。
我的代码工作正常。但是,当我在 Windows 2008R2 服务器上运行相同的控制台应用程序时,它的行为不同。
所以我有我的控制台应用程序,下面是发生的事情:
我的程序只是在桌面上创建一个扩展名为 .docx 的快捷方式,并且在我的本地计算机上一切正常。当我在服务器上运行相同的控制台应用程序时,它会创建相同的快捷方式,但目标已修改...它将目标更改为 .doc 文件。
换句话说,当我运行控制台应用程序时:
本地机器
Creates MyWordFile.lnk pointing to U:\test.docx
服务器
Creates MyWordFile.lnk pointing to U:\test.doc
这是一种奇怪的行为。这是代码
代码
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)
{
//ShortcutTarget
var sTarget = @"U:\test.docx";
//ShortCutName
var sName = @"MyWordFile.lnk";
IShellLink link = (IShellLink)new ShellLink();
link.SetPath(sTarget);
IPersistFile file = (IPersistFile)link;
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
file.Save(Path.Combine(desktopPath, sName), 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);
}
}
更新
I noticed that the 4th character gets removed from the target's extension. So, when i have a file "file.abcdef", the link points at "file.abc". Also spaces get replaced for underscores, so "my file.abcd" pointer becomes "my_file.abc"
最佳答案
创建快捷方式不会修改目标名称。
您看到的是其他内容,“my_file.abc”是 short name “我的文件.abcd”。此类名称始终在仍启用短名称生成功能的文件系统上创建。几乎所有的人仍然这样做,尽管今天已经很少需要了。要使“my file.abcd”与只能处理 MS-Dos 名称的程序兼容,确实需要替换空格并将扩展名缩短为 3 个字母。您还经常在此类名称中看到“~1”,用于将文件名截断为 8 个字母。
您可以使用 DIR/x
查看短名称。
问题中并不清楚您究竟是如何看到该文件的短名称的。但是IShellLink接口(interface)声明肯定是错误的,方法没有按照正确的顺序列出。这对 ComInterfaceType.InterfaceIsIUnknown 接口(interface)有相当严重的后果,您将在运行时调用错误的方法。 Path 属性 setter 实际上是第二种方法。您现在正在调用第 18 个方法,它没有声明,因此很难猜测它可能做什么。好吧,如果它不抛出异常,这是非常令人惊讶的,这符合条件 :) 顺便说一句,这并非完全不可信,添加的第 17 个方法是 Target property 的 getter。 , 在以后版本的界面中添加。您可能会不小心撞到未记录的二传手。有意未记录。
只是不要自己声明接口(interface)。最好的方法是使用项目 > 添加引用 > 浏览按钮 > 选择 C:\Windows\System32\Shell32.dll。在 this post 中有更详细的描述.
关于c# - 创建快捷方式修改目标路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42510063/