src/programFrames/DllExport.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using RGiesecke.DllExport;
using System.Runtime.InteropServices;
using System.Threading;
 
namespace PSRunnerNS {
    partial static class PSRunnerEntry {
 
        private static readonly object _lock = new object(); // 用于线程同步
 
        // DllInitChecker
        [$threadingModelThread]
        public static void DllInitChecker() {
            lock (_lock) {
                if (!PSRunner.Inited) {
                    PSRunner.BaseInit();
                    me = new PSRunner(); // 创建 PSRunner 实例
 
                    // 执行初始化脚本(如果需要)
                    PSDataCollection<PSObject> colOutput = new PSDataCollection<PSObject>();
 
                    IAsyncResult asyncResult = me.pwsh.BeginInvoke<PSObject, PSObject>(null, colOutput);
 
                    // 使用 ManualResetEvent 等待 PowerShell 执行完成
                    using (ManualResetEvent mre = new ManualResetEvent(false)) {
                        ThreadPool.QueueUserWorkItem(_ => {
                            try {
                                foreach (PSObject outputItem in colOutput)
                                    Console.WriteLine(outputItem.ToString());
                                foreach (ErrorRecord errorItem in me.pwsh.Streams.Error)
                                    me.ui.WriteErrorRecord(errorItem);
 
                                if (me.pwsh.InvocationStateInfo.State == PSInvocationState.Failed) {
                                    me.ExitCode = 1;
                                    me.ui.WriteErrorLine("DllInitChecker failed: " + me.pwsh.InvocationStateInfo.Reason.Message);
                                }
                            }
                            finally {
                                mre.Set();
                            }
 
                        });
                        mre.WaitOne();
                        me.pwsh.EndInvoke(asyncResult);
                    }
 
                    PSRunner.Inited = true; // 标记为已初始化
                }
            }
        }
        [DllExport("DllExportExample", CallingConvention = CallingConvention.StdCall)]
        public static object DllExportExample(int a, int b) { // 返回类型改为 object
            DllInitChecker();
            object result = null;
            lock (_lock) {
                if (me.ShouldExit)
                    throw new InvalidOperationException("PSRunner is exiting."); // 更合适的异常
 
                //set parameters as variables in psrunspace
                me.PSRunSpace.SessionStateProxy.SetVariable("PSEXEDLLCallIngParameters", new ArrayList { a, b });
                me.pwsh.Commands.Clear(); // 清除之前的命令
                me.pwsh.AddScript("DllExportExample @PSEXEDLLCallIngParameters");
 
                PSDataCollection<PSObject> colOutput = new PSDataCollection<PSObject>();
                IAsyncResult asyncResult = me.pwsh.BeginInvoke<PSObject, PSObject>(null, colOutput);
 
                // 使用 ManualResetEvent 等待 PowerShell 执行完成
                using (ManualResetEvent mre = new ManualResetEvent(false)) {
                    ThreadPool.QueueUserWorkItem(_ => {
                        try {
                            foreach (PSObject outputItem in colOutput)
                                Console.WriteLine(outputItem.ToString());
                            foreach (ErrorRecord errorItem in me.pwsh.Streams.Error)
                                me.ui.WriteErrorRecord(errorItem);
 
                            if (me.pwsh.InvocationStateInfo.State == PSInvocationState.Failed)
                                throw new InvalidOperationException("DllExportExample failed: " + me.pwsh.InvocationStateInfo.Reason.Message);
                        }
                        finally {
                            mre.Set();
                        }
                    });
 
                    mre.WaitOne(); // 等待输出处理完成
                    me.pwsh.EndInvoke(asyncResult);
                }
 
                //处理返回值
                if (colOutput.Count == 1)
                    result = colOutput[0].BaseObject; //返回实际的值, 而不是PSObject
                else if (colOutput.Count > 1)
                    result = colOutput.ToArray(); // 如果有多个输出,返回 PSObject 数组
            }
 
            return result;
        }
    }
}