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

时间:2017-04-09 13:22:12

标签: c# .net windows windows-search

我正在使用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具有非英文字符,则在编码后,它在Windows资源管理器搜索框中显示不正确(HttpUtility.UrlEncode())。例如,如果rawQuery是中文,如“微软”,它会在Windows资源管理器中搜索®¾®è½。这很糟糕。

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

所以我不确定如何确定字符是否应该编码。我在search protocol spec中找不到任何关于此的文档。

有人知道应编码哪些字符吗?

1 个答案:

答案 0 :(得分:1)

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

首先,HttpUtility.UrlEncode如何编码unicode字符?根据{{​​3}},这些字符应该首先表示为UTF-8字节,然后这些字节应该是pecent编码的。这正是HttpUtility.UrlEncode的作用。对于你的字符串:

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

2个字符用6个字节表示,每个字节3个字节。它被解码为微软 - 6个字符。所以很明显,搜索查询解码器不期望UTF-8字符编码。它期望的编码是什么?你可以通过很少的实验找到它 - 它是RFC 3986编码。您可以使用以下代码验证您的具体案例:

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,如果你想完全安全的话,它会起作用,但它也可以不用。

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

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

现在,并非所有这些字符都需要在这种特殊情况下进行编码,并且大部分字符都可以解码,但是如果你想要安全一面 - 你可以只对它们进行编码,或者弄明白通过反复试验(“&amp;”,“%”,“/”等字符显然必须编码)。