Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

ExecCmdNoFocus del Foro no funciona en BC++2010

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Consultas
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: ExecCmdNoFocus del Foro no funciona en BC++2010 Responder citando

La función "ExecCmdNoFocus" publicada en este foro la he utilizado en varios proyectos de BC++2007 sin problemas, pero ahora en BC++2010 no soy capaz de hacer que funcione.
No me da ningún error de compilación ni de ejecución pero lo que pasa es que no hace NADA cuando la ejecuto. He intentado arreglarla pero sin éxito. ¿Podrian hecharme un cable?
Código:

DWORD __fastcall Shell(LPTSTR PathName, LPTSTR lpInitialDir, WORD WindowStyle)
{
   /* Parametros: PathName = ruta y nombre de la aplicación DOS
    lpInitialDir = ruta de la carpeta de trabajo
    WindowStyle = Estilo de la ventana en que se ejecuta la app. DOS*/

   STARTUPINFO si;
   PROCESS_INFORMATION pi;
   LPVOID lpvEnv;

   // Get a pointer to the environment block.
   lpvEnv = GetEnvironmentStrings();

   // Variable strings are separated by NULL byte, and the block is
   // terminated by a NULL byte.
   ZeroMemory(&si, sizeof(STARTUPINFO));
   si.dwFlags = STARTF_USESHOWWINDOW;
   si.wShowWindow = WindowStyle;
   si.cb = sizeof(si);

   CreateProcess(NULL, PathName, NULL, NULL, false, 0, lpvEnv, lpInitialDir, &si, &pi);
   return (pi.dwProcessId);
}
//--------------------------------------------------------------------------

//Un procedimiento para ejecutar y esperar a que termine
void ExecCmdNoFocus(LPTSTR CmdLine)
{
   /*Parametro: CmdLine = ruta y nombre de la aplicación DOS.
   Esperar a que un proceso termine,
   la ventana se mostrará minimizada sin foco*/

   HANDLE hProcess;
   DWORD RetVal;

   //The next line launches CmdLine as icon,
   //captures process ID
   hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
   Shell(CmdLine, NULL, SW_SHOWMINNOACTIVE));
   do
   {
      GetExitCodeProcess(hProcess, &RetVal); //Get the status of the process
      Application->ProcessMessages();
      Sleep(100); //Sleep command recommended as well as DoEvents
   }
   while (RetVal == STILL_ACTIVE);//Loop while the process is active
}
//--------------------------------------------------------------------------

_________________
Muchos hombres no se equivocan jamás porque no se proponen nada razonable.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email Visitar sitio web del autor
Mensaje    Asunto: Responder citando

Tienes varias opciones (las que voy a poner están pensadas para que al modificar el código sigan siendo compatibles con las versiones anteriores):


- Opción 1: (Dejamos que el nuevo proceso utilice las mismas variables de entorno que el proceso actual)

      Cambiamos la línea:
Código:
CreateProcess(NULL, PathName, NULL, NULL, false, 0, lpvEnv, lpInitialDir, &si, &pi);
      por:
Código:
CreateProcess(NULL, PathName, NULL, NULL, false, 0, 0, lpInitialDir, &si, &pi);
      Y podemos borrar las líneas:
Código:
LPVOID lpvEnv;
lpvEnv = GetEnvironmentStrings();



- Opción 2: (Forzamos a que las variables de entorno sean siempre Ansi)

      Cambiamos la línea:
Código:
lpvEnv = GetEnvironmentStrings();
      por:
Código:
lpvEnv = GetEnvironmentStringsA();



- Opción 3: (Adaptamos la llamada para que sea Ansi o Unicode según sea necesario)

      Cambiamos la línea:
Código:
CreateProcess(NULL, PathName, NULL, NULL, false, 0, lpvEnv, lpInitialDir, &si, &pi);
      por:
Código:
CreateProcess(NULL, PathName, NULL, NULL, false,
#ifdef _UNICODE
    CREATE_UNICODE_ENVIRONMENT,
#else
    0,
#endif
    lpvEnv, lpInitialDir, &si, &pi);


-----

Y otra opción por si te sirve, resumimos un poco el código original por:
Código:
bool EjecutarPrograma(String sPrograma)
{
    PROCESS_INFORMATION pi = {0};
    STARTUPINFO si = {0};
    si.cb = sizeof(si);
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_SHOWMINNOACTIVE;
    bool bRet = CreateProcess(0,sPrograma.c_str(),0,0,0,0,0,0,&si,&pi);
    while (bRet && WAIT_TIMEOUT == WaitForSingleObject(pi.hProcess, 100))
        Application->ProcessMessages();
    return bRet;
}
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Muchisimas gracias Leo,
funciona PERFECTAMENTE.

Me quedo con la primera opción...
_________________
Muchos hombres no se equivocan jamás porque no se proponen nada razonable.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email Visitar sitio web del autor
Mensaje    Asunto: Responder citando

POSDATA:

Después me he dado cuenta de que has tenido la cortesia de reducir y mejorar el código. GRACIAS nuevamente.

Resultado de las distintas funciones comprimiendo 2 ficheros que pesan en total (4.99MB), Tiempos de Proceso:

con ExecCmdNoFocus():
PRIMERA VEZ: 0.700977 seg.
SEGUNDA VEZ: 0.701187 seg.
TERCERA VEZ: 0.701714 seg.

con EjecutarPrograma():
PRIMERA VEZ: 0.532925 seg.
SEGUNDA VEZ: 0.521711 seg.
TERCERA VEZ: 0.520016 seg.

Es decir la mejora es del: 34,859%
probado con:
Código:

        // Creo variables de Proceso
        LARGE_INTEGER start, end, freq;
        SetThreadAffinityMask(GetCurrentThread(), 1);
        QueryPerformanceFrequency(&freq);
        QueryPerformanceCounter(&start);
        double seg;

        EjecutaCmd(Comprime);
        //ExecCmdNoFocus(Comprime.w_str());

        QueryPerformanceCounter(&end);
        seg = (end.QuadPart-start.QuadPart)/static_cast<double>(freq.QuadPart);
        ShowMessage(String().sprintf(L"%f segundos", seg));

_________________
Muchos hombres no se equivocan jamás porque no se proponen nada razonable.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email Visitar sitio web del autor
Mostrar mensajes de anteriores:   
Cambiar a:  
No puedes publicar temas nuevos en este foro
No puedes responder a temas en este foro
No puedes editar tus mensajes en este foro
No puedes borrar tus mensajes en este foro
No puedes votar en las encuestas de este foro


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.