Files
gtav-src/tools_ng/bin/ironruby/Samples/IRPowerShell/powershell.rb
T
2025-09-29 00:52:08 +02:00

208 lines
4.9 KiB
Ruby
Executable File

#####################################################################################
#
# Copyright (c) Microsoft Corporation. All rights reserved.
#
# This source code is subject to terms and conditions of the Apache License, Version 2.0. A
# copy of the license can be found in the License.html file at the root of this distribution. If
# you cannot locate the Apache License, Version 2.0, please send an email to
# ironpy@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
# by the terms of the Apache License, Version 2.0.
#
# You must not remove this notice, or any other, from this software.
#
#
#####################################################################################
require 'mscorlib'
require 'System.Management.Automation'
include System
include System::Management::Automation
include System::Management::Automation::Host
include System::Management::Automation::Runspaces
$runspace = RunspaceFactory.create_runspace
$runspace.open
$intrinsics = $runspace.session_state_proxy.get_variable("ExecutionContext")
class Object
def pop_arg_hash(args)
result = args.last.is_a?(Hash) ? args.pop : {}
return result, args
end
end
module PowerShell
=begin
Utility function converts a string, name, to lowercase.
Also replaces hyphens with underscores.
=end
def translate(name)
name.downcase.gsub(/-/,"_")
end
=begin
Utility function converts arg (of type string, PSObject, or
ShellOutput) to type string.
=end
def fix_arg(arg)
case arg
when String
$intrinsics.invoke_command.expand_string(arg)
when PSObject
arg
when ShellOutput
arg.data
else
arg
end
end
=begin
Used to actually invoke a powershell command
=end
def invoke_command(cmd_name, input = nil, *args)
arg_hash, args = pop_arg_hash(args)
cmd = Command.new(cmd_name)
args.each {|arg| cmd.parameters.add(CommandParameter.new(nil, fix_arg(arg)))}
arg_hash.each {|key, value| cmd.parameters.add(CommandParameter.new(key.to_s, fix_arg(value)))}
#Create a pipeline to run the command within and invoke
#the command.
pipeline = $runspace.create_pipeline
pipeline.commands.add(cmd)
ret = if input
pipeline.invoke(fix_arg(input))
else
pipeline.invoke
end
#return the output of the command formatted special
#using the ShellOutput class
ShellOutput.new(ret)
end
end
=begin
Instances of this class are like pseudo PowerShell
shells. That is, this class essentially has a method for
each PowerShell command available.
=end
class Shell
def initialize(data)
@data = data
end
def method_missing(sym, *args, &block)
if @data[sym.to_s]
return @data[sym.to_s].call(*args, &block)
end
raise NoMethodError(sym, *args, &block)
end
end
=begin
Wrapper class for shell commands
=end
class ShellCommand
include PowerShell
attr_accessor :input
def initialize(name, input=nil)
@name = name
@input = input
end
def call(*args)
invoke_command(@name, @input, *args)
end
def to_s
"#<ShellCommand #{@name}>"
end
end
class ShellOutput
attr_accessor :data
def initialize(data)
@data = data
end
def self.[]=(name, value)
define_method(name) do |*args|
input, value.input = value.input, self
result = value.call(*args)
value.input = input
result
end
end
def each
@data.each {|el| yield el}
end
def length
@data.count
end
def inspect
return "" if @data.count.zero?
out_string(:Width => (System::Console.BufferWidth-1))[0].to_s.strip
end
alias_method :to_s, :inspect
def [](key)
@data[key]
end
end
class PSObject
def method_missing(sym, *args, &block)
member = members[sym.to_s]
if member
result = member.value
if result.is_a? PSMethod
result = result.invoke(*args)
end
result
else
raise NoMethodError.new(sym, *args, &block)
end
end
def inspect
members["ToString"].invoke
end
alias_method :to_s, :inspect
end
class Program
include PowerShell
def initialize
@cmds = {}
invoke_command('get-command').each do |cmdlet|
@cmds[translate(cmdlet.name)] = ShellCommand.new cmdlet.name
end
invoke_command('get-alias').each do |al|
cmd_name = translate(al.get_ReferencedCommand.name)
if @cmds.include? cmd_name
@cmds[translate(al.name)] = @cmds[cmd_name]
end
end
$shell = Shell.new @cmds
@cmds.each {|key, value| ShellOutput[key] = value }
end
end
Program.new
if __FILE__ != $0
puts <<EOL
Run '$shell.instance_variables' to get a list of available PowerShell commands!
In general, IronRuby PowerShell commands are accessed using the form:
$shell.get_process("cmd")
EOL
end