c#中用System.Diagnostics.Process.Start(Path.GetFullPath(“vlc.exe.lnk“), url);用vlc的快捷方式打开http的url不起作用?
Posted 福大大架构师每日一题
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#中用System.Diagnostics.Process.Start(Path.GetFullPath(“vlc.exe.lnk“), url);用vlc的快捷方式打开http的url不起作用?相关的知识,希望对你有一定的参考价值。
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#中用PadLeftPadRight 补足位数
在 C# 中可以对字符串使用 PadLeft 和 PadRight 进行轻松地补位。
PadLeft(int totalWidth, char paddingChar) //在字符串左边用 paddingChar 补足 totalWidth 长度
PadRight(int totalWidth, char paddingChar) //在字符串右边用 paddingChar 补足 totalWidth 长度
示例:
h = h.PadLeft(2, ‘0‘);
注意第二个参数为 char 类型,所以用单引号,也可以用 Convert.ToChar(string value) 把字符串转换成 char 类型。如果字符串长度大于 1,则使用 str.ToCharArray()[index]。
以上是关于c#中用System.Diagnostics.Process.Start(Path.GetFullPath(“vlc.exe.lnk“), url);用vlc的快捷方式打开http的url不起作用?的主要内容,如果未能解决你的问题,请参考以下文章