From: Bernd H. <ber...@ic...> - 2008-11-05 12:57:16
|
Hi Mads, thanks a lot for your reply. I wasn't subscribed to wxhaskell-develop yet so I only today realized you answered my posting. I applied your supposal on my Windows machine with the following results: wxExecProcess now indeed yields output on stderr, but output on both stdout and stderr are somewhat incomplete (with no change when setting output buffering in processtest.exe to NoBuffering): display on stdout frame: Stdout: 100: Info 98: Info 96: Info 94: Info 92: Info 90: Info 88: Info 86: Info 84: Info 82: Info Stdout: 80: Info 78: Info ... and on stderr frame: Stderr: 99: Error 97: Error 95: Error 93: Error 91: Error 89: Error 87: Error 85: ErroStderr: r 83: Error ... That is, the first 8 bytes (Stdout: / Stderr: ) are most of the time vanished. Whereas processExecAsyncTimed yields the correct output (of course only on stdout): Stdout: 100: Info Stdout: 98: Info Stdout: 96: Info Stdout: 94: Info ... Do you have any idea? (Before starting to delve deep into the process management myself...) Thanks again, Bernd > Hi Bernd > > Bernd Holzmüller wrote: >> Hi all, >> >> I am developing a test management GUI where processes are started and >> their output (on stdout and stderr) are shown on corresponding console >> windows. The process management worked quite OK with version 0.9.4 but >> does no longer work in version 0.10.3 (using ghc 6.8.3 on Windows XP). >> >> The attached small example application shows what happens: with >> processExecAsync only garbage is shown on both the stdout and the stderr >> console window, with processExecAsyncTimed the stdout console works >> fine, but the stderr console shows nothing. Main.hs is the wxHaskell GUI >> with two buttons, both calling the application compiled from >> Testproc.hs, one using processExecAsync, one using the Timed variant. >> The attached makefile builds everything. >> >> If someone with understanding of the internals of wxHaskell could have a >> look on this topic, I would be very grateful. Perhaps the (soon?) coming >> new wxHaskell version 0.11 will do correctly? >> >> Thanks, >> Bernd >> > > Your processExecAsyncTimed example works on Linux. But of cause that do > not help you much. The processExecAsync example do not work on Linux > either. > > A while ago I got tired of the hard-to-get-to-work nature of > processExecAsyncTimed and therefore wrote my own process executor. I > have attached my own process executor and an adapted version of your > code, which works for me (on Linux). You will have to adapt it a little > bit to work on windows (properly just changing "./testproc.exe" to > "testproc" should do). > > I would love to hear if it works on your machine. > > > Greetings, > > Mads Lindstrøm |
From: Mads L. <mad...@ya...> - 2008-11-05 20:46:39
|
Hi, > Hi Mads, > > thanks a lot for your reply. I wasn't subscribed to wxhaskell-develop > yet so I only today realized you answered my posting. > > I applied your supposal on my Windows machine with the following > results: wxExecProcess now indeed yields output on stderr, but output on > both stdout and stderr are somewhat incomplete (with no change when > setting output buffering in processtest.exe to NoBuffering): > > display on stdout frame: > > Stdout: 100: Info > 98: Info > 96: Info > 94: Info > 92: Info > 90: Info > 88: Info > 86: Info > 84: Info > 82: Info > Stdout: > 80: Info > 78: Info > ... > > and on stderr frame: > > Stderr: 99: Error > 97: Error > 95: Error > 93: Error > 91: Error > 89: Error > 87: Error > 85: ErroStderr: r > 83: Error > ... > > That is, the first 8 bytes (Stdout: / Stderr: ) are most of the time > vanished. Whereas processExecAsyncTimed yields the correct output (of > course only on stdout): > > Stdout: 100: Info > Stdout: 98: Info > Stdout: 96: Info > Stdout: 94: Info > ... > > Do you have any idea? (Before starting to delve deep into the process > management myself...) Nope, I have no idea why it do not work for you - sorry :( /Mads Lindstrøm > > Thanks again, > Bernd > > > Hi Bernd > > > > Bernd Holzmüller wrote: > >> Hi all, > >> > >> I am developing a test management GUI where processes are started and > >> their output (on stdout and stderr) are shown on corresponding console > >> windows. The process management worked quite OK with version 0.9.4 but > >> does no longer work in version 0.10.3 (using ghc 6.8.3 on Windows XP). > >> > >> The attached small example application shows what happens: with > >> processExecAsync only garbage is shown on both the stdout and the stderr > >> console window, with processExecAsyncTimed the stdout console works > >> fine, but the stderr console shows nothing. Main.hs is the wxHaskell GUI > >> with two buttons, both calling the application compiled from > >> Testproc.hs, one using processExecAsync, one using the Timed variant. > >> The attached makefile builds everything. > >> > >> If someone with understanding of the internals of wxHaskell could have a > >> look on this topic, I would be very grateful. Perhaps the (soon?) coming > >> new wxHaskell version 0.11 will do correctly? > >> > >> Thanks, > >> Bernd > >> > > > > Your processExecAsyncTimed example works on Linux. But of cause that do > > not help you much. The processExecAsync example do not work on Linux > > either. > > > > A while ago I got tired of the hard-to-get-to-work nature of > > processExecAsyncTimed and therefore wrote my own process executor. I > > have attached my own process executor and an adapted version of your > > code, which works for me (on Linux). You will have to adapt it a little > > bit to work on windows (properly just changing "./testproc.exe" to > > "testproc" should do). > > > > I would love to hear if it works on your machine. > > > > > > Greetings, > > > > Mads Lindstrøm > > > > > ------------------------------------------------------------------------- > This SF.Net email is sponsored by the Moblin Your Move Developer's challenge > Build the coolest Linux based applications with Moblin SDK & win great prizes > Grand prize is a trip for two to an Open Source event anywhere in the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > _______________________________________________ > wxhaskell-devel mailing list > wxh...@li... > https://lists.sourceforge.net/lists/listinfo/wxhaskell-devel |
From: shelarcy <she...@gm...> - 2008-11-12 16:22:12
|
Hi, On Wed, 05 Nov 2008 21:57:07 +0900, Bernd Holzmüller <ber...@ic...> wrote: >>> The attached small example application shows what happens: with >>> processExecAsync only garbage is shown on both the stdout and the stderr >>> console window, with processExecAsyncTimed the stdout console works >>> fine, but the stderr console shows nothing. Main.hs is the wxHaskell GUI >>> with two buttons, both calling the application compiled from >>> Testproc.hs, one using processExecAsync, one using the Timed variant. >>> The attached makefile builds everything. I tested Mads' program on Mac OS X platform. [1]. processExecAsync example crashes this program. [2]. processExecAsyncTimed example doesn't work correctory. stdout console works fine, but the stderr console *almost* shows nothing. We must care about this fact. stderr console *sometimes* works fine. (I also saw this fact on Windows. stderr console *sometimes* works fine, too.) [3]. wxExecProcess example works fine. >>> I am developing a test management GUI where processes are started and >>> their output (on stdout and stderr) are shown on corresponding console >>> windows. The process management worked quite OK with version 0.9.4 but >>> does no longer work in version 0.10.3 (using ghc 6.8.3 on Windows XP). > I applied your supposal on my Windows machine with the following > results: wxExecProcess now indeed yields output on stderr, but output on > both stdout and stderr are somewhat incomplete (with no change when > setting output buffering in processtest.exe to NoBuffering): > > (snip) Do you test program with same version's GHC? GHC's IO functions has some bugs on Windows platform. So, I want to know that this is wxHaskell's bug or GHC's bug. http://hackage.haskell.org/trac/ghc/ticket/806 http://hackage.haskell.org/trac/ghc/ticket/2189 etc... I tried to fix the problem in this week. But I can't find where causes this problem by undoing Graphics.UI.WXCore.Process related changes. Best Regards, > display on stdout frame: > > Stdout: 100: Info > 98: Info > 96: Info > 94: Info > 92: Info > 90: Info > 88: Info > 86: Info > 84: Info > 82: Info > Stdout: > 80: Info > 78: Info > ... > > and on stderr frame: > > Stderr: 99: Error > 97: Error > 95: Error > 93: Error > 91: Error > 89: Error > 87: Error > 85: ErroStderr: r > 83: Error > ... > > That is, the first 8 bytes (Stdout: / Stderr: ) are most of the time > vanished. Whereas processExecAsyncTimed yields the correct output (of > course only on stdout): > > Stdout: 100: Info > Stdout: 98: Info > Stdout: 96: Info > Stdout: 94: Info > ... -- shelarcy <shelarcy hotmail.co.jp> http://page.freett.com/shelarcy/ |
From: Bernd H. <ber...@ic...> - 2008-11-13 10:08:13
|
{-# LANGUAGE PatternSignatures #-} module WxProcess ( wxExecProcess , ExitCode(..) ) where import Control.Concurrent -- forkIO, MVars import System.Exit (ExitCode(..)) import System.Process (runInteractiveCommand, waitForProcess, ProcessHandle) import System.IO import Foreign.Marshal.Array import Foreign.Marshal.Alloc import Data.Word import Data.IORef -- import qualified Graphics.UI.WX as WX import Graphics.UI.WX import Graphics.UI.WX (Prop(..), on) type OnReceive = String -> IO() wxExecProcess :: Window a -> String -> Int -> IORef Bool -> (ExitCode -> IO()) -> OnReceive -> OnReceive -> IO ProcessHandle -- if the user needs to give input to the created process, we could return IO (String -> IO StreamStatus) in stead wxExecProcess parent cmd bufferSize killedByUser onEndProcess onOutput onErrOutput = do (inh,outh,errh,pid) <- runInteractiveCommand cmd mapM_ (\hdl -> hSetBuffering hdl NoBuffering) [inh, outh, errh] -- fork off two threads to start consuming the stdout and stderr output stdOutMVar <- newEmptyMVar stdErrMVar <- newEmptyMVar stdOutIsFinished <- newEmptyMVar stdErrIsFinished <- newEmptyMVar processFinished <- newEmptyMVar let consume handle isFinished outputMVar = do buf <- mallocArray bufferSize consume' handle isFinished outputMVar buf free buf consume' handle isFinished outputMVar buf = do outIsEOF <- hIsEOF handle if outIsEOF then putMVar isFinished () else do hWaitForInput handle 1000 -- 1000 = one second count <- hGetBufNonBlocking handle buf bufferSize (x :: [Word8]) <- peekArray count buf putMVar outputMVar (map (toEnum . fromIntegral) x) consume' handle isFinished outputMVar buf forkIO $ consume outh stdOutIsFinished stdOutMVar forkIO $ consume errh stdErrIsFinished stdErrMVar let handleAnyInput mvar withOutput = do val <- tryTakeMVar mvar maybe (return ()) withOutput val let handleAllInput = do handleAnyInput stdOutMVar onOutput handleAnyInput stdErrMVar onErrOutput checkOutput <- timer parent [ interval := 100 ] -- 10 times a second set checkOutput [ on command := do exitCode <- tryTakeMVar processFinished handleAllInput case exitCode of Nothing -> return () Just code -> do onEndProcess code set checkOutput [enabled := False] ] forkIO $ do exitCode <- waitForProcess pid -- compile with -threaded to allow other threads to be active concurrently! wasKilled <- varGet killedByUser let waitForOutputs = mapM_ takeMVar [stdOutIsFinished, stdErrIsFinished] signalFinished = putMVar processFinished exitCode if wasKilled then do signalFinished; waitForOutputs else do waitForOutputs; signalFinished hClose outh hClose errh return pid |