簡體   English   中英

在 PS 腳本中將 powershell 變量傳遞給 C# 代碼

[英]passing powershell variables to C# code within PS script

我閱讀了很多關於將變量從 C# 傳遞到 powershell 腳本的內容,但我對其他方式感興趣。

在這里,我有這段代碼可以在我的 powershell 腳本中創建一個類型:

Add-Type @'

public class Node
{

    public string Type;
    public string VM_Name;
    public string VM_IP;
    public string Hostname;

}
'@

$vm1 = New-Object Node
$vm2 = New-Object Node
$vm3 = New-Object Node
$vm4 = New-Object Node

在這段代碼之后,我有 C# 代碼:

$sourceCode = @'


public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void InitializeComponent()
    {
    }
}

'@

我如何才能在上面的 C# 代碼中訪問 $vm1,2,3,4 ?

您可以通過 C# 類中的方法將變量傳遞到類型中,該方法將接受變量作為參數,例如:

$form = new-object Form1
$form.SetVariables($vm1, $vm2, $vm3, $vm4)

我推薦這種方法。

另一種選擇(較重且未經測試)是嘗試從 C# 代碼訪問當前運行空間,例如:

var defRunspace = System.Management.Automation.Runspaces.Runspace.DefaultRunspace;
var pipeline = defRunspace.CreateNestedPipeline();
pipeline.Commands.AddScript("$vm1,$vm2,$vm3,$vm4");
var results = pipeline.Invoke();
var vm1 = results[0];
var vm2 = results[1];
...

我還沒有從 C# 代碼(僅在 PowerShell 中)嘗試過這個,所以我不能 100% 確定它會起作用。

將變量傳遞給在 Powershell 內運行的 C# 腳本的一種方法是使用 HttpListener(監視本地主機端口)來收集內容類型。 Content-Type 字段最多可以包含 16,000 個字符,我用它來防止您機器上的同事使用瀏覽器創建虛假輸入。

此處顯示的偵聽器位於獨立的 Powershell 腳本中:

Add-Type -TypeDefinition @'

using System;
using System.Threading.Tasks;
using System.Net;
using System.Windows.Forms;

namespace LocalHostListener
{
    public class Program
    {
        HttpListener listener = new HttpListener();

            public static void Main(string[] args)
            {
                    Program program = new Program();
                    program.Start(args[0]);
            }

            public void Start(string url_)
            {
                    listener.Prefixes.Add(url_);
                    listener.Start();
                    listener.BeginGetContext(new AsyncCallback(GetContextCallback), null);
                    Console.ReadLine();
                    listener.Stop();
            }

            public void GetContextCallback(IAsyncResult result)
            {
            HttpListenerContext context = listener.EndGetContext(result);
            HttpListenerRequest request = context.Request;
            HttpListenerResponse response = context.Response;

            Task.Factory.StartNew(() => 
            {
                // KICK OFF YOUR UPDATE ACTIONS HERE (THE LENGTH FILTER EXCLUDES BROWSER CALLS)
                if(request.ContentType.Length>0) yourAction(request.ContentType);
            });

                // SEND A RESPONSE TO KEEP POWERSHELL Invoke-WebRequest,
                // BROWSERS AND VBS MSXML2.XMLHTTP.6.0 HAPPY
                // (C# HttpWebRequest DOESN'T CARE)
                    response.ContentLength64 = 1;
            response.OutputStream.WriteByte(Convert.ToByte('!'));

                    listener.BeginGetContext(new AsyncCallback(GetContextCallback), null);
            }

        public void yourAction(string update)
        {
            Console.WriteLine(update); 
            MessageBox.Show(new Form(), update,"Message from localhost feed",
             MessageBoxButtons.OK,MessageBoxIcon.None,
               MessageBoxDefaultButton.Button1,(MessageBoxOptions)0x40000);
        }
    }
}

'@ -Language CSharp -ReferencedAssemblies System.Windows.Forms

$Host.UI.RawUI.WindowTitle='Monitoring "Content-Type" on http://localhost:1959'
[LocalHostListener.Program]::Main('http://localhost:1959/')

然后,您可以使用 Powershell WebRequest 更新偵聽器:

Invoke-WebRequest -ContentType 'Your message here' -URI http://localhost:1959

還可以使用 C# 發送器將更新發送到偵聽器,該發送器使用您的變量設置 Content-Type(同樣,此處顯示為獨立 Powershell 腳本):

Add-Type -TypeDefinition @'

using System;
using System.Net;

namespace LocalHostSender
{
    public class Program
    {
        public static void Main(string[] args)
        {
            try{
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:1959");
                    request.ContentType = args[0];
                    request.Timeout = 200;
                    request.GetResponse();          
            }catch{}
        }
    }
}

'@ -Language CSharp -ReferencedAssemblies System.Net

[LocalHostSender.Program]::Main("Your message here")

如果僅使用 C# 發送器,則可以刪除偵聽器腳本的響應部分。

這種方法的另一個優點是 VBS 腳本還可以更新 Content-Type:

text_ = "Your message here"

Randomize
Set req = CreateObject("MSXML2.XMLHTTP.6.0")
req.open "GET", "http://localhost:1959/" & rnd, False
req.setRequestHeader "Content-Type", text_
req.send
'req.responseText

如果您想循環多個請求,則需要對頁面請求進行隨機添加,因為 MSXML2.XMLHTTP.6.0 不會在相同的頁面請求上發送 Content-Type 信息。

如果您確實想要瀏覽器/HTML 訪問,您可以使用以下方法在偵聽器中收集頁面請求:

string simplePageRequest_ = request.Url;
//Parsing "favicon.ico" and "http://localhost:1959/"

string pageQuery_ = request.QueryString["q"];

通過瀏覽器頁面請求更新,或再次使用 Powershell WebRequest:

Invoke-WebRequest 'http://localhost:1959/Your message here'
Invoke-WebRequest 'http://localhost:1959/?q=Your message here'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM