Im making a web app that turns of computer everytime its not visible to COM (component object model)
Exception setting "ObjectForScripting": "ObjectForScripting's class must be visible to COM. Verify that the object is public, or consider adding the ComVisible attribute to your class." At C:\Users\kayde\window.ps1:99 char:1
- $webBrowser.ObjectForScripting = $scriptBlock
-
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException + FullyQualifiedErrorId : ExceptionWhenSetting
I tried using 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
maybe instead of using COM I could use ICP(inter communication protocol)
I tried and was expecting it to power of computer on windows 11
$scriptBlockto$webBrowser.ObjectForScripting? Sounds like you'll want to execute the scriptblock, and then create and pass an instance of theActionHandlertype instead (eg.$webBrowser.ObjectForScripting = (&$scriptBlock)::new())