private PsWrapperParameterBuilder SetPSVariables( IMethodCallMessage methodCall, Type sessionStateProxy, object proxyInstance, string helpMessage) { //get "SetVariable" method which will set all param as variable. MethodInfo methodSetVariable = sessionStateProxy.GetMethod( "SetVariable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, new Type[] { typeof(string), typeof(object) }, null ); if (methodSetVariable == null) { throw new InvalidOperationException("Cannot get 'SetVariable' method from SessionStateProxy."); } //set all properties and help message as variable //which can be used in PowerShell script. //set help message as variable methodSetVariable.Invoke(proxyInstance, new object[] { "PtfHelpMessage", helpMessage }); //set all properties as variables foreach (string key in this.TestSite.Properties.AllKeys) { string propName = "PTFProp" + key; methodSetVariable.Invoke( proxyInstance, new object[] { propName, this.TestSite.Properties[key] } ); } methodSetVariable.Invoke( proxyInstance, new object[] { "MethodName", methodCall.MethodName } ); if (methodCall != null) { //set all parameters as variables which can be used //by users directly in the PowerShell script PsWrapperParameterBuilder builder = new PsWrapperParameterBuilder(methodCall); builder.SetAllParametersAsVariables(methodSetVariable, proxyInstance); return(builder); } return(null); }
private PsWrapperParameterBuilder SetPSVariables( IMethodCallMessage methodCall, Type sessionStateProxy, object proxyInstance, string helpMessage) { //get "SetVariable" method which will set all param as variable. MethodInfo methodSetVariable = sessionStateProxy.GetMethod( "SetVariable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, new Type[] { typeof(string), typeof(object) }, null ); if (methodSetVariable == null) { throw new InvalidOperationException("Cannot get 'SetVariable' method from SessionStateProxy."); } //set all properties and help message as variable //which can be used in PowerShell script. //set help message as variable methodSetVariable.Invoke(proxyInstance, new object[] { "PtfHelpMessage", helpMessage }); //set all properties as variables foreach (string key in this.TestSite.Properties.AllKeys) { string propName = "PTFProp" + key; methodSetVariable.Invoke( proxyInstance, new object[] { propName, this.TestSite.Properties[key] } ); } methodSetVariable.Invoke( proxyInstance, new object[] { "MethodName", methodCall.MethodName} ); if (methodCall != null) { //set all parameters as variables which can be used //by users directly in the PowerShell script PsWrapperParameterBuilder builder = new PsWrapperParameterBuilder(methodCall); builder.SetAllParametersAsVariables(methodSetVariable, proxyInstance); return builder; } return null; }
protected override IMessage Invoke(IMethodCallMessage methodCall) { //get help message from attribute string methodhelp = AdapterProxyHelpers.GetHelpMessage(methodCall); bool compactMode = ((methodCall.MethodName == "Initialize" || methodCall.MethodName == "Reset") && AdapterType.IsAdapterTypeFullName(methodCall.MethodBase.DeclaringType.FullName) ); if (compactMode) { return(InvokeCompact(methodCall, methodhelp)); } object retVal = null; object[] outArgs = methodCall.Args; // Check if this is a method from IAdapter. Any IAdapter methods should be ignored. if (!AdapterType.IsAdapterTypeFullName(methodCall.MethodBase.DeclaringType.FullName) && (methodCall.MethodBase.DeclaringType.FullName != typeof(IDisposable).FullName) ) { TestSite.Log.Add(LogEntryKind.EnterAdapter, "Power Shell adapter: {0}, method: {1}", ProxyType.Name, methodCall.MethodName); try { if (scriptFile == null || !File.Exists(scriptFile)) { TestSite.Assume.Fail( "The invoking Power Shell script file ({0}) can not be found.", scriptFile); } else { PsWrapperParameterBuilder builder = InvokeScript(scriptFile, methodCall, methodhelp); if (builder != null) { retVal = builder.RetValue; if (builder.OutArguments != null) { int argsIndex = 0; int outArgsIndex = 0; foreach (ParameterInfo pi in methodCall.MethodBase.GetParameters()) { if (pi.ParameterType.IsByRef) { outArgs[argsIndex] = builder.OutArguments[outArgsIndex++]; } argsIndex++; } } //clear builder builder = null; } } } catch (Exception ex) { TestSite.Log.Add(LogEntryKind.Debug, ex.ToString()); throw; } finally { TestSite.Log.Add(LogEntryKind.ExitAdapter, "Power Shell adapter: {0}, method: {1}", ProxyType.Name, methodCall.MethodName); } } ReturnMessage mret = new ReturnMessage( retVal, (outArgs != null && outArgs.Length > 0) ? outArgs : null, (outArgs != null) ? outArgs.Length : 0, methodCall.LogicalCallContext, methodCall); return(mret); }
//use reflection to invoke PowerShell script via APIs in System.Management.Automation.dll private PsWrapperParameterBuilder InvokeScript(string path, IMethodCallMessage methodCall, string helpMessage) { //the patameter builder to handle all parameters PsWrapperParameterBuilder builder = null; Assembly sysMgmtAutoAssembly = null; try { sysMgmtAutoAssembly = Assembly.Load(PSConstant.SystemManagementAutomationAssemblyNameV3); } catch { } // If loading System.Management.Automation, Version=3.0.0.0 failed, try Version=1.0.0.0 if (sysMgmtAutoAssembly == null) { try { sysMgmtAutoAssembly = Assembly.Load(PSConstant.SystemManagementAutomationAssemblyNameV1); } catch { throw new InvalidOperationException("Can not find system management automation assembly from GAC." + "Please make sure your PowerShell installation is valid." + "Or you need to reinstall PowerShell."); } } if (sysMgmtAutoAssembly != null) { //use the Dot operation in PowerShell to make all variables can be accessed in whole runspace. string scriptContent = string.Format(". \"{0}\"", Path.GetFullPath(path)); BindingFlags flag = BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod; //call static method, and create the instance of runspace type Type runspaceFactory = GetPSType(sysMgmtAutoAssembly, "System.Management.Automation.Runspaces.RunspaceFactory"); object runspaceInstance = runspaceFactory.InvokeMember( "CreateRunspace", BindingFlags.InvokeMethod, null, null, null); //open run space Type runspace = GetPSType(sysMgmtAutoAssembly, "System.Management.Automation.Runspaces.Runspace"); runspace.InvokeMember("Open", flag, null, runspaceInstance, null); //call runspace.CreatePipeline to create an instance of Pipeline Type pipeline = GetPSType(sysMgmtAutoAssembly, "System.Management.Automation.Runspaces.Pipeline"); object pipelineInstance = runspace.InvokeMember( "CreatePipeline", flag, null, runspaceInstance, null); //get the Commands property of the pipeline instance object commandsInstance = pipeline.InvokeMember( "Commands", BindingFlags.GetProperty, null, pipelineInstance, null); //add commands to invoke script Type commands = GetPSType(sysMgmtAutoAssembly, "System.Management.Automation.Runspaces.CommandCollection"); commands.InvokeMember( "AddScript", flag, null, commandsInstance, new object[] { scriptContent }); //get "SessionStateProxy" instance from runspace Type sessionStateProxy = GetPSType(sysMgmtAutoAssembly, "System.Management.Automation.Runspaces.SessionStateProxy"); object proxyInstance = runspace.InvokeMember( "SessionStateProxy", BindingFlags.GetProperty, null, runspaceInstance, null); //set variables which can be used in PowerShell script builder = SetPSVariables(methodCall, sessionStateProxy, proxyInstance, helpMessage); try { if (builder != null) { //invoke script and get the return value and out/ref parameters if (builder.HasRetValue) { object returnValueCollection = pipeline.InvokeMember("Invoke", flag, null, pipelineInstance, null); Type psObject = GetPSType(sysMgmtAutoAssembly, "System.Management.Automation.PSObject"); //get return value object KeyValuePair <string, object> retValue = this.GetRetValueFromCollection(returnValueCollection, psObject); if (retValue.Value != null) { if (builder.RetType.IsInstanceOfType(retValue.Value)) { builder.RetValue = retValue.Value; } else { throw new InvalidOperationException("The returned type is mismatched"); } } else { builder.RetValue = null; } } else { pipeline.InvokeMember("Invoke", flag, null, pipelineInstance, null); } //get out parameters values builder.GetAllOutParameterValues( sysMgmtAutoAssembly, sessionStateProxy, proxyInstance, methodCall.MethodBase.GetParameters().Length); } else { pipeline.InvokeMember("Invoke", flag, null, pipelineInstance, null); } //check errors in the error pipeline CheckErrorsInPipeline(sysMgmtAutoAssembly, pipeline, pipelineInstance); } catch (TargetInvocationException ex) { string innerException = string.Empty; string traceInfo = string.Empty; Exception e = ex as Exception; if (null != e.InnerException) { innerException = e.InnerException.Message; traceInfo = GetPSScriptPositionMessage(sysMgmtAutoAssembly, e.InnerException); } string ptfAdFailureMessage = string.Format( "Exception thrown. InnerException: {1} {2}", path, innerException, traceInfo); throw new InvalidOperationException(ptfAdFailureMessage); } //close runspace and release resources runspace.InvokeMember("Close", flag, null, runspaceInstance, null); } else { throw new InvalidOperationException("Can not find system management automation assembly from GAC." + "Please make sure your PowerShell installation is valid." + "Or you need to reinstall PowerShell."); } return(builder); }