Подтвердить что ты не робот

Море Исключения, связанные с открытием FileStream

Хорошо, поэтому я искал во многих местах ответ на этот вопрос, но я открыт для любых ссылок, если я пропустил что-то очевидное.

Мне интересно создавать разумные сообщения об ошибках пользователю, когда они пытаются открыть конкретный файл, но по какой-то причине программа не может получить доступ к этому файлу. Я хотел бы различать следующие случаи:

  • Файл был заблокирован другим процессом, так что этот процесс не мог его записать.
  • Пользователь не имеет соответствующих прав доступа для записи в файл (как и в их разрешениях пользователей, как показано на экране "Свойства" для файла в проводнике Windows, не дает пользователю права на запись)
  • Для доступа к файлу для файла требуется "повышенное" разрешение.

Я использую объект FileStream. Я просмотрел документацию msdn для создания экземпляра FileStream, и мне совершенно не ясно, что Exception делает то, что для вышесказанного, и как чтобы различать их. Я признаю, что мой опыт программирования на Windows ограничен, поэтому мне может быть недостает чего-то очевидного. Приносим извинения, если так.

4b9b3361

Ответ 1

Вот что вы могли бы сделать:

1) Вы можете проверить, имеете ли вы права доступа к файлу до, пытающегося получить доступ к вашему файлу. Из этого SO-потока, это метод, который должен возвращать true, если пользователь имеет права Write (т.е. При щелчке правой кнопкой мыши по файлу → свойство → безопасность), Это покрывает вашу точку (2) за привилегированные привилегии доступа (обратите внимание, что для получения этой информации может быть что-то более надежное/безошибочное):

public static bool HasWritePermissionOnFile(string path)
{
    bool writeAllow = false;
    bool writeDeny = false;

    FileSecurity accessControlList = File.GetAccessControl(path);
    if (accessControlList == null)
    {
        return false;
    }

    var accessRules = accessControlList.GetAccessRules(true, true, typeof(SecurityIdentifier));
    if (accessRules == null)
    {
        return false;
    }

    foreach (FileSystemAccessRule rule in accessRules)
    {
        if ((FileSystemRights.Write & rule.FileSystemRights) != FileSystemRights.Write)
        {
            continue;
        }

        if (rule.AccessControlType == AccessControlType.Allow)
        {
            writeAllow = true;
        }
        else if (rule.AccessControlType == AccessControlType.Deny)
        {
            writeDeny = true;
        }
    }

    return writeAllow && !writeDeny;
}

2) Попробуйте создать экземпляр FileStream и исключить исключения:

try
{
    string file = "...";
    bool hasWritePermission = HasWritePermissionOnFile(file);
    using (FileStream fs = new FileStream(file, FileMode.Open))
    {
    }
}
catch (UnauthorizedAccessException ex)
{
    // Insert some logic here
}
catch (FileNotFoundException ex)
{
    // Insert some logic here
}
catch (IOException ex)
{
    // Insert some logic here
}

В вашем случае (3) (файл требует повышения), UnauthorizedAccessException выбрано.

В вашем случае (1) (файл заблокирован другим процессом), бросается IOException. Затем вы можете проверить HRESULT для исключения:

catch (IOException ex)
{
    // Gets the HRESULT
    int hresult = Marshal.GetHRForException(ex);

    // See http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx
    // for system error code
    switch (hresult & 0x0000FFFF)
    {
        case 32:    //ERROR_SHARING_VIOLATION
            Console.WriteLine("File is in use by another process");
            break;
    }
}

Теперь вы сможете отличить свои 3 варианта использования.