Sample for pipe/inter-process communications on WIN?

Machine-specific discussion
Unix, Linux, OS X, OS/2, Windows, ..?
Locked
HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Sample for pipe/inter-process communications on WIN?

Post by HPW »

For understanding the new function 'pipe' and 'process', is it possible to get some sample code which shows how to use it on windows?
Hans-Peter

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

In the file 'qa' in the source distributin is a function 'test-pipe':

Code: Select all

(define (test-pipe)
	(write-file "pipe-child.lsp" 
[text]
(set 'msg (read-line (integer (nth 2 (main-args)))))
(write-line (upper-case msg) (integer (nth 3 (main-args))))
(exit)
[/text]
	)
	(set 'channel (pipe))
	(set 'in (first channel))
	(set 'out (last channel))

	(process (string "newlisp pipe-child.lsp " in " " out))
	(sleep 300)
	(write-line "hello there" out)
	(sleep 100)
	(= (read-line in) "HELLO THERE")
	(delete-file "pipe-child.lsp"))
The child process will read a string and write back the uppercase via the pipe.

Lutz

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

I just realize you should swap the last two lines, so the function only returns 'true' when succesfull:

Code: Select all

(define (test-pipe)
	(write-file "pipe-child.lsp" 
[text]
(set 'msg (read-line (integer (nth 2 (main-args)))))
(write-line (upper-case msg) (integer (nth 3 (main-args))))
(exit)
[/text]
	)
	(set 'channel (pipe))
	(set 'in (first channel))
	(set 'out (last channel))

	(process (string "newlisp pipe-child.lsp " in " " out))
	(sleep 300)
	(write-line "hello there" out)
	(sleep 100)
	(delete-file "pipe-child.lsp")
	(= (read-line in) "HELLO THERE"))
Lutz

HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by HPW »

Interesting stuff.

On this matter I would have a wish for the 'process' command.

It it possible to add a flag 'Hidden' or something like that,
which would try to start the programm without a visible console
window.

In neobook the 'run' command has such option and I use
it successfully for starting the newLISP based UdpListener
in hidden mode. Then it only appears in the process-list
of the task-manager. So it is possible with newLISP-based apps.

With this it would be possible to start a invisble process from
a main-app and communicate with the pipe-function.
Hans-Peter

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

newLISP is a console/shell application therefore you see a shell window popping up. If you do a (process "notepad.exe") you will see only the application window.

But isn't there some commandline parameter in Windows in do do this? the process function spawnvp() I am using does not have such an option, but is compatible over all platforms supported.

Lutz

HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by HPW »

>But isn't there some commandline parameter in Windows in do do this?

Yes I think so. I am not sure that I can use them here with '!' or 'process'.
Will check.
But as I said I had start a newLISP console app hidden from neobook.
So there it works for sure.
Hans-Peter

HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by HPW »

I did not get it with '!' or 'process' but I looked in the WIN-API:

Code: Select all

ShellExecute(0, 'open', 'ToStart.exe', 'CommandlineParams', 'StartDir' , SW_HIDE);
This works from a delphi-testapp.
Hans-Peter

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

Thanks, hopefully it works with 'pipe'

Lutz

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

This is how you can use it:

(set 'winexec (import "shell32.dll" "ShellExecuteA"))

(winexec 0 "open" "newlisp.exe" "" "" 0) ; hides newlisp shell

(winexec 0 "open" "newlisp.exe" "" "" 1) ; displays newlisp shell

(winexec 0 "open" "newlisp.exe" "" "" 2) ; shell is minimized

The last two parameters before the mode number are command line parameters and startup directory the application assumes. here the original API:

HINSTANCE ShellExecute(

HWND hwnd, // handle to parent window
LPCTSTR lpOperation, // pointer to string that specifies operation to perform
LPCTSTR lpFile, // pointer to filename or folder name string
LPCTSTR lpParameters, // pointer to string that specifies executable-file parameters
LPCTSTR lpDirectory, // pointer to string that specifies default directory
INT nShowCmd // whether file is shown when opened
);

Lutz

PS: I think it would not be a good idea to built this in to newLISP becuase there is no functional equivalent in Linux/Unix but the import gives you the full functionality offered by the Win32 API.

pjot
Posts: 733
Joined: Thu Feb 26, 2004 10:19 pm
Location: The Hague, The Netherlands
Contact:

Post by pjot »

Hi,

I suffer the same type of problem when starting small scripts interpreted by an external binary. This is also the case with newLisp. I made a small "run.exe" which solves this issue. In there, I use CreateProcess:

//Start process without console window
si.dwFlags=STARTF_USESHOWWINDOW;
si.wShowWindow=SW_HIDE;
ret = CreateProcess (NULL, (char*)exe, NULL, NULL, FALSE,
CREATE_NO_WINDOW, NULL, NULL, &si, &pi);

This will start the (interpreter-)process without DOS box. These are the specs according to the Win32 docs:

BOOL CreateProcess(

LPCTSTR lpApplicationName, // pointer to name of executable module
LPTSTR lpCommandLine, // pointer to command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // pointer to process security attributes
LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to thread security attributes
BOOL bInheritHandles, // handle inheritance flag
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // pointer to new environment block
LPCTSTR lpCurrentDirectory, // pointer to current directory name
LPSTARTUPINFO lpStartupInfo, // pointer to STARTUPINFO
LPPROCESS_INFORMATION lpProcessInformation // pointer to PROCESS_INFORMATION
);


I use my "run.exe" also to start newLisp applications. I hope this helps. The "run.exe" can be found at my site.

Regards

Peter

HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by HPW »

PS: I think it would not be a good idea to built this in to newLISP because there is no functional equivalent in Linux/Unix but the import gives you the full functionality offered by the Win32 API.
Agree, no need for it. I had not thought about direct use of the API and it shows again the flexibility of newLISP. 2 lines of lisp and the freedom to use it either from EXE and DLL. Great.
Hans-Peter

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

I remember several people on this board asked for exec without the window popping before. We should collect all these Win32 imports and put them together in a win32.lsp module. There is lots of other useful stuff in the Win23 API, just takes time to go thru it write the imports, document etc.

Lutz

Locked