0

私は使用しています:

- Ruby 1.9.3-p448
- Windows Server 2008

プログラムで使用されるコマンドを含むファイルがあり、この方法で使用しています

C:\> PATH_TO_FOLDER/program.exe file.txt

File.txtいくつかのコマンドがあるのでprogram.exe、次のことを行います:

- Execute commands 
- Reads from a DB using an ODBC method used by program
- Outputs result in a txt file

powershell を使用すると、このコマンドは正常に機能し、期待どおりに機能します。

今、私はこれをファイル ( app.rb) に持っています:

require 'sinatra'
require 'open3'

get '/process' do
  program_path = "path to program.exe"
  file_name = "file.txt"
  Open3.popen3(program_path, file_name) do |i, o, e, w|
    # I have some commands here to execute but just as an example I'm using o.read
    puts o.read
  end
end

にアクセスしてこれを使用する場合、これを行うことhttp://localhost/processOpen3機能します(100%確信はありませんが、何度か試した後、これが唯一のオプションだと思います)

  • コマンドを読み取り、実行します (これで問題ありません)。

  • ODBCメソッドを使用してDBから読み取ろうとします(これが私の問題です。Open3ブラウザーで表示できるように出力を受け取る必要がありますが、読み取ろうとするとOpen3、認識していない別のプロセスが開始されると思います。 Open3 は進行し、それを待たずに終了します)

  • 出口

出口

私は次のことを発見しました:

  • プロセスが終了するのを待つためにThread.join(この場合は) を使用しますが、機能しませんw.join
  • Open4子プロセスを処理しているようですが、Windows では動作しません
  • Process.wait(pid)、この場合pid = w.pidは 、また機能しません
  • Timeout.timeout(n)、ここでの問題は、どれくらい時間がかかるかわからないことです。

これを処理する方法はありますか?(サブプロセスを待ってOpen3いるので、適切な出力が得られます)。

4

2 に答える 2

0

終了ステータスを取得する際にも同様の問題があり、これが私たちがしたことです

Open3.popen3(*cmd) do |stdin, stdout, stderr, wait_thr|

  # print stdout and stderr as it comes in
  threads = [stdout, stderr].collect do |output|
    Thread.new do
      while ((line = output.gets rescue '') != nil) do
        unless line.blank?
          puts line
        end
      end
    end
  end

  # get exit code as a Process::Status object
  process_status = wait_thr.value #.exitstatus

  # wait for logging threads to finish before continuing
  # so we don't lose any logging output
  threads.each(&:join)

  # wait up to 5 minutes to make sure the process has really exited
  Timeout::timeout(300) do
    while !process_status.exited?
      sleep(1)
    end
  end rescue nil

  process_status.exitstatus.to_i
end
于 2014-10-28T22:25:59.287 に答える