GetStartupInfoA (@Si);
En realidad esa es la verdadera declaración que hace M$.
Saludos.
Posted 12 December 2016 - 01:41 PM
GetStartupInfoA (@Si);
Posted 12 December 2016 - 02:17 PM
Revisando las modificaciones de Delphius desde mi smartphone veo esto, que es un error:
si: LPSTARTUPINFOA; // Se cambió el tipo!
Debe ser así:
si: STARTUPINFOA; ........ GetStartupInfoA(@si);
Por eso salta el error en ejecución!!
Saludos.
Posted 12 December 2016 - 02:21 PM
A esos cambios añade STARTUPINFOA y GetStartupInfoA.
Saludos.
Añado. Parece que GetStartupInfoA pide un puntero y no una referencia en Lazarus64:
delphi
GetStartupInfoA (@Si);
En realidad esa es la verdadera declaración que hace M$.
Saludos.
Efectivamente con esos cambios ahora si compiló.
Y al ejecutar no dió AVs. Tendría que probarse el programa para comprobar que haga el trabajo correctamente aunque viniendo de escafandra seguro que lo hace.
A todo esto estos son los cambios ejectuados:
unit PipeShell2; interface uses Windows, Messages, SysUtils, FileUtil, Classes, LazUTF8; const BUFFERSIZE = 4*1024; type TPipeShell = class private PipeIn, PipeOut, PipeWrite, PipeRead: THANDLE; hProcess: THANDLE; Buffer: PAnsiChar; protected public constructor Create; destructor Destroy; override; function Write(S: String): DWORD; function Read: String; end; implementation constructor TPipeShell.Create; var sd: SECURITY_DESCRIPTOR; sa: SECURITY_ATTRIBUTES; si: STARTUPINFOA; pi: PROCESS_INFORMATION; begin PipeIn:= 0; PipeOut:= 0; PipeWrite:= 0; PipeRead:= 0; hProcess:= 0; GetMem(Buffer, BUFFERSIZE); InitializeSecurityDescriptor(@sd, SECURITY_DESCRIPTOR_REVISION); sa.lpSecurityDescriptor:= @sd; // sa.lpSecurityDescriptor:= nil; sa.nLength:= sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle:= TRUE; // Tuberia de entrada if CreatePipe(PipeIn, PipeWrite, @sa, 0) then begin // Tuberia de salida if CreatePipe(PipeRead, PipeOut, @sa, 0) then begin GetStartupInfoA(@Si); // Indicamos tuberias del proceso si.hStdOutput:= PipeOut; si.hStdError:= PipeOut; si.hStdInput:= PipeIn; si.dwFlags:= STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW; si.wShowWindow:= SW_HIDE; //si.wShowWindow:= SW_SHOW; // Ruta del shell ZeroMemory(Buffer, BUFFERSIZE); GetEnvironmentVariableA('COMSPEC', Buffer, BUFFERSIZE - 1); // Ejecutamos el shell if CreateProcessA(nil, Buffer, nil, nil, TRUE, CREATE_NEW_CONSOLE, nil, nil, si, pi) then begin hProcess:= pi.hProcess; CloseHandle(pi.hThread); end; end; end; end; destructor TPipeShell.Destroy; var ExitCode: DWORD; begin // Tratamos de terminar el shell repeat Write('quit'); Read; Write('q'); Read; Write('exit'); Read; GetExitCodeProcess(hProcess, ExitCode); until ExitCode <> STILL_ACTIVE; if PipeIn <> 0 then CloseHandle(PipeIn); if PipeOut <> 0 then CloseHandle(PipeOut); if PipeWrite <> 0 then CloseHandle(PipeWrite); if PipeRead <> 0 then CloseHandle(PipeRead); if hProcess <> 0 then CloseHandle(hProcess); if Buffer <> nil then FreeMem(Buffer); if WaitForSingleObject(hProcess, 9000) <> WAIT_OBJECT_0 then TerminateProcess(hProcess, DWORD(-1)); //GetExitCodeProcess(hProcess, ExitCode); //inherited; end; function TPipeShell.Write(S: String): DWORD; begin if PipeWrite = 0 then exit; lstrcpy(Buffer, PAnsiCHAR(S + #10)); WriteFile(PipeWrite, Buffer^, lstrlen(Buffer), Result, nil); end; function TPipeShell.Read: String; var dwRead, dwBytesAvail: DWORD; begin if PipeRead = 0 then exit; dwRead:= 0; // Esperamos a que tengamos algo que leer en PipeRead repeat sleep(100); PeekNamedPipe(PipeRead, Buffer, BUFFERSIZE, @dwRead, @dwBytesAvail, nil); if dwRead > 0 then begin // Leemos y vaciamos el PipeRead ZeroMemory(Buffer, BUFFERSIZE); ReadFile(PipeRead, Buffer^, dwRead, PDWORD(0)^, nil); OemToCharBuffA(Buffer, Buffer, dwRead); //Result:= Result + SysToUTF8(Buffer); Result := Result + LazUTF8.SysToUTF8(Buffer); end; until dwBytesAvail = 0; end; end.
Pueden ver al final que invoco a la versión SysToUTF8() de LazUTF8. Entre las pruebas me había dicho que estaba marcada como obsoleta y se aconsejaba usar la de la unidad LazUTF8.
Un detalle final que noté al probarlo un poco es la falta de las ñ y palabras con acentos que son reemplazadas con ?. Es algo menor, y se lo puede dejar de tarea.
Saludos,
PD: Si alguien recuerda como era para marcar/resaltar en la etiqueta de código una línea que me lo diga. Me hizo falta en esta ocasión.
Posted 12 December 2016 - 02:30 PM
Revisando las modificaciones de Delphius desde mi smartphone veo esto, que es un error:
delphi
si: LPSTARTUPINFOA; // Se cambió el tipo!
Debe ser así:
delphi
si: STARTUPINFOA; ........ GetStartupInfoA(@si);
Por eso salta el error en ejecución!!
Saludos.
Ya está amigo.
Ya hice los cambios como sugeriste. el código final está en el post #23
Nos estamos cruzando en los mensajes, parece el teléfono descompuesto...
Lo que queda al final es el tema de los carácteres "especiales" como la ñ que la reemplaza con ?
Posted 12 December 2016 - 02:31 PM
Posted 12 December 2016 - 02:34 PM
Delphius, soy muy lento escribiendo en el smartphone.
Saludos.
Posted 12 December 2016 - 03:33 PM
Veo que ya te compila y funcionó, Delphius.
A mi con SysToUTF8 me sale Ok el texto en Lazarus32.
De hecho es la función que siempre usé en Lazarus32 para ajustar esos caracteres. En fin, les gusta cambiar cosas no siempre para arreglarlo. Cuando llegue a casa hago unas pruebas.
Saludos.
Para Windows en 64bits, o al menos eso sospecho, o quizá sea a que uso posiblemente otra versión de Lazarus y han cambiado las cosas, los caracteres especiales no son bien reconocidos. Para arreglar esto al menos para mi ha sido necesario emplear WinCPToUTF8.
En este documento de la wiki explican algunas cosas relacionadas justo sobre esto.
Delphius, soy muy lento escribiendo en el smartphone.
Saludos.
Yo también lo soy amigo.
No te preocupes.
Lo importante es que me guiaste a la solución para que pudiera probarlo.
Tu sabes como odio a los punteros... al día de hoy me cuesta entender cuando va el @ y cuando no...
Saludos,
PROGRAMACIÓN →
Lazarus / FreePascal →
Consulta sobre invocacion de pascalStarted by ezequiel , 11 Jun 2017 pascal, procesos, listas |
|
|