创建快捷方式修改目标路径
Creating shortcut modifies the path to target
我正在尝试在我的 windows 文件系统上创建一个快捷方式 (.lnk)。
我的代码工作正常。但是,当我 运行 相同的控制台应用程序 在 Windows 2008R2 服务器上时,它的行为 不同 .
所以我有我的控制台应用程序,这是发生的事情:
我的程序只是在桌面上创建了一个扩展名为 .docx 的快捷方式,并且在我的本地计算机上一切正常。当我在服务器上 运行 相同的控制台应用程序时,它会创建相同的快捷方式,但 目标已修改 ... 它将目标更改为 。文档 文件。
换句话说,当我 运行 控制台应用程序时:
本地机器
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" 是 "my file.abcd" 的 short name。此类名称始终在仍启用短名称生成功能的文件系统上创建。几乎所有的人仍然这样做,尽管今天已经很少需要了。保持 "my file.abcd" 与只能处理 MS-Dos 名称的程序兼容确实需要替换 space 并将扩展名缩短为 3 个字母。您还经常在此类名称中看到“~1”,用于将文件名截断为 8 个字母。
您可以看到带DIR /x
的简称。
问题中并不清楚您是如何看到该文件的简称的。但是IShellLink接口声明肯定是错误的,方法没有按照正确的顺序列出。这对 ComInterfaceType.InterfaceIsIUnknown 接口有相当严重的后果,您将在运行时调用错误的方法。 Path 属性 setter 实际上是第二种方法。您现在正在调用第 18 个方法,它没有声明,因此很难猜测它可能做什么。好吧,如果它不抛出异常,这是非常令人惊讶的,这符合条件 :) 顺便说一句,这并非完全不可信,添加的第 17 个方法是 getter 用于 Target property,稍后添加界面的版本。您可能会不小心碰到未记录的 setter。有意未记录。
只是不要自己声明接口。最好的方法是使用 Project > Add Reference > Browse button > select C:\Windows\System32\Shell32.dll。 this post.
中有更详细的描述
我正在尝试在我的 windows 文件系统上创建一个快捷方式 (.lnk)。
我的代码工作正常。但是,当我 运行 相同的控制台应用程序 在 Windows 2008R2 服务器上时,它的行为 不同 .
所以我有我的控制台应用程序,这是发生的事情:
我的程序只是在桌面上创建了一个扩展名为 .docx 的快捷方式,并且在我的本地计算机上一切正常。当我在服务器上 运行 相同的控制台应用程序时,它会创建相同的快捷方式,但 目标已修改 ... 它将目标更改为 。文档 文件。
换句话说,当我 运行 控制台应用程序时:
本地机器
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" 是 "my file.abcd" 的 short name。此类名称始终在仍启用短名称生成功能的文件系统上创建。几乎所有的人仍然这样做,尽管今天已经很少需要了。保持 "my file.abcd" 与只能处理 MS-Dos 名称的程序兼容确实需要替换 space 并将扩展名缩短为 3 个字母。您还经常在此类名称中看到“~1”,用于将文件名截断为 8 个字母。
您可以看到带DIR /x
的简称。
问题中并不清楚您是如何看到该文件的简称的。但是IShellLink接口声明肯定是错误的,方法没有按照正确的顺序列出。这对 ComInterfaceType.InterfaceIsIUnknown 接口有相当严重的后果,您将在运行时调用错误的方法。 Path 属性 setter 实际上是第二种方法。您现在正在调用第 18 个方法,它没有声明,因此很难猜测它可能做什么。好吧,如果它不抛出异常,这是非常令人惊讶的,这符合条件 :) 顺便说一句,这并非完全不可信,添加的第 17 个方法是 getter 用于 Target property,稍后添加界面的版本。您可能会不小心碰到未记录的 setter。有意未记录。
只是不要自己声明接口。最好的方法是使用 Project > Add Reference > Browse button > select C:\Windows\System32\Shell32.dll。 this post.
中有更详细的描述