English 中文(简体)
使用 C# 的 Powershell 脚本
原标题:HostException executing Powershell script using C#

我使用 PS 2. 0, VS 2010, C# 调用 Powershell 脚本( PS1 文件) 使用 C# 。

我有这个单位测试 工作很好:

output = UsingPowerShell(@".	est1.ps1, "");
Assert.IsTrue(output.Contains("StringToBeVerifiedInAUnitTest"));

脚本内容 :

=================== test1.ps1 ==========================
$someVariable = "StringToBeVerifiedInAUnitTest" 
$someVariable
=================== End test1.ps1 ==========================

但这次单位测试失败。 我收到错误信息:

" "Cannot 援引此函数,因为当前主机主机不执行此函数"

        output = UsingPowerShell(@".	est2.ps1", "");
        Assert.IsTrue(output.Contains("test2.ps1"));

脚本内容

    =================== test2.ps1 ==========================
$fullPathIncFileName = $MyInvocation.MyCommand.Definition
$currentPath =  $MyInvocation.MyCommand.Path
$currentScriptName = $MyInvocation.MyCommand.Name
$currentExecutingPath = $fullPathIncFileName.Replace($currentScriptName, "")
$scriptDir = Split-Path -parent $MyInvocation.MyCommand.Path

#Write-Host $currentExecutingPath
Write-Host $currentScriptName
Write-Host `r`nRuta: $scriptDir
    =================== End test2.ps1 ==========================

使用 PowerShell 方法 :

public static string UsingPowerShell(string scriptPS, string parametros)
        {
            if (string.IsNullOrWhiteSpace(parametros)) return UsingPowerShell(scriptPS, new List<string> { });
            return UsingPowerShell(scriptPS, parametros.Split(   ));
        }

        public static string UsingPowerShell(string scriptPS, IList<string> parametros)
        {
            var builder = new StringBuilder();
            string answer = null;

            RunspaceConfiguration rsConfig = RunspaceConfiguration.Create();
            InitialSessionState iss = InitialSessionState.CreateDefault();
            using (Runspace runspace = RunspaceFactory.CreateRunspace(iss))
            {
                runspace.Open();

                //runspace.ApartmentState = System.Threading.ApartmentState.STA;
                //runspace.ThreadOptions = PSThreadOptions.UseCurrentThread;

                RunspaceInvoke runSpaceInvoker = new RunspaceInvoke(runspace);
                runSpaceInvoker.Invoke("Set-ExecutionPolicy Unrestricted");

                // create a pipeline and feed it the script text 
                using (Pipeline pipeline = runspace.CreatePipeline())
                {
                    Command command = new Command(scriptPS,true,true);
                    foreach (var param in parametros)
                    {
                        command.Parameters.Add(null, param);
                    }
                    pipeline.Commands.Add(command);

                    //pipeline.Commands.AddScript(cmdArg);
                    //runspace.SessionStateProxy.SetVariable("MyResponse", response);

                    pipeline.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);

                    Collection<PSObject> psresults = pipeline.Invoke();

                    //PSObject newResponse = (PSObject)runspace.SessionStateProxy.GetVariable("MyResponse");

                    //if you want to get a value from a variable in you script like so:
                    //Object resultcollection = runspace.SessionStateProxy.GetVariable("results");

                    // convert the script result into a single string 
                    var sb = new StringBuilder();
                    foreach (PSObject obj in psresults)
                    {
                        sb.AppendLine(obj.ToString());
                    }


                    answer = sb.ToString();
                    Console.WriteLine(answer);
                    //Console.WriteLine(psresults.ToArray()[0].ToString());

                    // check for errors (non-terminating) 
                    if (pipeline.Error.Count > 0)
                    {
                        //iterate over Error PipeLine until end 
                        while (!pipeline.Error.EndOfPipeline)
                        {
                            //read one PSObject off the pipeline 
                            var value = pipeline.Error.Read() as PSObject;
                            if (value != null)
                            {
                                //get the ErrorRecord 
                                var r = value.BaseObject as ErrorRecord;
                                if (r != null)
                                {
                                    //build whatever kind of message your want 
                                    builder.AppendLine(r.InvocationInfo.MyCommand.Name + " : " + r.Exception.Message);
                                    builder.AppendLine(r.InvocationInfo.PositionMessage);
                                    builder.AppendLine(string.Format("+ CategoryInfo: {0}", r.CategoryInfo));
                                    builder.AppendLine(string.Format("+ FullyQualifiedErrorId: {0}", r.FullyQualifiedErrorId));
                                }
                            }
                        }
                        //return builder.ToString();
                    }

                    pipeline.Dispose();
                }

                runspace.Close();
            }

            return answer;

        }

有什么建议吗?

更新:

How Windows PowerShell Works
http://msdn.microsoft.com/en-us/library/ms714658(VS.85).aspx

Windows PowerShell 在一个主机应用程序(默认为 powershell.exe) 中运行,该应用程序向用户披露命令行,并使用主机接口与命令行引用的命令进行沟通。主机应用程序可以是控制台应用程序、 Windows 应用程序或网络应用程序。在大多数情况下,主机应用程序使用其主要功能与 Windows Powershell 内部主机接口进行互动;然而,主机应用程序可以通过实施 PSHost 类和一个或多个相关用户界面类别来选择性地支持自己的自定义主机。这些类别允许应用程序与 Windows PowerShell 命令直接沟通。

最佳回答

您正在使用的电壳主机不支持写入主机 。

一种容易的变通办法是取代:

Write-Host $currentScriptName
Write-Host `r`nRuta: $scriptDir

以:

$currentScriptName
"`r`nRuta: $scriptDir"
问题回答

暂无回答




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签