Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Ejecutar .bat de un backup mysql desde c++ builder 6 ó XE (https://www.clubdelphi.com/foros/showthread.php?t=78376)

dmartinezn 13-04-2012 17:47:26

Ejecutar .bat de un backup mysql desde c++ builder 6 ó XE
 
Saludos a todos
Estoy tratando de hacer un backup de una BD mysql, para ello cree un .bat con el siguiente código:
Código:

set FECHA=%date%
set FECHA=%FECHA:/=%
set FECHA=%FECHA: =%
set FECHA=%FECHA::=%
set FECHA=%FECHA:,=%
mysqldump.exe --opt --password=damian --user=damian test> D:\backups\Backup_%FECHA%.sql

Cuando le doy doble clic al .bat (Backup.bat) me genera el backup perfectamente por fechas como lo quiero (Backup_13042012.sql). Ahora lo que quiero lograr es ejecutar ese .bat (Backup.bat) desde c++, pero con el código que lo hago me genera el .sql (Backup_13042012.sql) vacío, no se si será problema del código que utilizo o que desde c++ no podría ejecutar el mysqldump.exe que se encuentra dentro del Backup.bat. Acá les dejo las 2 formas como he tratado de hacerlo y en ambas me genera el .sql vacío.
Saludos y espero que puedan corregirme que estoy haciendo mal.
Código:

String Destino= ExtractFilePath(Application->ExeName)+"web server\\mysql\\bin\\Backup.bat";
  SHELLEXECUTEINFO lpExecInfo;
  memset(&lpExecInfo, 0, sizeof(SHELLEXECUTEINFO));
  lpExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
  lpExecInfo.lpFile = Destino.c_str();
  lpExecInfo.lpParameters = 0;
  lpExecInfo.lpDirectory = 0;
  lpExecInfo.lpVerb = 0;
  lpExecInfo.nShow = SW_NORMAL;
  lpExecInfo.fMask = 0;
  ShellExecuteEx(&lpExecInfo);
  String Dia = Date();
  ShowMessage("La salva de la BD fue creada satisfactoriamente con la Fecha " + Dia);

Código:

ShellExecuteA(NULL,"open","D:\\Damian\\web server\\mysql\\bin\\Backup.bat",NULL,"",SW_SHOWNORMAL);
Tambien he probado utilizando ShellExecute en ves de ShellExecuteA

olbeup 13-04-2012 19:24:14

He probado esto y funciona correctamente

Fichero notepd.bat
Código:

@echo off
cls
set fichero="%1%date%"
set fichero=%fichero:/=%
notepad.exe %fichero%
exit

Código Delphi [-]
ShellExecute(Handle, 'Open', 'C:\Windows\notepad.exe', nil, nil, SW_SHOWDEFAULT);
ShellExecute(Handle, 'Open', 'C:\notepd.bat', nil, nil, SW_SHOWDEFAULT);
ShellExecute(Handle, 'Open', 'C:\notepd.bat', 'Prueba.txt', 'C:\', SW_SHOWDEFAULT);

Un saludo

dmartinezn 13-04-2012 19:34:32

Gracias por responder, en el caso del notepad funciona perfectamente, pero el problema está en lo que le plantee anteriormente cuando se trata del mysqldump.exe dentro del .bat

olbeup 13-04-2012 19:51:46

Es posible que sea la ruta
Código Delphi [-]
ShellExecute(Handle,'Open','D:\\Damian\\web server\\mysql\\bin\\Backup.bat',nil,'D:\\Damian\\web server\\mysql\\bin',SW_SHOWDEFAULT);

Un saludo

roman 13-04-2012 19:54:48

Yo creo que el problema es que ShellExecute no maneja la redirección de la salidad de un comando. Tendrías que usar CreateProcess especificando una tubería (pipe) de sailida para capturar el volcado de mysqldump.

Sin embargo, creo que puedes optar por algo mucho más sencillo, que es especificar el archivo de salida como parámetro de mysqldump usando la opción -r:

Código:

mysqldump --password=damian --user=damian test -r D:\backups\Backup_%FECHA%.sql
// Saludos

dmartinezn 13-04-2012 20:47:06

Saludos
Esa opción que usted me da como podría utilizarla desde el c++ ?,la probé y funciona pero el problema está en como llamo ahora a ese .bat para que me haga lo que quiero.

roman 13-04-2012 21:04:07

Pues igual a como lo tienes ahora. Es decir, en el bat, en la línea del mysqladmin pones el cambio que te menciono.

Ahora bien, en realidad yo creo que puedes olvidarte del BAT. Calcula la fecha desde tu aplicación y manda llamr directamente a mysqladmin con ShellExecute.

Por cierto, no entiendo qué es lo que hace tu BAT con la fecha.

// Saludos

dmartinezn 13-04-2012 21:25:10

Le hice la modificación que me recomendó y sigue el mismo problema.
Ahora si me olvido del .bat y mando a ejecutar directamente el mysqldump, como le digo que BD, usuario y contraseña debe coger desde el c++?.
Lo que hace el bat con la fecha es generarme por días las salvas, ejemplo día de hoy: Backup_13042012.sql

roman 13-04-2012 22:03:39

Te pongo un ejemplo en delphi. No debe ser mayor problema traducirlo a C++.

Código Delphi [-]
procedure Backup(User, Password, Database, OutputDir: String);
var
  OutputFile: String;

begin
  OutputFile :=
  IncludeTrailingPathDelimiter(OutputDir) +
  Database + '_' + FormatDateTime('ddmmyy', Now) + '.sql';

  ShellExecute(
    0, 'open',
    'C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqldump.exe',
    PChar(Format('-u%s -p%s %s -r %s', [User, Password, Database, OutputFile])),
    nil, SW_HIDE);
end;

Usas esta función pasando el usuario, contraseña, base de datos a respaldar y directorio donde colocar el respaldo. El archivo generado tendrá por nombre la base de datos seguida de la fecha, por ejemplo: test_130412.sql.

Desde luego, tienes que ajustar la ruta a mysqldump.exe tal como lo tengas en tu sistema.

// Saludos

dmartinezn 13-04-2012 23:08:02

Bueno no se nada de delphi pero +- por lo que entendi lo hice asi y me sale algunos errores que le mostrare.

Código:

void  Backup(String User,String Password,String Database,String OutputDir)
{
  String OutputFile;
  AnsiString  as  =  FormatDateTime( "yyyymmmdd  hh:mm:ss ",Now());
  OutputFile =  IncludeTrailingPathDelimiter(OutputDir) +  Database + '_' + as + '.sql';
  ShellExecute(NULL,"open","D:\Damian\web server\mysql\bin\mysqldump.exe",PChar(Format('-u%s -p%s %s -r %s', [User, Password, Database, OutputFile])),NULL, SW_HIDE);
 }

esta seria la forma como lo llamaria

Código:

Backup("damian","damian","test","D:\backups");
Y estos son los errores que me salen,todos en la linea del ShellExecute:

Código:

[BCC32 Error] Unit1.cpp(187): E2129 Character constant too long (or empty)
  [BCC32 Error] Unit1.cpp(187): E2188 Expression syntax
  [BCC32 Error] Unit1.cpp(187): E2293 ) expected
  [BCC32 Error] Unit1.cpp(187): E2121 Function call missing )


ecfisa 14-04-2012 00:14:25

Hola dmartinezn.

No utilizo mysql por lo que no puedo probar si los parámetros son correctos. Según entiendo de tu primer mensaje, estos no son enviados por la aplicación sino que se determinan dentro del archivo backup.bat.

Yo llamaría a Backup.bat con ShellExecute de este modo:
Código:

{
char cmd[1024];
  GetEnvironmentVariable("COMSPEC", cmd, sizeof(cmd));
  ShellExecute(Handle,
              "open",
              cmd,
              " /K D:\\Damian\\web server\\mysql\\bin\\Backup.bat",
              NULL,
              SW_HIDE);
}

(Linea de comando: /K: ejecuta y permanece, /C ejecuta y retorna inmediatamente)

Saludos.

ecfisa 14-04-2012 03:15:47

Hola dmartinezn.

Como te dije antes no uso mysql, pero el código de roman, que sin dudas debe funcionar correctamente, creo que deberías traducirlo más o menos así:
Código:

void Backup(char *User, char *Password, char *Database, char *OutputDir)
{
AnsiString OutputFile = IncludeTrailingPathDelimiter(OutputDir) +
  Database + '_' + FormatDateTime("ddmmyy", Now()) + ".sql";
TVarRec vr[] = {User,Password,Database,OutputFile};
  ShellExecute(0,
              "open",
              "C:\\Program Files\\MySQL\\MySQL Server 5.1\\bin\\mysqldump.exe",
              Format("-u%s -p%s -r %s %s",vr,4).c_str(),
              NULL,
              SW_HIDE);
}


Saludos.

roman 14-04-2012 03:56:37

¡Ah! ¡Bien!

Je, je. Yo como no manejo C y lo único que tengo a la mano es Dev-C++ creé esta función. Menos eficiente que la de ecfisa pero no me puedo quedar con las ganas de ponerla luego del rato que pasé haciendola :D

Código:

#include <time.h>
#include <shellapi.h>

void backup(char *user, char *password, char *database, char *outputdir)
{
        /* Obtenemos la fecha actual */
        time_t t = time(NULL);
        struct tm *tmp = localtime(&t);
        char fecha[9];
        strftime(fecha, sizeof(fecha), "%d%m%Y", tmp);

        char outputfile[MAX_PATH];
        char args[MAX_PATH];
       
        /* Calculamos el nombre del archivo de salida */
        sprintf(outputfile, "%s\\%s_%s.sql", outputdir, database, fecha);
       
        /* Calculamos los parámetros */
        sprintf(args, "-u%s -p%s %s -r %s", user, password, database, outputfile);
       
        /* Hacemos el respaldo */
        ShellExecute(
                0,
                "open",
                "C:\\Program Files\\MySQL\\MySQL Server 5.1\\bin\\mysqldump.exe",
                args,
                "",
                SW_HIDE);
}

La otra opción de ecfisa, mandando llamar a cmd.exe, seguro que también funciona parra ejecutar el BAT.

// Saludos

dmartinezn 14-04-2012 16:42:16

Saludos y muchas gracias por la ayuda.
He probado con cada una de las variantes que ustedes me han dado y no realiza el backup,en esta ocasion el codigo corre perfectamente pero no hace nada.

ecfisa 14-04-2012 19:37:32

Hola dmartinezn.

Veo que en tu primer mensaje envias la cadena:
Cita:

--opt --password=damian --user=damian ...
Sin embargo los códigos anteriores envían:
Cita:

-udamian -pdamian -r ...
Por mi ignorancia sobre mysql, no tengo ni idea cuál es el correcto (o si lo son ambos), pero yo revisaría el contenido de la cadena que se le envía a mysqldump.exe. Quizá allí radique el problema....

Saludos.

roman 15-04-2012 19:56:26

dmartinezn, el último código que puse lo probé y funcionó bien. Toma en cuenta que al llamar la función, casi seguro que tienes que especificar el directorio de salida usando dobles \\ y no una sola.

ecfisa, ambas formas de poner los parámetros son correctas. Es algo muy común en unix.

// Saludos

ecfisa 15-04-2012 21:40:45

Cita:

ecfisa, ambas formas de poner los parámetros son correctas. Es algo muy común en unix.
Hola roman.

Gracias por la aclaración.

Entonces con toda seguridad se trata de problemas en la definición de la ruta, ya que al igual que vos comprobé en la traducción del mensaje #12 los parámetros enviados por ShellExecute (mediante otro ejecutable) y son correctos. La función del mensaje #13 no la probé por que dí por sentado que funcionaba correctamente.

Saludos. :)


La franja horaria es GMT +2. Ahora son las 10:05:16.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi