 |
Club Builder Foro de C++Builder en español
|
| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
JesúsGandia Master


Registrado: 17 Jul 2004Mensajes: 403Ubicación: Gandia, Valencia
|
Publicado: Mie 17 Mar, 2010 4:14 pm Asunto: ExecCmdNoFocus del Foro no funciona en BC++2010 |
|
|
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 |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Mie 17 Mar, 2010 5:29 pm Asunto: |
|
|
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 |
|
 |
JesúsGandia Master


Registrado: 17 Jul 2004Mensajes: 403Ubicación: Gandia, Valencia
|
Publicado: Mie 17 Mar, 2010 8:00 pm Asunto: |
|
|
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 |
|
 |
JesúsGandia Master


Registrado: 17 Jul 2004Mensajes: 403Ubicación: Gandia, Valencia
|
Publicado: Mie 17 Mar, 2010 8:52 pm Asunto: |
|
|
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 |
|
 |
|
|
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
|
© 2002–2026 Club Builder · Funciona con phpBB.
|