我正在制作一个网络应用程序,每当 COM(组件对象模型)不可见时,它就会关闭计算机
异常设置“ObjectForScripting”:“ObjectForScripting 的类必须对 COM 可见。验证该对象是否是 public,或者考虑将 ComVisible 属性添加到您的类中。” 在 C:\Users\kayde\window.ps1:99 字符:1
+ 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 上为计算机供电
正如评论中所暗示的,这里的问题是您将
[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