2008-09-09 19 views
6

Comment créer un processus d'arrière-plan avec Haskell sous Windows sans créer de fenêtre de commande visible?Création d'un processus d'arrière-plan dans Windows sans fenêtre de console visible

J'ai écrit un programme Haskell qui exécute des processus de sauvegarde périodiquement mais chaque fois que je l'exécute, une fenêtre de commande s'ouvre en haut de toutes les fenêtres. Je voudrais me débarrasser de cette fenêtre. Quel est le moyen le plus simple de le faire?

+1

Cette question devrait être rouverte, car il s'agit d'un "problème de programmation spécifique", spécifiquement comment démarrer un processus en arrière-plan à partir de Haskell. – Cirdec

+0

Édité/reformulé dans l'espoir d'une réouverture. Je pense que c'est une question utile. Je pense aussi qu'il devrait être rouvert – Andre

Répondre

0

La manière la plus simple à laquelle je puisse penser est d'exécuter la commande rsync depuis un script Shell Windows (vbs ou cmd).

0

Je ne connais rien à Haskell, mais j'ai eu ce problème dans un projet C il y a quelques mois. La meilleure façon d'exécuter un programme externe sans ouvrir de fenêtre est d'utiliser la fonction API ShellExecuteEx() avec le verbe "open". Si ShellExecuteEx() est disponible pour vous dans Haskell, vous devriez être capable de réaliser ce que vous voulez.

Le code C ressemble à ceci:

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

Je ne crois pas que ce soit directement, mais c'est seulement un petit peu de FFI. – wnoise

5

Vous devriez vraiment nous dire comment vous essayez de le faire actuellement, mais sur mon système (en utilisant Linux) l'extrait suivant exécutera une commande sans ouverture une nouvelle fenêtre de terminal. Cela devrait fonctionner de la même manière sur les fenêtres. Merci pour les réponses à ce jour, mais j'ai trouvé ma propre solution.

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

Les scripts qui fonctionnent directement sur la ligne de commande sous Linux tendent à afficher la fenêtre cmd dans Windows. Je viens d'éprouver ce plaisir pour la première fois hier. –

4

J'ai essayé beaucoup de choses différentes, de l'écriture d'un script vbs comme suggéré à un programme autonome appelé hstart. hstart a fonctionné ... mais cela crée un processus séparé que je n'aimais pas beaucoup parce que je ne peux pas le tuer normalement. Mais j'ai trouvé une solution plus simple qui nécessitait simplement le code Haskell.

Mon code d'avant était un simple appel à runCommand, qui faisait apparaître la fenêtre. Une autre fonction que vous pouvez utiliser est runProcess qui a plus d'options. De jeter un coup d'oeil au fichier de code source ghc runProcess.c, j'ai trouvé que l'indicateur CREATE_NO_WINDOW est défini lorsque vous fournissez des redirections pour tout STDIN, STOUT et STDERR. Donc, c'est ce que vous devez faire, fournir des redirections pour ceux. Mon programme de test ressemble à:

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) 

Cela a fonctionné! Aucune fenêtre de commande à nouveau! Une mise en garde est que vous avez besoin d'un fichier vide pour inH à lire en tant que le STDIN même si dans ma situation, il n'était pas nécessaire.

+0

On dirait que votre code n'est pas complet. Qu'est-ce que "faire inH"? – oshyshko

+0

Peut-être y a-t-il de meilleures poignées à fournir que les fichiers '" in "' et '" out "' du répertoire courant? – Cirdec