A way to pass variables to C# scripts running inside Powershell is to use an HttpListener (monitoring a localhost port) that harvests the Content-Type. The Content-Type field can take up to 16,000 characters, and I used it to prevent colleagues on your machine using a browser to create spurious input.
The listener shown here is in a stand-alone Powershell script:
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/')
You can then update the listener using the Powershell WebRequest:
Invoke-WebRequest -ContentType 'Your message here' -URI http://localhost:1959
Updates can also be sent to the listener using a C# sender that sets the Content-Type with your variables (again, shown here in a stand-alone Powershell script):
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")
The response section of the listener script can be removed if only the C# sender is used.
Another advantage with this method is that VBS scripts can also update the 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
The random addition to the page request is required if you want to loop multiple requests, as MSXML2.XMLHTTP.6.0 doesn't send Content-Type information on identical page requests.
If you actually wanted browser/HTML access you could harvest the page requests in the listener using:
string simplePageRequest_ = request.Url;
//Parsing "favicon.ico" and "http://localhost:1959/"
string pageQuery_ = request.QueryString["q"];
updating via the browser page requests, or again using the Powershell WebRequest:
Invoke-WebRequest 'http://localhost:1959/Your message here'
Invoke-WebRequest 'http://localhost:1959/?q=Your message here'