| Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум на Исходниках.RU > Ruby > [Ruby] Запуск документа ассоциированной программой в Windows |
| Автор: Romtek 09.01.13, 21:11 |
| В Руби программе требуется запустить программу для любого типа документа (mp3, html, pdf, ...) с ожиданием результата от запущенного процесса. Проблема заключается в том, что программа запускает процесс без ожидания окончания процесса, что недопустимо. Хочу контролировать результат успешности выполнения процесса, чтобы потом, в случае успеха, скопировать документ в хранилище. Программа должна работать в Windows (XP и может в других). Пробовал такой вариант: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> 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: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> 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 |
| Автор: deil 10.01.13, 07:43 |
Оффтоп: очевидно, что оба исходных кода идентичны Добавлено Вообще у меня есть подозрение, что виноват rundll, который как раз и не дожидается возврата из ассоциированного приложения. |
| Автор: Romtek 10.01.13, 12:01 |
| Без Thread.new и с ним. Так что не идентичны. Цитата deil @ Кстати, проверил сейчас в Линуксе:у меня есть подозрение, что виноват rundll, который как раз и не дожидается возврата из ассоциированного приложения <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> res=nil; command = Thread.new { res =system "gnome-open list.txt" }; command.join Открывается gedit и в консоли тут же сообщается: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> => #<Thread:0xa030e44 dead> и res возвращает "успех". |
| Автор: deil 15.01.13, 19:28 |
| Цитата Romtek @ Без Thread.new и с ним. Так что не идентичны. Цитата deil @ Кстати, проверил сейчас в Линуксе:у меня есть подозрение, что виноват rundll, который как раз и не дожидается возврата из ассоциированного приложения <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> res=nil; command = Thread.new { res =system "gnome-open list.txt" }; command.join Открывается gedit и в консоли тут же сообщается: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> => #<Thread:0xa030e44 dead> и res возвращает "успех". Вызванный через system процесс мгновенно завершается. Во втором листинге в отдельном потоке вызывается процесс, он мгновенно завершается и поток умирает. Результат выполнения обоих листингов идентичен. |
| Автор: Romtek 15.01.13, 22:42 |
| То что результат выполнения одинаков я и так знаю. Мне бы решить вопрос насчёт синхронного вызова процесса. Повсюду пишут, что метод system является синхронным. А значит, он должен дожидаться окончания процесса. Только мне не понять почему это не срабатывает. |
| Автор: Мяут-Настоящий 16.01.13, 04:56 |
| Возможно имеет смысл использовать FFI и дергать напрямую WinAPI-шные функции? Например об этом говорят здесь: http://habrahabr.ru/post/142172/ и здесь: http://stackoverflow.com/questions/1107601...dowex-from-ruby ЗЫ. В питоне вообще есть pywin32 |
| Автор: Romtek 17.01.13, 10:44 |
| В общем, написал я экспериментальную proof of concept реализацию на C#, взяв за основу примеры на http://www.dotnetperls.com/process-start . Делает всё как мне и надо, с возвратом кода ошибки (если приложение неудачно закрывается). Позже попробую перевести на WinAPI и затем уже приделать привязку к Руби при помощи FFI или без. Хотя, ещё остаётся вариант вызывать как внешнюю программу системным вызовом. Пока надо подумать как лучше сделать. P.S. В свободное время пытаюсь воплотить разные идеи. |