Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > API de Windows
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 22-08-2007
feidakila feidakila is offline
Registrado
 
Registrado: mar 2007
Posts: 1
Poder: 0
feidakila Va por buen camino
Error utilizando GetModuleUsage en WinExecAndWait32 en Borland Delphi 7

Hola, estoy usando Borland Delphi 7 y necesitaba un procedimiento para ejecutar un programa en consola (cmd) de manera síncrona (es decir hasta que no termina de ejecutarse el programa en la consola no se devuelve el control al programa Delphi que lo llamó) y he estado investigando en la red y el foro y me he topado con una funcion llamada WinExecAndWait32. He descargado 3 versiones diferentes de esta y sólo he conseguido hacer funcionar una de las 3 después de alguna leve modificación.

Pongo las 3 funciones, los problemas que he tenido y las modificaciones que les he hecho, además propongo una duda al final del post que me surge en una de las implementaciones y que no se resolver (por curiosidad)

1era implementacion: esta no me funciona, ya que se llama a WaitForSingleObject antes de que finalice el programa llamado por WinExec
Código Delphi [-]
function TForm1.WinExecAndWait(Path:PChar;Visibility:Word):Word;
var
  InstanceID:THandle;
begin
  InstanceID:=WinExec(Path, Visibility);
  WinExecAndWait:=WaitForSingleObject(InstanceID,INFINITE);
end;



2da implementacion: en esta me surgieron los siguientes errores, al principio cuando operamos con la variable Path, se intenta acceder mediante la funcion move a Path[0] con lo que da un error de compilación de valor inaccesible (supongo que se almacena el valor de la longitud de la cadena en esa celda); esto lo he solucionado cambiando el tipo de la variable Path a PChar para no tener que hacer ninguna transformación a Path (de todas maneras no se porque lo hace el autor). Como 2º error que no he conseguido solventar es la llamada a la funcion GetModuleUsage, la cual al compilar me dice que no existe dicho identificador y en la ayuda de Dephi no viene nada al respecto, como solución la he comentado pero evidentemente la función retoma el control antes de que el programa de consola termine (la condición es true)
Código Delphi [-]
Function TForm1.WinExecAndWait33(Path : PChar; Visibility : word) : word;
var
  InstanceID : THandle;
//  PathLen : integer;
begin
  { inplace conversion of a String to a PChar }
//  PathLen := Length(Path);
//  Move(Path[1],Path[0],PathLen);  {esta linea falla al acceder a path[0]}
//  Path[PathLen] := #0;
  { Try to run the application }
  InstanceID := WinExec(Path,Visibility); {hemos sustituido @Path por Path}
  if InstanceID < 32 then { a value less than 32 indicates an Exec error }
     WinExecAndWait33 := InstanceID
  else
  begin
    Repeat
      Application.ProcessMessages;
    until Application.Terminated;{or (GetModuleUsage(InstanceID)=0);}  {error! getmoduleusage -> identificador no declarado}
    WinExecAndWait33 := 32;
  end;
end;


3era implementacion: por último y la que me ha funcionado, salvo una ligera modificación. Y ha sido cambiar el tipo de la variable lpExitCode (antes entero) a tipo cardinal (según parece antes estaba definido como entero y ahora como cardinal)
Código Delphi [-]
function TForm1.WinExecAndWait32(Path: PChar; Visibility: Word): integer;
var
   Msg: TMsg;
   lpExitCode : cardinal;  {antes era integer}
   StartupInfo: TStartupInfo;
   ProcessInfo: TProcessInformation;
begin
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  with StartupInfo do
  begin
    cb := SizeOf(TStartupInfo);
    dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
    wShowWindow := visibility; 
  end;
  if CreateProcess(nil,path,nil, nil, False,
    NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo) then begin
    repeat
      while PeekMessage(Msg, 0, 0, 0, pm_Remove) do
        begin
          if Msg.Message = wm_Quit then Halt(Msg.WParam);
          TranslateMessage(Msg);
          DispatchMessage(Msg);
        end;  
    GetExitCodeProcess(ProcessInfo.hProcess,lpExitCode);    {producia error porque lpExitCode es de tipo entero y ha de ser cardinal}
    until lpExitCode<>Still_Active;
    with ProcessInfo do 
    begin
      CloseHandle(hThread);
      CloseHandle(hProcess);
    end;
    result := 0; {sucess}
  end
  else
    result:=GetLastError;
end;



Duda en la 2da implementación ¿porqué no me deja declarar la función GetModuleUsage?, ¿no viene implementada en la librería ShellApi de Borland? (he tratado a incluir la librería WinApi pero me da error, supongo que tampoco existe), ¿existe una función similar, se llama de otra manera?

Perdonad el rollo, pero es que llevaba un tiempo estancado con esto y lo mismo este post sirve por si alguien se topa con el mismo problema, muchas gracias y enhorabuena por el foro es de grandísima ayuda
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Error utilizando DataSet Coco_jac Conexión con bases de datos 2 13-04-2006 00:12:35
error inesperado con Borland (2) mrmanuel Conexión con bases de datos 2 09-08-2005 13:40:42
Excel con delphi 5 utilizando Bde zugazua2001 API de Windows 0 30-05-2005 16:18:49
IBDataSet en Delphi 2005 (Error de Borland?) gluglu Conexión con bases de datos 0 15-02-2005 23:22:33
WinExecAndWait32 Aztaroth Varios 2 02-02-2004 16:19:36


La franja horaria es GMT +2. Ahora son las 18:08:32.


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
Copyright 1996-2007 Club Delphi