如何从桌面应用程序打开 Windows 资源管理器和搜索?

How to open Windows explorer and search from a desktop application?

我正在使用 c#/.net 开发 windows 桌面应用程序,并希望添加一个功能来打开 windows 资源管理器并从该应用程序在计算机中搜索查询。

我打算使用Windows搜索协议来实现它。下面是我的代码片段。 rawQuery 从我的应用程序传递到 windows 资源管理器搜索框。

var query = "&query=" + HttpUtility.UrlEncode(rawQuery);
var location = string.Empty;
foreach (var drive in DriveInfo.GetDrives().Where(d => d.IsReady && d.DriveType.Equals(DriveType.Fixed)))
{
    location += "&crumb=location:" + HttpUtility.UrlEncode(drive.Name);
}
var searchQuery = "search:displayname=Search computer" + query + location;
Process.Start(searchQuery);

以上代码有问题。如果 rawQuery 包含非英文字符,则在编码 (HttpUtility.UrlEncode()) 后,它在 windows 资源管理器搜索框中显示不正确。例如,如果 rawQuery 是中文,如“微软”,它会在 windows 资源管理器中搜索 微软。不好了。

但是,如果未对 rawQuery 进行编码,则无法在 windows 资源管理器搜索框中显示 &、% 等特殊字符。

所以我不确定如何确定字符是否应该被编码。我没有在 search protocol spec.

中找到任何相关文档

有人知道应该对哪些字符进行编码吗?

似乎确实没有关于在搜索查询中究竟应该 url 编码什么的文档,但我们可以做出有根据的猜测。

首先,HttpUtility.UrlEncode如何对unicode字符进行编码?根据 RFC 3986 这样的字符应该首先表示为 UTF-8 字节,然后这些字节应该是百分比编码的。 HttpUtility.UrlEncode 正是这样做的。对于您的字符串:

var encoded = HttpUtility.UrlEncode(rawQuery); // = %e5%be%ae%e8%bd%af

2个字符用6个字节表示,每个字符3个字节。它被解码为 微软 - 6 个字符。所以很明显,搜索查询解码器不期望 UTF-8 字符编码。它期望哪种编码?您可以通过一些小实验找到它 - 它是 ISO-8859-1 编码。您可以使用此代码验证您的特定情况:

var rawQuery = "微软";
var encoded = HttpUtility.UrlEncode(rawQuery);
var iso = Encoding.GetEncoding("iso-8859-1");
var decoded = HttpUtility.UrlDecode(encoded, iso); // outputs "微软"

因此我们可以得出结论,对 ISO-8859-1 之外的任何内容进行编码是没有意义的,并且会产生无效的结果,因为这些字符无法在此编码中表示(它只是 8 位字符)。

该集合中应该编码什么?任何高于 ASCII 的字符(因此字符 128-256)都可以在不编码的情况下传递。这当然是违反 RFC 的,但我们已经知道无论如何搜索协议都不遵循它,因为它允许不编码的 UTF-8 字符。如果你想完全安全起见,你可以将 ¢(ISO-8859-1 中的 162)之类的字符编码为 %A2,它可以工作,但没有它也可以工作。

现在我们需要对 ASCII 字符进行编码,这些字符在 url 的不同部分保留用于特殊用途,或者根本不允许存在(未转义),或者被视为“使用未转义时可能会导致问题”。 RFC 说这样的字符是:

control     = <US-ASCII coded characters 00-1F and 7F hexadecimal>
space       = <US-ASCII coded character 20 hexadecimal>
delims      = "<" | ">" | "#" | "%" | <">
unwise      = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
reserved    = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","

现在,在这种特殊情况下,并非所有这些字符都需要编码,它们中的大多数都可以不编码,但如果您想安全起见,您还是可以对它们全部进行编码,或者计算这是通过反复试验得出的(像“&”、“%”、“/”这样的字符显然无论如何都必须编码)。