7

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

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

4

4 回答 4

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
于 2008-09-09T17:00:11.687 回答
5

感谢您到目前为止的回复,但我找到了自己的解决方案。我确实尝试了很多不同的东西,从按照建议编写一个 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 读入,尽管在我的情况下不需要它。

于 2008-09-12T02:54:20.183 回答
0

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

于 2008-09-09T00:59:53.790 回答
0

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

在不弹出任何窗口的情况下执行外部程序的最佳方法是使用带有“open”动词的 ShellExecuteEx() API 函数。如果您在 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);
      }
   }
于 2008-09-09T14:13:47.093 回答