在PS脚本中将powershell变量传递给C#代码
我读了很多关于将变量从C#传递到powershell脚本的文章,但我对另一方面很感兴趣 下面是我在powershell脚本中创建类型的代码:在PS脚本中将powershell变量传递给C#代码,c#,powershell,C#,Powershell,我读了很多关于将变量从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-
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
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/')
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#代码:
如何访问上述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(监视本地主机端口)来获取内容类型。“内容类型”字段最多可以包含16000个字符,我使用它来防止计算机上的同事使用浏览器创建虚假输入 此处显示的侦听器位于独立的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
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/')
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")
然后,您可以使用Powershell WebRequest更新侦听器:
Invoke-WebRequest -ContentType 'Your message here' -URI http://localhost:1959
Invoke-WebRequest 'http://localhost:1959/Your message here'
Invoke-WebRequest 'http://localhost:1959/?q=Your message here'
还可以使用C#发送器将更新发送给侦听器,该发送器使用变量设置内容类型(同样,在独立的Powershell脚本中显示):
如果只使用C#发送方,则可以删除侦听器脚本的响应部分
此方法的另一个优点是VBS脚本还可以更新内容类型:
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不会在相同的页面请求上发送内容类型信息
如果确实需要浏览器/HTML访问,可以使用以下方法在侦听器中获取页面请求:
string simplePageRequest_ = request.Url;
//Parsing "favicon.ico" and "http://localhost:1959/"
string pageQuery_ = request.QueryString["q"];
通过浏览器页面请求或再次使用Powershell WebRequest更新:
Invoke-WebRequest -ContentType 'Your message here' -URI http://localhost:1959
Invoke-WebRequest 'http://localhost:1959/Your message here'
Invoke-WebRequest 'http://localhost:1959/?q=Your message here'