none
Как запустить программу в фоновом режиме без открытия окна и с перенаправлением вывода в файл? RRS feed

  • Вопрос

  • OS Windows XP
    Есть консольная программа, которая работает несколько часов, выводит информацию на стандартный поток вывода. Нужно запустить её в фоновом режиме из .bat файла (в этом файле до запуска этой программы выполняются ещё другие нужные действия) так, чтобы не осталось на экране открытого окна, даже консольного (cmd.exe), но при этом вывод программы перенаправить в файл.

    Просто фоновый режим (без окна), но без перенаправления в файл работает так.
    start /b myprog.exe

    Просто перенаправление вывода в файл, но без закрытия окна работает так.
    cmd /c "myprog.exe > myfile.txt"
    или
    myprog.exe > myfile.txt
    В любом из этих случаев .bat не заканчивает выполнения, а ждёт завершения этой команды (которая работать будет несколько часов) и не закрывает своё окно, которое зачет-то открыл.

    Таким образом, для немедленного завершения .bat файла приходится использовать команду start, иначе никак. Однако команда
    start /b myprog.exe > myfile.txt
    будет делать не то, что нужно, так как поток перенаправится от команды start, а не от myprog.exe, как нужно.

    Единственной возможностью остаётся вложить команду cmd в команду start так.
    start /b cmd /c "myprog.exe > myfile.txt"
    По описаниям в помощи это должно делать то, что нужно, однако почему-то окно всё равно не закрывается.

    Вообще непонятно, зачем понадобилось открывать окно по умолчанию и создавать такие сложности, чтобы его специально закрыть. В OS Linux всё наоборот. По умолчанию окна нет, если оно нужно, то отдельной опцией это указывается. В OS Linux требуемое действие делается очень просто так.
    myprog > myfile &

    Ещё одна сложность в том, что команда cmd принимает в качестве параметра строку, которую нужно выполнить, что удобно, но не умеет её выполнять, не открывая окна. Команда start как раз сделана для того, чтобы не открывать окно, однако она не умеет выполнять команду в виде строки, а принимает первым параметром имя программы, вторым параметром - первый параметр запускаемой программы и так далее, что делает невозможным перенаправить поток вывода запускаемой программы в файл, так как знак > перенаправит поток вывода команды start.

    У каждой из этих двух команд есть преимущества и недостатки, но сделать то, что нужно не получается даже комбинируя их.

    Ещё хочу заметить, что очень глупо открывать консольное окно при выполнении программы и не закрывать его, так как оно не всегда нужно. В моём случае закрытие окна вручную не приводит к завершению работы запущенной программы, а просто создаёт пользователю лишние трудности по закрыванию окна. Нужно избавить пользователя от ненужной работы.

    Я уже долго мучался сам, советовался с друзьями, но никто не может помочь. Обращаюсь теперь к вам в надежде, что фирма Microsoft всё же лучше знает, как использовать возможности её командной строки для достижения нужного результата. Если ВЫ не поможете, больше обращаться мне не к кому. Это ВАШ программный продукт, всё что можно почерпнуть из помощи по этим командам, я прочитал, но там практически нет ничего нужного.

    Помогите, пожалуйста, написать одну строку с командой, но правильно, чтобы она делала то, что нужно. Заранее спасибо.

    27 октября 2007 г. 15:51

Все ответы

  • Можно по-разному выйти из положения. Например, переписать ваш командный файл в виде сценария WSH (файл с расширением vbs). В этом случае запуск вашей программы в невидимом окне будет выглядеть так:

     

    Set oShell = WScript.CreateObject("WScript.Shell")
    oShell.Run "myprog.exe > myfile.txt", 0, False

    27 октября 2007 г. 17:20
    Модератор
  • Я к сожалению никогда не пользовался сценариями WSH, но я прочитал в Интернете некоторую основную информацию, чтобы примерно понять как работают эти строки.

    К сожалению, при запуске "myprog.exe > myfile.txt" oShell.Run воспринимает это как программу с параметрами, то есть ">" - первый параметр, "myfile.txt" - второй параметр. Это можно проверить например, если myprog.exe создать из myprog.c, который выглядит так:

    #include <stdio.h>

    int main(int argc, char** argv)
    {
            int i;
            FILE* F;
            
            printf("Hello\n");
            F = fopen("my.log", "w");
            for (i = 0; i < argc; i++)
                    fprintf(F, "arg%d='%s'\n", i, argv[ i ]);
            fclose(F);
            
            return 0;
    }

    В результате, после запуска файла  my.vbs (скрипт) файл myfile.txt остаётся пустым, а в файле my.log мы видим, что ">" и "myfile.txt" были переданы программе myprog.exe как параметры командной строки.

    Мне же нужно, чтобы это было перенаправление потока вывода, как интерпретирует его cmd.exe. Следовательно, oShell.Run должен запускать не такую команду, а такую
    cmd /c "myprog.exe > myfile.txt"

    То есть нужно запустить команду cmd и передать ей два параметра командной строки: "/c" - первый параметр, "myprog.exe > myfile.txt" - второй параметр (строка с командой cmd).

    Но ведь команда для oShell.Run должна быть в двойных кавычках, а у cmd тоже второй параметр должен быть в кавычках (иначе он будет интерпретироваться неправильно). То есть нужно сделать вложенные двойные кавычки. Просто вложенные или экранированные \ не работают, одинарные кавычки тоже не работают.

    Как всё-таки выйти из положения? Заранее спасибо.
    29 октября 2007 г. 12:59
  • А если запускать посредством планировщика задач ? создать учётную запись с требуемыми правами и запускать из под неё. Т.е допустим есть 2 записи user1 и user2, работает за компом user1, а задача выполняется с правами user2, соответственно user1 её не увидит и повлиять на неё тоже не сможет

     

    29 октября 2007 г. 17:43
  • Всё-таки пользователь должен иметь возможность при необходимости прекратить работу программы (это осуществляется запуском другой программы, которая останавливает первую) или запустить её заново.

    В принципе я собирался сделать задание для запуска программы при загрузке. К сожалению я не нашёл возможности запуска программы при выключении системы.

    Но тем не менее, помимо заданий, программой должен управлять пользователь.

    Насчёт кавычек в данном случае есть такой выход: не ставить пробелы около знака ">" (с двух сторон), но это помогает только в том случае, если у программы нет параметров.

    То есть для запуска
    cmd /c "myprog.exe > myfile.txt"
    Можно использовать
    oShell.Run "cmd /c myprog.exe>myfile.txt", 0, False

    Но в случае необходимости запуска
    cmd /c "myprog.exe parameter1 ... parameterN > myfile.txt"
    Нужно использовать вложенные кавычки. В OS Linux вложенные кавычки экранируются так
    \"
    В OS Windows так не работает ни в одном скриптовом языке, который я видел в XP.

    То есть нужно каким-то образом передать параметры или экранировать кавычки. Почему-то в OS Windows для этого приходится мучиться много дней/недель/месяцев и писать длинные неэстетические скипты на разных скриптовых языках, комбинируя из них один нужный сценарий, всё время изворачиваюсь, чтобы убрать лишнее окно, передать параметры, перенаправить поток и т.д. А в OS Linux всё делается сходу не задумываясь в одну/две команды.

    Просто не понимаю, как можно удобно пользоваться OS Windows, когда одни проблемы?

    Может быть, кто-то знает какой-то продвинутый скриптовый язык для OS Windows, который легко выучить, легко использовать и который имеет хорошую документацию, хотя бы на английском языке. Просто уже полгода не могу сделать то, что в Linux за 10 секунд сделал.

    Заранее спасибо.
    29 октября 2007 г. 20:17
  • А нельзя сделать вывод в файл средствами самой программы ? И кстати любопытно, а что делает программа ? Да ещё в течении нескольких часов.

    P.S. запускать программу при выключении системы можно в консоли управления "локальная политика безопасности->конфигурация пользователя->административные шаблоны->система->сценарии"

    29 октября 2007 г. 20:45
  • создайте скрипт

    myprog.exe > myfile.txt

    например, myprog.cmd

     

    и попробуйте это:

     

    AT [\\имя_компьютера] время [/INTERACTIVE]
        [ /EVERY:день[,...] | /NEXT:день[,...]] "команда"

    \\имя_компьютера   Имя удаленного компьютера. Если этот параметр опущен,
                       используется локальный компьютер.
    код                Порядковый номер запланированной задачи.
    /delete            Отмена запланированной задачи. Если код задачи опущен,
                       отменяются все задачи, запланированные для указанного
                       компьютера.
    /yes               Отмена запроса на подтверждение при отмене всех
                       запланированных задач.
    время              Время запуска команды.
    /interactive       Разрешение взаимодействия задачи с пользователем,
                       работающим на компьютере во время запуска задачи.
    /every:день[,...]  Запуск задачи осуществляется по указанным дням недели или
                       месяца. Если дата опущена, используется текущий день
                       месяца.
    /next:день[,...]   Задача будет запущена в следующий указанный день недели
                       (например в следующий четверг). Если дата опущена,
                       используется текущий день месяца.
    "команда"          Команда Windows NT или имя пакетного файла.

    выполняется от системы, можно зашедулить или выполнить однократно (если однократно, задача сама исчезнет после выполнения), прервать, сделать (или не сделать) интерактивным, так же позволит увидеть код звершения задачи.

     

    30 октября 2007 г. 13:44
  •  zavvin_itr написано:

    А нельзя сделать вывод в файл средствами самой программы ? И кстати любопытно, а что делает программа ? Да ещё в течении нескольких часов.

     

    например очень удобно выполнять ntbackup (файловый сервер в 400 Гб бекапится около 12-15 часов) и при этом получать инфу о состоянии файла *.bkf

    30 октября 2007 г. 13:49
  • Млин.... вот ведь народ, Вы что думаете никто не знает о ntbackup кроме Вас ? и сколько создаётся архив ? Спрашивал ведь определённого человека, об обпределённой программе.. а в ответ флуд....Sad

    30 октября 2007 г. 16:38
  • Для вставки экранированных кавычек и прочих спец.символов в текстовую перменную используют функцию chr() в данном случае для передачи кавычек используется chr(34)

     

    В данном случае решением задачи будет

     

    Option Explicit
    Dim objShell, strCommand
    Set objShell = CreateObject("Wscript.Shell")

     

    strCommand = "cmd /c " & chr(34) & "myprog.exe > myfile.txt" & chr(34)
    objShell.Run strCommand, 0, False

    28 января 2008 г. 15:50
  • Если не принципиально, то можно воспользоваься сторонними утилитами, например hstart.exe

    hstart /nowindow "cmd /c myprog 1>myfile.txt"

    А остановить,  т.к.  окна  нет,  только  через  таскменеджер  или  taskkill  /im  myprog.exe

    • Предложено в качестве ответа fajm 6 сентября 2011 г. 7:09
    28 января 2008 г. 18:36
  •  а как сделать так, чтобы программа запускалась с командной строки и открывала файл находящемся на другом компьютере???
    6 сентября 2011 г. 7:11