我试图从ruby代码执行powershell命令。 Get-WmiObject -Class Win32_Product -ComputerName。 -Filter“Name ='Qlik Sense Client'”| Select-Object -Property version
它完美地给了我产品的版本。但是当我尝试从ruby执行时(在反引号中的整个命令)同样的事情:
find = powershell.exe Get-WmiObject -Class Win32_Product -ComputerName . -Filter "Name=''"|Select-Object -Property version
命令中断,它无法解释红宝石中的引号,管道等。我试图逃避这些引用,但它仍然打破了。我也不知道如何逃脱这条管道。 请在这里帮助我或推荐我相关的东西。非常感谢。
答案 0 :(得分:4)
我现在已经测试了这个:
require 'base64'
cmd = %{Get-WmiObject -Class Win32_Product -ComputerName . -Filter "Name='Qlik Sense Client'"|Select-Object -Property version}
encoded_cmd = Base64.strict_encode64(cmd.encode('utf-16le'))
find = `powershell.exe -encodedCommand #{encoded_cmd}`
Powershell期望使用UTF-16LE编码的字符串,因此您必须在base64转换之前从Ruby的编码(UTF-8)进行转换。
或者,您可以尝试使用shellwords中的shellescape
来转义命令,以便shell将其解释为单个字符串。
另一种方法是将powershell.exe -Command -
与popen3一起使用。这将允许您编写命令并使用文件流读取其结果。
答案 1 :(得分:0)
这里有一个关于我如何对外部应用程序进行shell的示例,也应该与Powershell一起使用。在没有额外分隔符的{}之间从控制台复制工作命令。 %Q还可以在您的命令不总是相同的情况下进行变量插值,它的工作方式与“分隔符”之间的工作方式相同。
所有输出都由" 2>&1"
捕获,并在while之后逐行枚举。
如果捕获了多行,您需要检查显示的结果是哪一行并返回结果。
def powershell
command = %Q{your command just like you execute it in a console}
IO.popen(command+" 2>&1") do |pipe|
pipe.sync = true
while lijn = pipe.gets
# do whatever you need with the output of the command
# return the result
end
end
end
如果您不需要插值,请使用%q {}替代方法,因为这也会产生问题。在获得PowerShell结果的同一控制台中使用Ruby comamnd。确保您可以从那里运行powershell(必须在路径中)。
但据我所知,这将为您提供电脑上已安装产品的名称和版本。
为什么不只使用Ruby?它比非常慢的Wmi查询更快。
require 'win32/registry'
Win32::Registry::HKEY_LOCAL_MACHINE.open(
'Software\Microsoft\Windows\CurrentVersion\Uninstall'
) do |reg|
reg.each_key do |key|
k = reg.open(key)
puts key
puts k["DisplayName"] rescue "?"
puts k["DisplayVersion"] rescue "?"
puts
end
end