На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
    > [Ruby] Запуск документа ассоциированной программой в Windows , с ожиданием процесса
      В Руби программе требуется запустить программу для любого типа документа (mp3, html, pdf, ...) с ожиданием результата от запущенного процесса.

      Проблема заключается в том, что программа запускает процесс без ожидания окончания процесса, что недопустимо. Хочу контролировать результат успешности выполнения процесса, чтобы потом, в случае успеха, скопировать документ в хранилище.

      Программа должна работать в Windows (XP и может в других).

      Пробовал такой вариант:
      ExpandedWrap disabled
        document = ARGV[0]
         
        if RUBY_PLATFORM =~ /mswin|mingw|cygwin|bccwin|wince|emx/
          res = system "rundll32.exe url.dll,FileProtocolHandler #{document}"
         
          puts "OK" if res
        end

      потом такой, как советовалось в одном форуме, с помощью Thread:
      ExpandedWrap disabled
        document = ARGV[0]
         
        if RUBY_PLATFORM =~ /mswin|mingw|cygwin|bccwin|wince|emx/
          command = Thread.new do
            res = system "rundll32.exe url.dll,FileProtocolHandler #{document}"
          end
          command.join
         
          puts "OK" if res
        end
         
        puts "OK" if res


      Добавлено
      Ruby 1.9.2
        Оффтоп: очевидно, что оба исходных кода идентичны :)

        Добавлено
        Вообще у меня есть подозрение, что виноват rundll, который как раз и не дожидается возврата из ассоциированного приложения.
          Цитата deil @
          оба исходных кода идентичны
          Без Thread.new и с ним. Так что не идентичны.


          Цитата deil @
          у меня есть подозрение, что виноват rundll, который как раз и не дожидается возврата из ассоциированного приложения
          Кстати, проверил сейчас в Линуксе:
          ExpandedWrap disabled
            res=nil; command = Thread.new { res =system "gnome-open list.txt" }; command.join


          Открывается gedit и в консоли тут же сообщается:
          ExpandedWrap disabled
            => #<Thread:0xa030e44 dead>

          и res возвращает "успех".
            Цитата Romtek @
            Цитата deil @
            оба исходных кода идентичны
            Без Thread.new и с ним. Так что не идентичны.


            Цитата deil @
            у меня есть подозрение, что виноват rundll, который как раз и не дожидается возврата из ассоциированного приложения
            Кстати, проверил сейчас в Линуксе:
            ExpandedWrap disabled
              res=nil; command = Thread.new { res =system "gnome-open list.txt" }; command.join


            Открывается gedit и в консоли тут же сообщается:
            ExpandedWrap disabled
              => #<Thread:0xa030e44 dead>

            и res возвращает "успех".

            Вызванный через system процесс мгновенно завершается. Во втором листинге в отдельном потоке вызывается процесс, он мгновенно завершается и поток умирает. Результат выполнения обоих листингов идентичен.
              То что результат выполнения одинаков я и так знаю. Мне бы решить вопрос насчёт синхронного вызова процесса.
              Повсюду пишут, что метод system является синхронным. А значит, он должен дожидаться окончания процесса. Только мне не понять почему это не срабатывает.
                Возможно имеет смысл использовать FFI и дергать напрямую WinAPI-шные функции?

                Например об этом говорят здесь:
                http://habrahabr.ru/post/142172/
                и здесь: http://stackoverflow.com/questions/1107601...dowex-from-ruby

                ЗЫ. В питоне вообще есть pywin32 8-)
                  В общем, написал я экспериментальную proof of concept реализацию на C#, взяв за основу примеры на http://www.dotnetperls.com/process-start
                  . Делает всё как мне и надо, с возвратом кода ошибки (если приложение неудачно закрывается). Позже попробую перевести на WinAPI и затем уже приделать привязку к Руби при помощи FFI или без.
                  Хотя, ещё остаётся вариант вызывать как внешнюю программу системным вызовом. Пока надо подумать как лучше сделать.

                  P.S. В свободное время пытаюсь воплотить разные идеи.
                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                  0 пользователей:


                  Рейтинг@Mail.ru
                  [ Script execution time: 0,0293 ]   [ 15 queries used ]   [ Generated: 8.02.23, 23:34 GMT ]