在没有可见控制台窗口的窗口中创建后台进程
如何在不创建可见命令窗口的情况下在Windows上使用Haskell创建后台进程?
我编写了一个Haskell程序,该程序定期运行备份进程,但是每次运行该程序时,都会在所有窗口的顶部打开一个命令窗口。我想摆脱这个窗口。最简单的方法是什么?
解决方案
回答
我能想到的最简单的方法是从Windows Shell脚本(vbs或者cmd)中运行rsync命令。
回答
我对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); } }
回答
我们应该真正告诉我们我们当前的尝试方式,但是在我的系统上(使用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
回答
到目前为止,感谢答复,但是我已经找到了自己的解决方案。我确实尝试了许多不同的事情,从建议的编写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读入inH,但我们需要一个空文件。