2009-04-08 27 views
7

Estoy intentando escribir una aplicación simple en C# que me permitirá realizar copias de seguridad, comprimir y enviar a través de ftp mi base de datos SQL Server. Un problema que he encontrado es que no puedo crear el archivo de copia de seguridad (.bak) si intento hacerlo en una ubicación diferente de "C: \ Archivos de programa \ Microsoft SQL Server \ MSSQL.3 \ MSSQL \ Backup "o carpeta" C: \ Archivos de programa \ Microsoft SQL Server \ MSSQL.3 \ MSSQL \ Data ". Entiendo que este es un problema de premisión. ¿Podría alguien señalarme los recursos o escribir aquí un pequeño fragmento de cómo agregar programáticamente dicho permiso a cualquier carpeta en mi sistema?Crear archivo de copia de seguridad de SQL Server (.bak) con C# en cualquier ubicación

Saludos Kris

Respuesta

1

Tome un vistazo a this article.

Recuerde establecer los permisos para la cuenta con la que se está ejecutando la instancia de SQL Server.

0

Aunque puede que esto no responda a su pregunta inmediata, le aconsejaría que consulte los Servicios de Integración de SQL Server (SSIS). Esto parece exactamente para lo que se creó SSIS, y en la versión 2008 existe la posibilidad de usar el código C# si es necesario, si los componentes estándar no hacen lo que necesita (las versiones anteriores usaban VB.NET).

MSDN SSIS Info Link 1
SSIS 2005 Tutorial Link 2

Tome una mirada en ella.

8

supongo que está ejecutando su programa como una tarea programada ... ¿le dio permisos de escritura a la carpeta de destino para el usuario que ejecuta la tarea?

edición:
con permisos puede tener 2 escenarios:

  • ventanas authenification
  • autentificación mixta

si está utilizando ventanas de autentificación, los de lectura y escritura permisos de el usuario de Windows está ocupado. de lo contrario, los permisos para la cuenta de servicio del servidor sql.

y este comportamiento tiene sentido para mí y tal vez da en el clavo en su situación!

editar 2:
no quiero animarle a hacerlo ... algunos administradores pueden odiarte cuando te sales de su acl pero this puede hacer el truco

por cierto: Magnus Johansson already gave que un "probar este" enlace

no importa para qué método que vaya - (! como descriped arriba) asegúrese de entregar al usuario correcto

(fo r historial completo)
...

nota lateral:
Sé que esto no es la respuesta exacta a su pregunta, pero yo le recomendaría SMO para generar copias de seguridad ...

como

using Microsoft.SqlServer.Management.Smo; 

var bdi = new BackupDeviceItem(/* your path inlcuding desired file */); 
var backup = new Backup 
{ 
    Database = /* name of the database */, 
    Initialize = true 
}; 

backup.Devices.Add(bdi); 

var server = new Server(this.SqlServer); 

try 
{ 
    backup.SqlBackup(server); 
} 
catch (Exception ex) 
{ 
    // * log or sth 
} 

sólo tiene que cuidar de los años .dll. tomar montajes para la versión servidor deseado (algunos parametros/propiedades varían a través de diferentes versiones de servidor)
mas info here

5

Ok chicos, Magnus y dittodhole! Muchas gracias por tu ayuda. He combinado el enlace de Magnus para el artículo sobre la configuración de permisos en la carpeta junto con algunas investigaciones más y finalmente lo tengo :). Así que reasumiendo, estoy usando Smo, y para crear una carpeta con los permisos adecuados, tengo que buscar el grupo en lugar de win32_Users. Aquí tienes un fragmento corto si alguien encuentra este post que puede resultar muy útil:

string tempPath = Directory.CreateDirectory("C:\\path_to_your_folder").FullName; 

//set permissions 
SelectQuery sQuery = new SelectQuery("Win32_Group", 
            "Domain='" + 
            System.Environment.UserDomainName.ToString() + 
            "'"); 
try 
{ 
    DirectoryInfo myDirectoryInfo = new DirectoryInfo("C:\\path_to_your_folder"); 
    DirectorySecurity myDirectorySecurity = myDirectoryInfo.GetAccessControl(); 
    ManagementObjectSearcher mSearcher = new ManagementObjectSearcher(sQuery); 
    foreach (ManagementObject mObject in mSearcher.Get()) 
    { 
     string User = System.Environment.UserDomainName + "\\" + mObject["Name"]; 
     if(User.StartsWith("your-machine-name\\SQL")) 
     { 
      myDirectorySecurity. 
      AddAccessRule(new FileSystemAccessRule(User, 
                FileSystemRights.FullControl, 
                AccessControlType.Allow)); 
     } 
    } 
    myDirectoryInfo.SetAccessControl(myDirectorySecurity); 
} 
catch (Exception ex) 
{ 
    Console.WriteLine(ex.StackTrace); 
} 

Una vez más, gracias a todos por su ayuda! Rocas Stackoverflow!

0

Aquí es un procedimiento es el uso de una copia de seguridad en C# Esperanza que ayuda a

public void BackupDatabase (string BackUpLocation, string BackUpFileName, string 
    DatabaseName, string ServerName) 
    { 

     DatabaseName = "[" + DatabaseName + "]"; 

     string fileUNQ = DateTime.Now.Day.ToString() + "_" + DateTime.Now.Month.ToString() + "_" + DateTime.Now.Year.ToString() +"_"+ DateTime.Now.Hour.ToString()+ DateTime.Now .Minute .ToString() + "_" + DateTime .Now .Second .ToString() ; 

     BackUpFileName = BackUpFileName + fileUNQ + ".bak"; 
     string SQLBackUp = @"BACKUP DATABASE " + DatabaseName + " TO DISK = N'" + BackUpLocation + @"\" + BackUpFileName + @"'"; 

     string svr = "Server=" + ServerName + ";Database=master;Integrated Security=True"; 

     SqlConnection cnBk = new SqlConnection(svr); 
     SqlCommand cmdBkUp = new SqlCommand(SQLBackUp, cnBk); 

     try 
     { 
      cnBk.Open(); 
      cmdBkUp.ExecuteNonQuery(); 
      Label1.Text = "Done"; 
      Label2.Text = SQLBackUp + " ######## Server name " + ServerName + " Database " + DatabaseName + " successfully backed up to " + BackUpLocation + @"\" + BackUpFileName + "\n Back Up Date : " + DateTime.Now.ToString(); 
     } 

     catch (Exception ex) 
     { 
      Label1.Text = ex.ToString(); 
      Label2.Text = SQLBackUp + " ######## Server name " + ServerName + " Database " + DatabaseName + " successfully backed up to " + BackUpLocation + @"\" + BackUpFileName + "\n Back Up Date : " + DateTime.Now.ToString(); 
     } 

     finally 
     { 
      if (cnBk.State == ConnectionState.Open) 
      { 

       cnBk .Close(); 
      } 
     } 
    } 
Cuestiones relacionadas