Как мне создать фоновый процесс с Haskell в Windows без создания видимого командного окна?
Я написал программу на Haskell, которая периодически запускает процессы резервного копирования, но каждый раз, когда я запускаю ее, командное окно открывается вверху всех окон. Я бы хотел избавиться от этого окна. Как это сделать проще всего?
Отредактировано / перефразировано в надежде на повторное открытие. Думаю, это полезный вопрос. Я тоже думаю, что его нужно снова открыть





Самый простой способ, который я могу придумать, - это запустить команду rsync из сценария Windows Shell (vbs или cmd).
Я ничего не знаю о Haskell, но у меня была эта проблема в проекте C несколько месяцев назад.
Лучший способ выполнить внешнюю программу без всплывающих окон - использовать функцию API ShellExecuteEx () с глаголом «открыть». Если ShellExecuteEx () доступен для вас в Haskell, вы сможете достичь того, чего хотите.
Код 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);
}
}
Я не верю, что это напрямую, но это лишь небольшая часть FFI.
Вы действительно должны рассказать нам, как вы пытаетесь это сделать в настоящее время, но в моей системе (с использованием Linux) следующий фрагмент кода будет запускать команду, не открывая новое окно терминала. Он должен работать точно так же в окнах.
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
сценарии, которые работают прямо в командной строке в Linux, имеют тенденцию открывать окно cmd в Windows. Я только вчера впервые испытал это удовольствие.
Спасибо за ответы, но я нашел собственное решение. Я пробовал много разных вещей, от написания сценария vbs, как предлагалось, до отдельной программы под названием hstart. hstart работал ... но он создает отдельный процесс, который мне не очень нравится, потому что тогда я не могу его убить обычным способом. Но я нашел более простое решение, для которого требовался простой код на Haskell.
Мой предыдущий код представлял собой простой вызов runCommand, который открывал всплывающее окно. Альтернативная функция, которую вы можете использовать, - это runProcess, у которой есть больше опций. Заглянув в файл исходного кода ghc runProcess.c, я обнаружил, что флаг CREATE_NO_WINDOW устанавливается, когда вы предоставляете перенаправления для всех STDIN, STOUT и STDERR. Вот что вам нужно сделать - предоставить для них перенаправления. Моя тестовая программа выглядит так:
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, хотя в моей ситуации он не нужен.
Может быть, есть дескрипторы лучше, чем файлы "in" и "out" из текущего каталога?
Этот вопрос следует снова открыть, поскольку он касается «конкретной проблемы программирования», в частности, как запустить процесс в фоновом режиме из Haskell.