我已经编写了一个Powershell cmdlet,该cmdlet使用C#使用一些DLL。 WebsocketSharp 以及Newtonsoft JSON。
应该将json字符串发送到websocket服务器,然后将回复返回到Out-File,或者用作另一个上下文中的变量,即
$varWithReply = Send-Cmd("ws://websocket-server.com/","mycommand")
function Send-Cmd
{
[CmdletBinding()]
Param (
[Parameter(Mandatory = $True)]
[string]$WSEndpointUrl,
[Parameter(Mandatory = $True)]
[string]$Command
)
try
{
Add-Type -Path ".\websocket-sharp.dll"
Add-Type -Path ".\Newtonsoft.Json.dll"
}
catch [System.Reflection.ReflectionTypeLoadException]
{
Write-Host "Message: $($_.Exception.Message)"
Write-Host "StackTrace: $($_.Exception.StackTrace)"
Write-Host "LoaderExceptions: $($_.Exception.LoaderExceptions)"
}
$CurrentlyLoadedAssemblies = [System.AppDomain]::CurrentDomain.GetAssemblies()
$AssembiesFullInfo = $CurrentlyLoadedAssemblies | Where-Object {
$_.GetName().Name -eq "Microsoft.CSharp" -or
$_.GetName().Name -eq "mscorlib" -or
$_.GetName().Name -eq "System" -or
$_.GetName().Name -eq "System.Collections" -or
$_.GetName().Name -eq "System.Core" -or
$_.GetName().Name -eq "System.IO" -or
$_.GetName().Name -eq "System.Linq" -or
$_.GetName().Name -eq "System.Runtime" -or
$_.GetName().Name -eq "System.Runtime.Extensions" -or
$_.GetName().Name -eq "System.Runtime.InteropServices" -or
$_.GetName().Name -eq "System.Threading" -or
$_.GetName().Name -eq "websocket-sharp" -or
$_.GetName().Name -eq "Newtonsoft.Json"
}
$AssembiesFullInfo = $AssembiesFullInfo | Where-Object {$_.IsDynamic -eq $False}
$ReferencedAssemblies = $AssembiesFullInfo.FullName | Sort-Object | Get-Unique
$usingStatementsAsString = @"
using Microsoft.CSharp;
using System.Collections.Generic;
using System.Collections;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime;
using System.Threading;
using System;
using WebSocketSharp;
using System.Net.WebSockets;
using Newtonsoft.Json;
"@
$TypeDefinition = @"
$usingStatementsAsString
namespace MyCore.Utils
{
public class WebSocketClient
{
public static void StartWSSession(string url, string cmd)
{
using (var ws = new WebSocketSharp.WebSocket(url))
{
int received = 0;
// Set the WebSocket events.
ws.OnOpen += (sender, e) =>
{
Response jsonmsg = new Response();
jsonmsg.Identifier = 2000;
jsonmsg.Message = cmd;
jsonmsg.Name = "PowershellWS";
string output = JsonConvert.SerializeObject(jsonmsg);
ws.Send(output);
};
ws.OnMessage += (sender, e) => {
Response response = JsonConvert.DeserializeObject<Response>(e.Data);
if (response.Identifier == 2000) {
Console.WriteLine(response.Message);
received ++;
ws.Close();
}
};
ws.OnError += (sender, e) =>
Console.WriteLine(e.Message);
ws.OnClose += (sender, e) =>
Console.WriteLine(e.Reason);
// Connect to the server.
ws.Connect();
while (received < 1){Thread.Sleep(1);}
}
}
}
internal class Response
{
[JsonProperty(PropertyName = "Identifier")]
public int Identifier { get; set; }
[JsonProperty(PropertyName = "Message")]
public string Message { get; set; }
[JsonProperty(PropertyName = "Name")]
public string Name { get; set; }
}
}
"@
Add-Type -ReferencedAssemblies $ReferencedAssemblies -TypeDefinition $TypeDefinition
return [MyCore.Utils.WebsocketClient]::StartWSSession($WSEndpointUrl,$Command)
}
我尝试过
$varWithReply = Send-Cmd("ws://websocket-server.com/","mycommand")
Send-Cmd("ws://websocket-server.com/","mycommand") | Out-File .\output.txt
但是我什么也没得到。 这是因为C#控制台行流是独立的吗?我将如何解决这个问题?
答案 0 :(得分:1)
所以...看起来我犯了C#新秀错误。 谢谢@ H.G。 Sandhagen可为您的评论指明正确的方向。
namespace MyCore.Utils
{
public class WebSocketClient
{
public static string StartWSSession(string url, string cmd)
{
string reply = null;
using (var ws = new WebSocketSharp.WebSocket(url))
{
int received = 0;
// Set the WebSocket events.
ws.OnOpen += (sender, e) =>
{
Response jsonmsg = new Response();
jsonmsg.Identifier = 2000;
jsonmsg.Message = cmd;
jsonmsg.Name = "PowershellWS";
string output = JsonConvert.SerializeObject(jsonmsg);
ws.Send(output);
};
ws.OnMessage += (sender, e) => {
Response response = JsonConvert.DeserializeObject<Response>(e.Data);
if (response.Identifier == 2000) {
Console.WriteLine(response.Message);
reply = response.Message;
received ++;
ws.Close();
}
};
ws.OnError += (sender, e) =>
Console.WriteLine(e.Message);
ws.OnClose += (sender, e) =>
Console.WriteLine(e.Reason);
// Connect to the server.
ws.Connect();
while (received < 1){Thread.Sleep(1);}
}
return reply;
}
}
internal class Response
{
[JsonProperty(PropertyName = "Identifier")]
public int Identifier { get; set; }
[JsonProperty(PropertyName = "Message")]
public string Message { get; set; }
[JsonProperty(PropertyName = "Name")]
public string Name { get; set; }
}
}
我认为PS是理所当然的,现在对返回的变量使用返回值,因此它实际上返回一个值,并且函数本身不能为空,因为这意味着它根本不返回任何内容,因此必须成为“字符串”