【问题标题】:MS Paint shortcut exist on desktop or not?桌面上是否存在 MS Paint 快捷方式?
【发布时间】:2016-03-13 07:36:08
【问题描述】:

我想知道桌面中是否存在 mspaint 快捷方式?如果存在,则用户评分为 7,否则为 0。我使用此代码:

  string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
  if (Directory.Exist (path + @"\mspaint.exe"))
  {
      Controller.ExamController.AddExam(1, n, 7, time, Session.currentUserId);
  }
  else
  {
      Controller.ExamController.AddExam(1, n, 0, time, Session.currentUserId);
  }

但无论如何结果是“0”。但此代码适用于目录和文件夹并返回 7。 我也尝试“File.Exist”,但它有同样的问题。

如何查看桌面是否存在特定程序的快捷方式?

    if (questionNumber == 2)
        {


            string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            var list = Directory.EnumerateFiles(path);
            foreach (var v in list)
            {
                var extension = Path.GetExtension(v);
                if (extension.Equals(".lnk", StringComparison.InvariantCultureIgnoreCase))
                {
                    WshShell shell = new WshShell();
                    IWshShortcut link = (IWshShortcut)shell.CreateShortcut(v);
                    if (Path.GetFileName(link.TargetPath).Equals("mspaint.exe", StringComparison.InvariantCultureIgnoreCase))
                    {
                        Controller.ExamController.AddExam(1, n, 7, time, Session.currentUserId);
                    }
                    else
                    {
                        Controller.ExamController.AddExam(1, n, 0, time, Session.currentUserId);
                    }
                }
            }



        }

当我使用它时,它没问题,但它返回 0 表示不存在,返回 0 和 7 表示存在

【问题讨论】:

  • 这不起作用的原因是因为快捷方式是一种特殊的文件,它包含指向某个位置的数据(例如 mspaint.exe),但这并不意味着它需要命名为与它指向的 exe 相同。所以它可以有一个名称“HappyPaint.lnk”并指向“mspaint.exe”。我建议将问题修改为“我如何阅读快捷方式目的地”。

标签: c# file


【解决方案1】:

快捷方式只是另一种文件类型,正如MSDN 所说:

当用户通过选择“创建”来创建对象的快捷方式时 对象快捷菜单中的快捷命令,Windows 存储 访问链接文件(二进制文件)中的对象所需的信息 具有 .lnk 文件扩展名的文件。

这意味着您应该准确引用快捷方式:具有准确的名称和.lnk 扩展名。

您需要检查快捷方式,例如:

File.Exist(Path.Combine(path, "Paint.lnk"))

但在我看来,正确的解决方案是从桌面获取所有快捷方式并检查 mspaint.exe 路径的每个快捷方式的目标路径。

要阅读快捷方式信息,请阅读此 SO 帖子:Get target of shortcut folder

【讨论】:

  • 谢谢,您能否解释一下从桌面获取所有快捷方式并检查每个快捷方式的目标路径以获取 mspaint.exe 路径?
  • 我试图替换 "Directory.Exists (Path.Combine(path + @"\p.lnk"))" 但它有同样的问题并返回 0
  • @Ali 你的桌面上是否有p.lnk 文件(名为“p”的快捷方式)?还要注意这一行:Directory.Exist(Path.Combine(path, @"\Paint.lnk"))
  • Directory.Exist 更改为File.Exist
  • static void Main(string[] args) { string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); var combinedPath = Path.Combine(desktopPath, @"p.lnk"); var isShortcut = File.Exists(combinedPath); } 这是经过测试的工作示例。
【解决方案2】:

这需要显式编码,您不能在deskTop中查找文件名,因为它可以更改为任何内容,因为它只是一个捷径,

包含 COM 插件参考 Windows 脚本宿主对象模型 - Interop.IWshRuntimeLibrary

using IWshRuntimeLibrary;

public string test()
        {
            string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            var list = Directory.EnumerateFiles(path);
            foreach(var v in list)
            {
                var extension = Path.GetExtension(v);
                if (extension.Equals(".lnk", StringComparison.InvariantCultureIgnoreCase))
                {
                    WshShell shell = new WshShell(); 
                    IWshShortcut link = (IWshShortcut) shell.CreateShortcut(v);
                    if (Path.GetFileName(link.TargetPath).Equals("mspaint.exe", StringComparison.InvariantCultureIgnoreCase))
                    {
                        return link.TargetPath;
                    }
                }
            }
            return null;
        }

【讨论】:

  • 嘿,谢谢你,我使用你的代码并且工作正常,但只有一个问题(更新我的问题),当快捷方式不存在时,它返回 0 但如果存在,它返回7 然后 0。所以当它存在时,我的表中有两条记录
  • 你能解释一下“它返回 0 但如果存在,它返回 7 然后返回 0”的确切含义吗?
  • 这是一个测试,如果是快捷方式,则必须在数据库中提交标记7,否则将提交标记0。但现在的问题是,当快捷方式存在时,2record 将添加到表中,分别为 0 和 7。但是当不存在时,它可以,只需添加一个带有标记 0 的记录
  • @Ali 你需要调试一下,看看是否有多余的调用去同一个方法。代码要么在给定的调用中转到 if OR else,它不能同时执行,因此可能是整个方法被调用了两次。请调试或添加一些日志以查看究竟是什么问题。
【解决方案3】:

快捷方式是一种特殊的文件

快捷方式是一种特殊的文件。它包含指向某个位置的数据(例如 mspaint.exe),但这并不意味着它需要与它所指向的 exe 命名相同。例如,它可以具有“HappyPaint.lnk”的名称并指向“mspaint.exe”。

阅读快捷方式目的地

因此,您需要在桌面上查找所有“*.lnk”文件并读取它们的目标路径。您可以这样做:

首先,添加对Microsoft Shell Controls And Automation的引用:

其次,添加一些代码:

string desktopDirectoryPath = Environment.GetFolderPath(
    Environment.SpecialFolder.DesktopDirectory);

string msPaintPath = Environment.ExpandEnvironmentVariables(
    @"%windir%\system32\mspaint.exe");

// add reference to COM --> Microsoft Shell controls and Automation
Shell shell = new Shell();
Folder folder = shell.NameSpace(desktopDirectoryPath);

var shortcutFilePaths = Directory.GetFiles(desktopDirectoryPath, "*.lnk");

bool msPaintShortcutExists = false;

foreach (string shortcutFilePath in shortcutFilePaths)
{
    FolderItem folderItem = folder.ParseName(Path.GetFileName(shortcutFilePath));
    Shell32.ShellLinkObject link = (Shell32.ShellLinkObject) folderItem.GetLink;
    var shortcutDestination = Environment.ExpandEnvironmentVariables(link.Path);

    if (string.Compare(
            msPaintPath, shortcutDestination, StringComparison.OrdinalIgnoreCase) == 0)
    {
        msPaintShortcutExists = true;
        break;
    }
}

if (msPaintShortcutExists)
{
    Controller.ExamController.AddExam(1, n, 7, time, Session.currentUserId);
}
else
{
    Controller.ExamController.AddExam(1, n, 0, time, Session.currentUserId);
}

需要在 STAThread 中运行

注意:如果InvalidCastException带有消息

无法将“System.__ComObject”类型的 COM 对象转换为接口类型“Shell32.Shell”。此操作失败,因为 IID 为“{286E6F1B-7113-4355-9562-96B7E9D64C54}”的接口的 COM 组件上的 QueryInterface 调用失败,原因是以下错误:不支持此类接口(HRESULT 异常:0x80004002 (E_NOINTERFACE)) .

发生在new Shell(); 您没有在 STAThread 中运行代码,但它需要在 STAThread 中运行。一个简单的解决方法是添加以下方法:

private static void ExecuteInStaThread(Action a)
{
    var thread = new Thread(() => a());
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    if (!thread.Join(TimeSpan.FromSeconds(30)))
    {
        thread.Abort();
    }
}

并将代码包装在对其的调用中:

ExecuteInStaThread(() =>
{
    string desktopDirectoryPath = ...
    ...
});

【讨论】:

  • 谢谢,但我在这一行有一个错误:“msPaintShortcutExists.Should().BeTrue();”错误是:“错误1'bool'不包含'Should'的定义,并且找不到接受'bool'类型的第一个参数的扩展方法'Should'(您是否缺少 using 指令或程序集引用? ) "
  • @Ali Ups 抱歉。该行仅用于“单元测试”目的。这就是我验证代码的方式。您可以安全地删除它(我也已将其从答案中删除)。
猜你喜欢
  • 2011-06-21
  • 2013-03-14
  • 1970-01-01
  • 1970-01-01
  • 2013-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多