powershell cmdlet中的C#代码未输出值



我写了一个使用C#的dll的powershell cmdletWebSocketSharp和Newtonsoft JSON。

应该将JSON字符串发送到WebSocket服务器,然后将答复返回到外文件中,或在其他上下文中用作变量,即

$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#控制台线流是独立的吗?我将如何解决此问题?

所以...看起来我犯了一个菜单错误。谢谢 @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是理所当然的,现在使用我做出的变量回复的回报,因此它实际上返回一个值,并且功能本身不能无效,因为这意味着它根本没有返回任何内容,必须成为"字符串"

最新更新