vlc.exe.lnk双击这个文件,能正常打开vlc,但是用System.Diagnostics.Process.Start(Path.GetFullPath("vlc.exe.lnk"), url);没有任何反应。根据常理,不应该出现这个问题。但是现实就是这么魔幻,偏偏有这个问题。

根据上面图,根据快捷方式是可以获取到vlc可执行文件的路径的,然后在网上搜索到这段代码,如下:

// 引用→添加引用→左侧菜单的 COM 选项→勾上 Microsoft Shell Controls And Automation
using Shell32;
namespace FD.WinformUI
{
public class UICommon
{
// 传入快捷方式文件的路径,返回目标 exe 文件的路径
public string GetExePathFromShortcut(string shortcutFilePath)
{
FileInfo fileInfo = new FileInfo(shortcutFilePath);
string targetPath = "";
if (fileInfo.Extension.ToLower() == ".lnk") // 判断是否为快捷方式文件
{
Shell shell = new Shell();
Folder folder = shell.NameSpace(fileInfo.DirectoryName);
FolderItem folderItem = folder.ParseName(fileInfo.Name);
if (folderItem != null)
{
ShellLinkObject link = (ShellLinkObject)folderItem.GetLink;
targetPath = link.Target.Path; // 获取目标 exe 文件的路径
}
}
else if (fileInfo.Extension.ToLower() == ".url") // 判断是否为网址快捷方式
{
using (StreamReader reader = new StreamReader(shortcutFilePath))
{
string line;
while ((line = reader.ReadLine()) != null)
{
if (line.StartsWith("URL=", StringComparison.OrdinalIgnoreCase))
{
targetPath = line.Substring(4).Trim();
break;
}
}
}
}
return targetPath;
}
}
}

调用上面的函数UICommon.Instance.GetExePathFromShortcut(Path.GetFullPath("vlc.exe.lnk")),得到的路径是 "C:\Program Files (x86)\VideoLAN\VLC\vlc.exe" ,而这个路径根本不存在,这应该是c#画蛇添足了,要去掉" (x86)"。用System.Diagnostics.Process.Start(@"C:\Program Files (x86)\VideoLAN\VLC\vlc.exe", url);这样就能调用了,算是解决了这个问题。

后来我尝试用System.Diagnostics.Process.Start(UICommon.Instance.GetExePathFromShortcut(Path.GetFullPath("vlc.exe.lnk")), url);结果又傻眼了,发现调用了这个函数,vlc根本无法启动。后来打印日志,发现日志卡住了,这意思就是程序卡住了。后来干脆在项目的主函数里调用System.Diagnostics.Process.Start(UICommon.Instance.GetExePathFromShortcut(Path.GetFullPath("vlc.exe.lnk")), url);结果vlc能启动,并且能正常打开http的url。

在主函数里可以,在项目的其他代码里不行,这非常奇怪。后来发现项目的其他代码里新开启了线程,怀疑是线程的问题。因此我在主函数里开启线程,然后在线程里调用System.Diagnostics.Process.Start(UICommon.Instance.GetExePathFromShortcut(Path.GetFullPath("vlc.exe.lnk")), url);测试结果是vlc无法启动。

这充分证明了我的猜想,UICommon.Instance.GetExePathFromShortcut(Path.GetFullPath("vlc.exe.lnk")这个方法只能在主线程里运行,在其他线程里无法运行。我在chatgpt里问了下,chatgpt回复的如下:

1.该方法需要在主线程中执行。因为 Shell32 命名空间对应的 COM 组件在内部使用了单线程模型(Single-Threaded Apartment, STA),必须在 UI 线程中执行,否则会抛出异常。

2.如果你想在新线程中调用该方法,可以考虑将该方法封装到一个带有返回值的委托中,并使用 Control.Invoke() 或者 Control.BeginInvoke() 方法将其运行在 UI 线程中。

最终的解决方案,不用根据快捷方式获取程序路径,在调用System.Diagnostics.Process.Start(Path.GetFullPath("vlc.exe.lnk"), url)之前,先判断"C:\Program Files (x86)\VideoLAN\VLC\vlc.exe"和"C:\Program Files\VideoLAN\VLC\vlc.exe"是否存在。如果存在,就直接用已经存在的vlc路径;如果不存在,就用"vlc.exe.lnk"这个快捷方式。

c#中用System.Diagnostics.Process.Start(Path.GetFullPath(“vlc.exe.lnk“), url);用vlc的快捷方式打开http的url不起作用?的更多相关文章

  1. System.Diagnostics.Process.Start的妙用

    我们经常会遇到在Winform或是WPF中点击链接或按钮打开某个指定的网址, 或者是需要打开电脑中某个指定的硬盘分区及文件夹, 甚至是"控制面板"相关的东西, 那么如何做呢? 答案 ...

  2. System.Diagnostics.Process 启动进程资源或调用外部的命令的使用

    经常看到一些程序在保存为一个txt,或者excel的文件的时候,保存完毕立即打开, 启动程序或打开文件的代码 System.Diagnostics.Process.Start(System.IO.Pa ...

  3. WPF中System.Diagnostics.Process.Start的妙用

    我们经常会遇到在Winform或是WPF中点击链接或按钮打开某个指定的网址, 或者是需要打开电脑中某个指定的硬盘分区及文件夹, 甚至是"控制面板"相关的东西, 那么如何做呢? 答案 ...

  4. C# 之 System.Diagnostics.Process.Start的妙用

    经常会遇到在Winform或是WPF中点击链接或按钮打开某个指定的网址, 或者是需要打开电脑中某个指定的硬盘分区及文件夹, 甚至是"控制面板"相关的东西, 如何做呢? 方法:使用S ...

  5. C#——System.Diagnostics.Process.Start的妙用

    我们经常会遇到在Winform或是WPF中点击链接或按钮打开某个指定的网址, 或者是需要打开电脑中某个指定的硬盘分区及文件夹, 甚至是"控制面板"相关的东西, 那么如何做呢? 答案 ...

  6. System.Diagnostics.Process 执行.EXE

    分类:  C#+WINFORM 2009-04-05 21:09 459人阅读 评论(0)  收藏  举报  我们经常会遇到在Winform或是WPF中点击链接或按钮打开某个指定的网址, 或者是需要打 ...

  7. (转)C# System.Diagnostics.Process.Start使用

    经常会遇到在Winform或是WPF中点击链接或按钮打开某个指定的网址, 或者是需要打开电脑中某个指定的硬盘分区及文件夹, 甚至是"控制面板"相关的东西, 如何做呢?  方法:使用 ...

  8. 在Winform或WPF中System.Diagnostics.Process.Start的妙用

    原文:在Winform或WPF中System.Diagnostics.Process.Start的妙用 我们经常会遇到在Winform或是WPF中点击链接或按钮打开某个指定的网址, 或者是需要打开电脑 ...

  9. 在Scorpio 1.0(天蝎座)中使用C# System.Diagnostics.Process打开chrome遇到的问题

    1 //在天蝎座 中使用C# System.Diagnostics.Process打开chrome遇到的问题 2 DiagProcess = import_type("System.Diag ...

  10. System.Diagnostics.Process.Star的用法

    System.Diagnostics.Process.Start(); 能做什么呢?它主要有以下几个功能: 1.打开某个链接网址(弹窗). 2.定位打开某个文件目录. 3.打开系统特殊文件夹,如“控制 ...

随机推荐

  1. MySQL系列之读写分离架构——Atlas介绍、安装配置、Atlas功能测试、生产用户要求、Atlas基本管理、自动分表、关于读写分离建议

    文章目录 1. Atlas介绍 2.安装配置 3. Atlas功能测试 4. 生产用户要求 5. Atlas基本管理 6. 自动分表 7. 关于读写分离建议 1. Atlas介绍 Atlas是由 Qi ...

  2. How to Install Python on Linux

    Summary Hostmonster uses the preinstalled version of Python that ships with CentOS. Because of this ...

  3. struct 结构体【GO 基础】

    〇.前言 虽然 Go 语言中没有"类"的概念,也不支持"类"的继承等面向对象的概念,但是可以通过结构体的内嵌,再配合接口,来实现面向对象,甚至具有更高的扩展性和 ...

  4. Kubernetes:kube-apiserver 之 scheme(一)

    0. 前言 在进入 kube-apiserver 源码分析前,有一个非常重要的概念需要了解甚至熟悉的:资源注册表(scheme). Kubernetes 中一切皆资源,管理的是资源,创建.更新.删除的 ...

  5. Unity - Win平台修改窗口标题

    原文参考 主要是通过user32.dll获取窗口句柄, 和Unity没有什么关系 using System; using System.Diagnostics; using System.Runtim ...

  6. 在Finalshell中一直弹出弹窗要求输入密码的解决方案

    在finalshell中即使输入正确了密码,仍然要求输入(密码错误), 对CentOS的防火墙也已经关闭,但是仍然提示 这个原因是因为自创的用户名在finalshell中不被认可,需要将用户名更改为r ...

  7. 浅谈一下go语言中的slice及其一些小坑

    数组 数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成.虽然数组元素可以被修改,但是数组长度是固定的,而且在go语言中数组的长度也是数组类型的组成部分,所以不同长度或不同 ...

  8. Python 潮流周刊#26:requests3 的现状

    你好,我是猫哥.这里每周分享优质的 Python.AI 及通用技术内容,大部分为英文.本周刊开源,欢迎投稿.另有电报频道作为副刊,补充发布更加丰富的资讯. 品牌赞助 本周刊由"Python猫 ...

  9. LabVIEW基于机器视觉的实验室设备管理系统(3)

    目录 行动计划 创建用户信息数据库 后面板连线 初始化 确认修改 确认id 判断旧密码是否正确 判断两次输入的新密码是否相同 修改用户数据库中的密码 结尾 效果演示 上一期我们完成了欢迎登录和信息查询 ...

  10. 神经网络入门篇:详解核对矩阵的维数(Getting your matrix dimensions right)

    核对矩阵的维数 当实现深度神经网络的时候,其中一个常用的检查代码是否有错的方法就是拿出一张纸过一遍算法中矩阵的维数. \(w\)的维度是(下一层的维数,前一层的维数),即\({{w}^{[l]}}\) ...