在没有可见控制台窗口的Windows中创建后台进程

时间:2008-09-09 00:47:22

标签: windows haskell

如何在没有创建可见命令窗口的情况下在Windows上使用Haskell创建后台进程?

我编写了一个定期运行备份过程的Haskell程序,但每次运行它时,命令窗口都会打开到所有窗口的顶部。我想摆脱这个窗口。最简单的方法是什么?

4 个答案:

答案 0 :(得分:5)

您应该告诉我们您当前是如何尝试这样做的,但在我的系统上(使用Linux),以下代码段将运行命令而无需打开新的终端窗口。它应该在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

答案 1 :(得分:4)

感谢目前为止的回复,但我找到了自己的解决方案。我确实尝试了很多不同的东西,从建议的vbs脚本到名为hstart的独立程序。 hstart工作......但它创建了一个我不太喜欢的独立过程,因为那时我不能以正常方式杀死它。但我找到了一个简单的解决方案,只需要Haskell代码。

我之前的代码是对runCommand的简单调用,它弹出窗口。您可以使用的另一个功能是runProcess,它有更多选项。通过查看ghc源代码文件runProcess.c,我发现当为所有STDIN,STOUT和STDERR提供重定向时,会设置CREATE_NO_WINDOW标志。这就是你需要做的,为那些提供重定向。我的测试程序如下:

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)

这很有效!再没有命令窗口!需要注意的是,你需要一个空的文件让inH以STDIN的形式读入,尽管在我的情况下它不需要。

答案 2 :(得分:0)

我能想到的最简单的方法是从Windows Shell脚本(vbs或cmd)中运行rsync命令。

答案 3 :(得分:0)

我对Haskell一无所知,但几个月前我在C项目中遇到了这个问题。

在没有任何窗口弹出的情况下执行外部程序的最佳方法是使用ShellExecuteEx()API函数和“open”动词。如果您在Haskell中可以使用ShellExecuteEx(),那么您应该能够实现您想要的目标。

C代码看起来像这样:

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);
      }
   }