gpt4 book ai didi

c# - 为 ProgId 动词运行命令

转载 作者:可可西里 更新时间:2023-11-01 10:00:29 25 4
gpt4 key购买 nike

有没有一种方法可以执行 progid 动词的命令,而无需深入研究注册表并进行字符串操作?

我可以使用 ShObjIdl.idl 运行以下命令来获取默认浏览器的 ProgId:

var reg = new ShellObjects.ApplicationAssociationRegistration();

string progID;
reg.QueryCurrentDefault("http", ShellObjects.ASSOCIATIONTYPE.AT_URLPROTOCOL, ShellObjects.ASSOCIATIONLEVEL.AL_EFFECTIVE, out progID);

这给了我“ChromeHTML.FHXQEQDDJYXVQSFWM2SVMV5GNA”。在注册表中,我可以看到此 progid 具有以下 shell/open/command:

"C:\Users\Paul\AppData\Local\Google\Chrome\Application\chrome.exe" -- "%1"

是否有一个 API 可以将 ProgId 连同动词和参数传递给它并运行它?

我采用的一种方法是使用 ShellExecuteEx:

var shellExecuteInfo = new SHELLEXECUTEINFO();
shellExecuteInfo.cbSize = Marshal.SizeOf(shellExecuteInfo);
shellExecuteInfo.fMask = SEE_MASK_CLASSNAME;
shellExecuteInfo.hwnd = IntPtr.Zero;
shellExecuteInfo.lpVerb = "open";
shellExecuteInfo.lpFile = "google.com";
shellExecuteInfo.nShow = SW_SHOWNORMAL;
shellExecuteInfo.lpClass = "http";

ShellExecuteEx(ref shellExecuteInfo);

但是由于 Window 正在检查 lpFile 而失败并出现“Windows 找不到”错误,我不希望发生这种情况,因为它与 URL 无关(来自:http://blogs.msdn.com/b/oldnewthing/archive/2010/07/01/10033224.aspx)


这是我想出的解决方案:

    private static void Main(string[] args)
{
if (!OpenUrlInDefaultBrowser("google.com"))
Console.WriteLine("An error happened");
}

[DllImport("Shlwapi.dll")]
private static extern int AssocQueryString(ASSOCF flags, ASSOCSTR str, string pszAssoc, string pszExtra, StringBuilder pszOut, ref uint pcchOut);

private enum ASSOCF
{
ASSOCF_NONE = 0x00000000
}

private enum ASSOCSTR
{
ASSOCSTR_COMMAND = 1
}

[DllImport("Shell32.dll", CharSet=CharSet.Auto)]
private static extern int SHEvaluateSystemCommandTemplate(string pszCmdTemplate, out string ppszApplication, out string ppszCommandLine, out string ppszParameters);

private static bool OpenUrlInDefaultBrowser(string url)
{
string browserProgId;
if (!GetDefaultBrowserProgId(out browserProgId))
return false;

string browserCommandTemplate;
if (!GetCommandTemplate(browserProgId, out browserCommandTemplate))
return false;

string browserExecutable;
string parameters;
if (!EvaluateCommandTemplate(browserCommandTemplate, out browserExecutable, out parameters))
return false;

parameters = ReplaceSubstitutionParameters(parameters, url);

try
{
Process.Start(browserExecutable, parameters);
}
catch (InvalidOperationException) { return false; }
catch (Win32Exception) { return false; }
catch (FileNotFoundException) { return false; }

return true;
}

private static bool GetDefaultBrowserProgId(out string defaultBrowserProgId)
{
try
{
// midl "C:\Program Files (x86)\Windows Kits\8.0\Include\um\ShObjIdl.idl"
// tlbimp ShObjIdl.tlb
var applicationAssociationRegistration = new ApplicationAssociationRegistration();
applicationAssociationRegistration.QueryCurrentDefault("http", ShellObjects.ASSOCIATIONTYPE.AT_URLPROTOCOL, ShellObjects.ASSOCIATIONLEVEL.AL_EFFECTIVE, out defaultBrowserProgId);
}
catch (COMException)
{
defaultBrowserProgId = null;
return false;
}
return !string.IsNullOrEmpty(defaultBrowserProgId);
}

private static bool GetCommandTemplate(string defaultBrowserProgId, out string commandTemplate)
{
var commandTemplateBufferSize = 0U;
AssocQueryString(ASSOCF.ASSOCF_NONE, ASSOCSTR.ASSOCSTR_COMMAND, defaultBrowserProgId, "open", null, ref commandTemplateBufferSize);
var commandTemplateStringBuilder = new StringBuilder((int)commandTemplateBufferSize);
var hresult = AssocQueryString(ASSOCF.ASSOCF_NONE, ASSOCSTR.ASSOCSTR_COMMAND, defaultBrowserProgId, "open", commandTemplateStringBuilder, ref commandTemplateBufferSize);
commandTemplate = commandTemplateStringBuilder.ToString();

return hresult == 0 && !string.IsNullOrEmpty(commandTemplate);
}

private static bool EvaluateCommandTemplate(string commandTemplate, out string application, out string parameters)
{
string commandLine;
var hresult = SHEvaluateSystemCommandTemplate(commandTemplate, out application, out commandLine, out parameters);

return hresult == 0 && !string.IsNullOrEmpty(application) && !string.IsNullOrEmpty(parameters);
}

private static string ReplaceSubstitutionParameters(string parameters, string replacement)
{
// Not perfect but good enough for this purpose
return parameters.Replace("%L", replacement)
.Replace("%l", replacement)
.Replace("%1", replacement);
}

最佳答案

显式类不会删除 lpFile 引用有效资源(文件或 URL)的要求。该类指定资源应如何执行(而不是从文件类型或 URL 协议(protocol)推断类),但您仍然必须传递有效的资源。 google.com 被视为文件名,因为它不是 URL,并且该文件不存在,因此您会收到“未找到”错误。

您尝试执行的一般情况比仅提取命令行更复杂,因为大多数浏览器使用 DDE 而不是命令行作为其主要调用。 (命令行是 DDE 失败时的回退。)

但如果真的要执行命令行,可以使用AssocQueryString获取ASSOCSTR_COMMAND,然后通过SHEvaluateSystemCommandTemplate执行插入> 让命令行执行。

关于c# - 为 ProgId 动词运行命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12131100/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com