无法使用 HTML 使 PowerShell COM 中的 C# 可见

问题描述 投票:0回答:1

我正在制作一个网络应用程序,每当 COM(组件对象模型)不可见时,它就会关闭计算机

异常设置“ObjectForScripting”:“ObjectForScripting 的类必须对 COM 可见。验证该对象是否是 public,或者考虑将 ComVisible 属性添加到您的类中。” 在 C:\Users\kayde\window.ps1:99 字符:1

  • $webBrowser.ObjectForScripting = $scriptBlock
  •   + CategoryInfo          : NotSpecified: (:) [], SetValueInvocationException
      + FullyQualifiedErrorId : ExceptionWhenSetting
    

我尝试使用 C#:

Add-Type -AssemblyName System.Windows.Forms

# Define the .NET class directly in PowerShell with ComVisible attribute
$scriptBlock = {
    Add-Type @"
    using System;
    using System.Runtime.InteropServices;

    [ComVisible(true)]
    public class ActionHandler
    {
        public void HandleAction(string action)
        {
            switch (action)
            {
                case "PowerOff":
                    System.Diagnostics.Process.Start("shutdown.exe", "/s /f /t 0");
                    break;
                case "Reboot":
                    System.Diagnostics.Process.Start("shutdown.exe", "/r /f /t 0");
                    break;
                case "Restart":
                    System.Diagnostics.Process.Start("shutdown.exe", "/r /f /t 0");
                    break;
            }
        }
    }
"@ -PassThru
}

# Create the form
$form = New-Object System.Windows.Forms.Form
$form.Text = "Power options"
$form.MaximumSize = New-Object System.Drawing.Size(300, 240)
$form.Size = New-Object System.Drawing.Size(250, 180) 
$form.MinimumSize = New-Object System.Drawing.Size(250, 180)
$form.ShowIcon = $false

# Create the WebBrowser control
$webBrowser = New-Object System.Windows.Forms.WebBrowser
$webBrowser.Dock = [System.Windows.Forms.DockStyle]::Fill

# Load HTML content into the WebBrowser control
$htmlContent = @"
<!DOCTYPE html>
<html>
<head>
    <title>Power options</title>
</head>
<body>

    <button id="a">
        Power
    </button><br>
    <button id="b">
        Reboot
    </button><br>
    <button id="c">
        Restart
    </button><br>
    <style>
        body {
            font-family: Verdana, Geneva, Tahoma, sans-serif;
            background-color: black;
        }

        button {
            color: blue;
            background-color: black;
            border: 1px solid blue;
            margin-left: 8px;
        }
    </style>
    <script>
        // Function to send message to PowerShell script
        function sendAction(action) {
            window.external.HandleAction(action);
        }

        // Attach click event handlers to the buttons
        document.getElementById("a").attachEvent("onclick", function() {
            sendAction("PowerOff");
        });

        document.getElementById("b").attachEvent("onclick", function() {
            sendAction("Reboot");
        });

        document.getElementById("c").attachEvent("onclick", function() {
            sendAction("Restart");
        });
    </script>
</body>
</html>
"@

# Set the HTML content and object for scripting for the WebBrowser control
$webBrowser.DocumentText = $htmlContent
$webBrowser.ObjectForScripting = $scriptBlock

# Add the WebBrowser control to the form
$form.Controls.Add($webBrowser)

# Show the form
$form.ShowDialog() | Out-Null

也许我可以使用 ICP(内部通信协议)来代替 COM

我尝试过并期待它能够在 Windows 11 上为计算机供电

c# html powershell internet-explorer com
1个回答
0
投票

正如评论中所暗示的,这里的问题是您将

[scriptblock]
类型的对象分配给
$webBrowser.ObjectForScripting

我的猜测是,您需要分配

ActionHandler
类的实例 - 因此调用脚本块来编译类型,然后创建一个实例并分配它:

# invoke scriptblock, store resulting type
$handlerType = & $scriptBlock

# create a new instance of the ActionHandler type
$myActionHandler = $handlerType::new()

# assign to target property
$webBrowser.ObjectForScripting = $myActionHandler
© www.soinside.com 2019 - 2024. All rights reserved.