7

How do I create a background process with Haskell on windows without a visible command window being created?

I wrote a Haskell program that runs backup processes periodically but every time I run it, a command window opens up to the top of all the windows. I would like to get rid of this window. What is the simplest way to do this?

2
  • 1
    This question should be reopened, as it is a about a "specific programming problem", specifically how to start a process in the background from Haskell. Commented Sep 7, 2014 at 21:47
  • Edited/reworded in hopes of a re-open. I think this is a useful question. I too think it should be re-opened Commented Aug 23, 2016 at 20:17

4 Answers 4

5

You should really tell us how you are trying to do this currently, but on my system (using linux) the following snippet will run a command without opening a new terminal window. It should work the same way on windows.

module Main where
import System
import System.Process
import Control.Monad

main :: IO ()
main = do
  putStrLn "Running command..."
  pid <- runCommand "mplayer song.mp3" -- or whatever you want
  replicateM_ 10 $ putStrLn "Doing other stuff"
  waitForProcess pid >>= exitWith
Sign up to request clarification or add additional context in comments.

1 Comment

scripts that work straight up on the command line in Linux do tend to pop up the cmd window in Windows. I just experienced this pleasure for the first time yesterday.
5

Thanks for the responses so far, but I've found my own solution. I did try a lot of different things, from writing a vbs script as suggested to a standalone program called hstart. hstart worked...but it creates a separate process which I didn't like very much because then I can't kill it in the normal way. But I found a simpler solution that required simply Haskell code.

My code from before was a simple call to runCommand, which did popup the window. An alternative function you can use is runProcess which has more options. From peeking at the ghc source code file runProcess.c, I found that the CREATE_NO_WINDOW flag is set when you supply redirects for all of STDIN, STOUT, and STDERR. So that's what you need to do, supply redirects for those. My test program looks like:

import System.Process
import System.IO
main = do
  inH <- openFile "in" ReadMode
  outH <- openFile "out" WriteMode
  runProcess "rsync.bat" [] Nothing Nothing (Just inH) (Just outH) (Just outH)

This worked! No command window again! A caveat is that you need an empty file for inH to read in as the STDIN eventhough in my situation it was not needed.

1 Comment

Perhaps there are better handles to supply than files "in" and "out" from the current directory?
0

The simplest way I can think of is to run the rsync command from within a Windows Shell script (vbs or cmd).

Comments

0

I don't know anything about Haskell, but I had this problem in a C project a few months ago.

The best way to execute an external program without any windows popping up is to use the ShellExecuteEx() API function with the "open" verb. If ShellExecuteEx() is available to you in Haskell, then you should be able to achieve what you want.

The C code looks something like this:

SHELLEXECUTEINFO Info;
BOOL b;

// Execute it
memset (&Info, 0, sizeof (Info));
Info.cbSize = sizeof (Info);
Info.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
Info.hwnd = NULL;
Info.lpVerb = "open";
Info.lpFile = "rsync.exe";
Info.lpParameters = "whatever parameters you like";
Info.lpDirectory = NULL;
Info.nShow = SW_HIDE;
b = ShellExecuteEx (&Info);
if (b)
   {
   // Looks good; if there is an instance, wait for it
   if (Info.hProcess)
      {
      // Wait
      WaitForSingleObject (Info.hProcess, INFINITE);
      }
   }

1 Comment

I don't believe it is directly, but it's only a small bit of FFI away.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.