Question Retrieving Current Windows 10 Power Plan

PurpleSweater

New member
Joined
Feb 21, 2020
Messages
3
Programming Experience
1-3
I've searched and searched and searched but I can't find anything on this topic. Simply put, I change my power plan from balanced to high performance based on if I'm gaming or not just to give my PC a break when I'm not gaming. I'm trying to make an app that mainly grabs the current power plan in plain text like such: "Current Power Plan: [currentPowerPlanHere]" and then a combo box to change the power plan such as: "Change Power Plan: 1.High Performance -or- 2.Balanced".

Any help is greatly appreciated thank you all!
 

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,439
Location
Norway
Programming Experience
10+
This is rather complicated to code in VB with Power Management Functions - Win32 apps
It can also be done with WMI and Win32_PowerPlan class (Windows)

Still lots of management code unless you generate a class with Mgmtclassgen.exe (Management Strongly Typed Class Generator)
I've attached a generated class I prepared with this command in VS Developer command prompt:
Mgmtclassgen.exe Win32_PowerPlan /l vb /n root\cimv2\power /p j:\Powerplan.vb
I made a small change to prevent Activate method throwing exception since it doesn't return a value.
Add the class to project and add reference to System.Management.dll.

The management functionality requires administrator permission, so change requestedExecutionLevel to "requireAdministrator" in app.manifest. (it can also be accessed through project properties > Application "View Windows Settings")

From here is get simple; set up UI controls ComboBox, Label and Button to interact with Powerplan members GetInstances, IsActive, ElementName and Activate.
initialize:
Dim plans = ROOT.CIMV2.POWER.Win32.Powerplan.GetInstances.Cast(Of ROOT.CIMV2.POWER.Win32.Powerplan).ToArray
ComboBoxPlans.DisplayMember = "ElementName"
ComboBoxPlans.DataSource = plans
LabelCurrent.Text = "Current plan: " & (From plan In plans Where plan.IsActive Select plan.ElementName).First
button click event handler:
Dim plan = CType(ComboBoxPlans.SelectedItem, ROOT.CIMV2.POWER.Win32.Powerplan)
plan.Activate()
LabelCurrent.Text = "Current plan: " & plan.ElementName
 

Attachments

  • Powerplan.zip
    4.6 KB · Views: 8

PurpleSweater

New member
Joined
Feb 21, 2020
Messages
3
Programming Experience
1-3
Wow. You're exceptional. Thank you.

Edit: Was having trouble but forgot to run with Admin privileges. Thanks so much.

Edit2: Now I get this error after clicking button:
VB.NET:
https://i.imgur.com/oRxNBNd.png
VB.NET:
System.Management.ManagementException
  HResult=0x80131501
  Message=This method is not implemented in any class
  Source=System.Management
  StackTrace:
   at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode)
   at System.Management.ManagementObject.InvokeMethod(String methodName, ManagementBaseObject inParameters, InvokeMethodOptions options)
   at GetCurrentPowerPlan.ROOT.CIMV2.POWER.Win32.Powerplan.Activate() in C:\Users\j0sha\source\repos\GetCurrentPowerPlan\GetCurrentPowerPlan\Powerplan.vb:line 425
   at GetCurrentPowerPlan.Form1.Button1_Click(Object sender, EventArgs e) in C:\Users\j0sha\source\repos\GetCurrentPowerPlan\GetCurrentPowerPlan\Form1.vb:line 11
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
   at GetCurrentPowerPlan.My.MyApplication.Main(String[] Args) in :line 81

  This exception was originally thrown at this call stack:
    System.Management.ManagementException.ThrowWithExtendedInfo(System.Management.ManagementStatus)
    System.Management.ManagementObject.InvokeMethod(string, System.Management.ManagementBaseObject, System.Management.InvokeMethodOptions)
    GetCurrentPowerPlan.ROOT.CIMV2.POWER.Win32.Powerplan.Activate() in Powerplan.vb
    GetCurrentPowerPlan.Form1.Button1_Click(Object, System.EventArgs) in Form1.vb
    System.Windows.Forms.Control.OnClick(System.EventArgs)
    System.Windows.Forms.Button.OnClick(System.EventArgs)
    System.Windows.Forms.Button.OnMouseUp(System.Windows.Forms.MouseEventArgs)
    System.Windows.Forms.Control.WmMouseUp(ref System.Windows.Forms.Message, System.Windows.Forms.MouseButtons, int)
    System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message)
    System.Windows.Forms.ButtonBase.WndProc(ref System.Windows.Forms.Message)
    ...
    [Call Stack Truncated]

Is it possible to change power plans using Process.Start("powercfg", "-setactive GUID_VALUE") with following parameters?:
VB.NET:
[*]Power Saver - powercfg.exe /setactive a1841308-3541-4fab-bc81-f71556f20b4a
[*]Balanced plan - powercfg.exe /setactive 381b4222-f694-41f0-9685-ff5bb260df2e
[*]High-Performance - powercfg.exe /setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c

so
VB.NET:
Select Case ComboBoxPlans.Text
            Case "Balanced"
                Process.Start("powercfg", "-setactive  381b4222-f694-41f0-9685-ff5bb260df2e")
            Case "High performance"
                Process.Start("powercfg", "-setactive  8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c")
            'Case "Power Saver"
                'Process.Start("powercfg", "-setactive  a1841308-3541-4fab-bc81-f71556f20b4a")
        End Select
 
Last edited:

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,439
Location
Norway
Programming Experience
10+
As you can see yourself Win32_PowerPlan class has the Activate method. No idea why yours errors out, it works fine here.
Yes, you can use powercnf also, here's an example getting the guids automatically:
VB.NET:
Dim plan = CType(ComboBoxPlans.SelectedItem, ROOT.CIMV2.POWER.Win32.Powerplan)
Dim guid = System.Text.RegularExpressions.Regex.Match(plan.InstanceID, "{(?<guid>.*)}").Groups("guid").Value
Dim info As New ProcessStartInfo("powercfg", "-setactive " & guid)
info.WindowStyle = ProcessWindowStyle.Hidden 'no flickering command window
Process.Start(info)
 

PurpleSweater

New member
Joined
Feb 21, 2020
Messages
3
Programming Experience
1-3
I'm not sure why it errors out. I'm running Windows 10 Pro x64. I'm running both visual studio in Admin and also set admin privileges in the manifest.

Does it have anything to do with .net version? I'd really prefer to use the Activate method instead of having a cmd box pop up with my app. Seems like activate would be better.
 
Top Bottom