Directory.GetFiles()在具有本地化名称

时间:2018-03-24 01:15:54

标签: c# windows file localization

我试图在zh-CN Windows 10 PC上迭代开始菜单项,但是失败就像标题所说的那样。

有问题的代码:

public static readonly string[] ItemSearchPath = new[]
{
    Environment.GetFolderPath(Environment.SpecialFolder.CommonStartMenu),
    Environment.GetFolderPath(Environment.SpecialFolder.StartMenu)
};

public static readonly string[] ItemSearchPattern = new[] {@"*.lnk", @"*.url"};

// ...

foreach (var item in ItemSearchPath.SelectMany(x => ItemSearchPattern.SelectMany(y =>
    Directory.GetFiles(x, y, SearchOption.AllDirectories))) /* <- here */ { ... }

堆栈跟踪:

System.UnauthorizedAccessException : Access to the path 'C:\ProgramData\Microsoft\Windows\Start Menu\程序' is denied.

起初我认为这是由于文件权限,因此我提升了Visual Studio并强制程序在app.manifest中使用管理员权限,但仍然抛出异常。很快我意识到路径实际指向C:\ProgramData\Microsoft\Windows\Start Menu\Programs

“运行”对话框也拒绝本地化路径,因此它是打开目录级别的预期行为。但是从Google告诉我的本地化名称只不过是desktop.ini中的一个关键字,所以在标准方法中获取它而不是“真实”的名称是奇怪的。我只是用错了方法吗?

1 个答案:

答案 0 :(得分:0)

在解析系统路径时,总是有机会面对拒绝尝试访问没有所需访问权限的目录/文件的拒绝。

但是,您可以在尝试对该目录/文件进行任何操作之前,检查是否已授予当前用户这些权限。

我在这里使用WindowsIdentity.GetCurrent()检索用户ACL身份,然后使用Directory.GetAccessControl()验证用户权限是否符合至少需要访问的AuthorizationRule路径。

我添加了一个执行测试的方法UserHasDirectoryAccesRight(string DirPath) { }

  

请注意,这是一种通用方法,必须将其调整为特定方法   文化。我已经添加了一个字符串转换   CultureInfo.CurrentCulture,在目录路径上尝试适应。   根据需要修改此设置。

using System.Security;
using System.Security.Principal;
using System.Security.AccessControl;

string[] ItemSearchPath = new[] {
    Environment.GetFolderPath(Environment.SpecialFolder.CommonStartMenu),
    Environment.GetFolderPath(Environment.SpecialFolder.StartMenu)
};

string[] itemSearchPattern = new[] { @"*.lnk", @"*.url" };

List<string> linksList = itemSearchPath.SelectMany(sPath =>
                         itemSearchPattern.SelectMany(sPatt =>
                         {
                             return UserHasDirectoryAccesRight(sPath)
                                    ? Directory.GetFiles(
                                                sPath.ToString(CultureInfo.CurrentCulture),
                                                sPatt.ToString(CultureInfo.CurrentCulture),
                                                            SearchOption.AllDirectories)
                                    : new string[] { "" };
                         })).ToList();

private bool UserHasDirectoryAccesRight(string DirPath)
{
    WindowsIdentity identity = WindowsIdentity.GetCurrent(false);
    AuthorizationRuleCollection dSecurity =
            Directory.GetAccessControl(DirPath, AccessControlSections.Access)
                     .GetAccessRules(true, true, typeof(SecurityIdentifier));

    bool hasRight =  dSecurity.Cast<AuthorizationRule>()
                              .Any(x => x.IdentityReference.Value.Equals(identity.Owner.Value));
    return hasRight;
}
相关问题