使用Ocra编译Ruby脚本为exe后,运行时弹出控制台窗口如何解决?
解决Ocra编译Ruby程序后运行时反复弹出控制台窗口的问题
问题根源
你主程序用--windows参数编译成窗口程序后,主进程不会弹出控制台,但调用taskkill时用了system、%x()这类默认创建控制台窗口的执行方法,子进程的控制台就会反复弹出。
实用解决方法
方法1:用Windows原生API创建无窗口进程
直接调用kernel32的API来隐藏子进程窗口,不需要额外依赖:
require 'win32api' require 'json' class Taskkill def self.kill_processes processes = JSON.parse(File.read('config/tlist.json')) processes.each do |proc_name| cmd = "taskkill /F /IM #{proc_name}" # 初始化API调用所需的结构 create_process = Win32API.new('kernel32', 'CreateProcessA', ['P', 'P', 'P', 'P', 'I', 'L', 'P', 'P', 'P', 'P'], 'I') startup_info = [0].pack('L') * 10 process_info = [0].pack('L') * 2 # 设置窗口隐藏标记 startup_info[0...4] = [0x1].pack('L') # STARTF_USESHOWWINDOW startup_info[44...48] = [0].pack('L') # SW_HIDE # 执行命令 create_process.call(nil, cmd, nil, nil, 0, 0x08000000, nil, nil, startup_info, process_info) # 清理句柄 close_handle = Win32API.new('kernel32', 'CloseHandle', ['P'], 'I') pid, h_thread = process_info.unpack('LL') close_handle.call(h_thread) close_handle.call(pid) end end end
方法2:用win32-process gem简化代码
这个gem封装了Windows进程操作,代码更简洁:
- 先安装依赖:
gem install win32-process
- 修改Taskkill类:
require 'win32/process' require 'json' class Taskkill def self.kill_processes processes = JSON.parse(File.read('config/tlist.json')) processes.each do |proc_name| cmd = "taskkill /F /IM #{proc_name}" # 以无窗口模式执行命令 Process.create( command_line: cmd, creation_flags: Process::CREATE_NO_WINDOW ) end end end
方法3:确认编译参数有效性
你已经加了--windows参数,这一步主要是排除参数遗漏:确保编译命令里的--windows没有拼写错误,它的作用是让主Ruby进程以窗口模式启动,不弹出主控制台,但子进程的窗口问题还是要靠上面的代码解决。
验证步骤
修改代码后,用你原来的编译命令重新打包:
ocra "c:\Users\usr\my_file_path\my_rb_script.rb" --dll ruby_builtin_dlls/libgmp-10.dll --icon ./resources/mdr256.ico --windows
运行新生成的exe,控制台窗口就不会再弹出了。
内容的提问来源于stack exchange,提问作者HannahLovesAna
相关产品推荐
相关产品推荐

