Проблема с разрешением папки .NET - PullRequest
1 голос
/ 29 января 2010

Я создаю программное обеспечение, которое пытается восстановить базу данных на сервере sql, но для этого мне нужен полный контроль над папкой, в которой будут храниться файлы .mdf и .ldf, я использую System.Security.AccessControl классы, чтобы дать полный контроль для всех, но это не работает! Я просто не знаю, почему это происходит ... Приложение выполняет правила нормально, но когда оно достигает части восстановления базы данных, оно выдает исключение, сообщающее мне: «Операционная система вернула ошибку (ошибка 5, доступ запрещен)». Мой код выглядит следующим образом:

public static void GiveDirFullPermissionEveryoneDotNet(String dir)
{
    GiveDirFullPermissionDotNet(dir, new String[] { @"TODOS", @"EVERYONE", @"BUILTIN/Users", @"Users", @"NT AUTHORITY\NETWORK SERVICE", @"NETWORK", @"Administrators", @"Administrator", @"Administradores", @"Administrador", @"SYSTEM" });
}

public static void GiveDirFullPermissionDotNet(String dir, String[] users)
{
    DirectorySecurity dirSec = Directory.GetAccessControl(dir);
    FileSystemAccessRule fsar;

    foreach (String userAtual in users)
    {
        try
        {
            fsar = new FileSystemAccessRule(userAtual
                                          , FileSystemRights.FullControl
                                          , InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit
                                          , PropagationFlags.InheritOnly
                                          , AccessControlType.Allow);
            dirSec.AddAccessRule(fsar);
        }
        catch (Exception)
        {
            continue;
        }
    }

    Directory.SetAccessControl(dir, dirSec);
}

Я пробовал это оболочкой, используя «CACLS.EXE», но некоторые версии Windows используют его «ICACLS.EXE» (спасибо большое мозгу в Microsoft за заботу о переносимости для нас, разработчиков!). Поэтому я действительно хочу сделать это .NET-способом, пожалуйста, помогите.

EDIT:

Я опубликую здесь мой метод RestoreDatabase, исключение выдается в "sqlRestore.SqlRestore (sqlServer);" линия

public void RestoreDatabase(string databaseName,
                            string filePath,
                            string serverName,
                            string userName,
                            string password,
                            string dataFilePath,
                            string logFilePath)
{
    //! Classe de restauração do SQL server
    Restore sqlRestore = new Restore();

    //! adicionando o arquivo indicado ao Restore
    BackupDeviceItem deviceItem = new BackupDeviceItem(filePath, DeviceType.File);
    sqlRestore.Devices.Add(deviceItem);
    sqlRestore.Database = databaseName;

    ServerConnection connection;

    //! Se passou string vazia no usuário, tenta Windows Authentication
    if (userName == "")
    {
        SqlConnection sqlCon = new SqlConnection(@"Data Source=" + serverName + @"; Integrated Security=True;");
        connection = new ServerConnection(sqlCon);
    }
    //! Se passou login de usuário, tenta Server Autentication
    else
        connection = new ServerConnection(serverName, userName, password);


    Server sqlServer = new Server(connection);

    Database db = sqlServer.Databases[databaseName];
    sqlRestore.Action = RestoreActionType.Database;
    string dataFileLocation = dataFilePath + databaseName + ".mdf";
    string logFileLocation = logFilePath + databaseName + "_Log.ldf";
    db = sqlServer.Databases[databaseName];
    RelocateFile rf = new RelocateFile(databaseName, dataFileLocation);

    sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName, dataFileLocation));
    sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName + "_log", logFileLocation));
    sqlRestore.ReplaceDatabase = true;
    sqlRestore.Complete += new ServerMessageEventHandler(sqlRestoreComplete);
    sqlRestore.PercentCompleteNotification = 10;
    sqlRestore.PercentComplete += new PercentCompleteEventHandler(sqlRestorePercentComplete);

    sqlRestore.SqlRestore(sqlServer);

    db = sqlServer.Databases[databaseName];

    db.SetOnline();

    sqlServer.Refresh();
}

Ответы [ 3 ]

1 голос
/ 02 февраля 2010

Я только что нашел ответ сам ...

в моем методе «RestoreDatabase», когда я устанавливаю экземпляры «RelocateFile» внутри класса «Restore», я говорю, чтобы сервер sql переместил файлы .mdf и .ldf в новую указанную мной папку, до сих пор звучит нормально, так как я даю полные права всем в папке, которая будет получать файлы.

НО именно здесь и начинается проблема: SQL Server создает файлы .mdf и .ldf в своей папке данных по умолчанию, назначая своего собственного пользователя (этот пользователь имеет полный контроль над папкой данных SQL по умолчанию), НО (снова), когда он перемещает файлы после завершения восстановления, он использует другого пользователя, и этот пользователь должен иметь разрешения для папки данных SQL по умолчанию. Что произойдет, если у этого пользователя нет необходимых разрешений? Ответ таков: «Что со мной происходит:« Операционная система вернула ошибку (ошибка 5, доступ запрещен) »».

Чтобы решить эту проблему, я подключаюсь к серверу SQL, запрашиваю расположение папки данных SQL по умолчанию и устанавливаю полный контроль над ней. После этого все идет хорошо =]

Желаю помочь кому-то с такой же проблемой! Спасибо всем, кто пытался помочь!

1 голос
/ 30 января 2010

Мои деньги на том, что это не проблема .Net, а проблема с SQL Server ...

Вот мое предположение (из здесь )

С http://www.fmsinc.com/freE/NewTips/SQL/SQLtip9.asp

В то время как только локальные устройства отображаются в Резервное копирование / восстановление Enterprise Manager диалоги, есть способ создать или восстановить резервную копию базы данных SQL Server на сетевом ресурсе. Создание или восстановление резервной копии базы данных на общий сетевой файл требует следующие предпосылки:

1) Службы SQL Server на Сервер, содержащий экземпляр SQL Сервер должен быть запущен под учетная запись на уровне домена (например, домен Администратор аккаунта). Это достигается путем изменения «Вход в систему» свойства для названных услуг "MSSQLSERVER" и "SQLSERVERAGENT" в сервер под управлением SQL Server (не ваш местный экземпляр). Когда у тебя есть завершено изменение входа в систему информация для этих 2 услуг, вы нужно будет перезапустить "MSSQLSERVER" сервис на этом сервере. Обратите внимание, что это спросит, хотите ли вы перезапустить «SQLSERVERAGENT» также - Ответ: Да.

2) Учетная запись службы SQL Server должна иметь права ПОЛНОГО КОНТРОЛЯ на файл системная папка и на общий ресурс. Тот означает, что вам нужно иметь общий доступ место, в котором учетная запись Вы указали в 1 (выше) имеет полный контроль прав.

3) Общая папка должна быть только доступ через имя UNC. Сопоставленные диски может быть не всегда видимым для Служба SQL.

4) Вы не можете указать путь по используя эллипсы просмотра (...). Вы необходимо ввести полный путь

0 голосов
/ 30 января 2010

Я протестировал ваш код "RestoreDatabase" без каких-либо изменений разрешений на моем компьютере, и он работает для меня. Visual Studio 2008 SP1, SQL 2008 Express SP1, Windows 7 x64.

Надеюсь, это поможет вам.

...