0

I'm working on a small C# app that will import a power plan to the user's PC and set it as active. It working perfectly with a .bat file when the .pow file is in the same folder and I'm running commands:

powercfg -import "%~dp0\Optimized.pow"
powercfg /setactive 62ffd265-db94-4d48-bb7a-183c87641f85

Now, in C# I tried this:

  Process cmd = new Process();
  cmd.StartInfo.FileName = "powercfg";
  cmd.StartInfo.Arguments = "-import \"%~dp0\\Optimized\"";
  cmd.StartInfo.Arguments = "powercfg /setactive 62ffd265-db94-4d48-bb7a-183c87641f85";
  cmd.Start(); 

  //and this:
  private void button1_Click(object sender, EventArgs e)
  {
      Process cmd = new Process();
      cmd.StartInfo.FileName = "cmd.exe";
      cmd.StartInfo.RedirectStandardInput = true;
      cmd.StartInfo.RedirectStandardOutput = true;
      cmd.StartInfo.CreateNoWindow = true;
      cmd.StartInfo.UseShellExecute = false;
      cmd.Start();
      cmd.StandardInput.WriteLine("powercfg -import \"%~dp0\\Optimized\"");
      cmd.StandardInput.WriteLine("powercfg /setactive 6aa8c469-317b-45d9-a69c-f24d53e3aff5");
      cmd.StandardInput.Flush();
      cmd.StandardInput.Close();
      cmd.WaitForExit();
      Console.WriteLine(cmd.StandardOutput.ReadToEnd());
  }

But the program doesn't see the .pow file in the project folder (I actually tried to put it in each and every folder in the project). How it can be implemented to let the powercfg see the file?

Any help is much appreciated! Thanks!

EggyBach
  • 4,148
  • 1
  • 18
  • 21
DIY Mods
  • 79
  • 2
  • 9

2 Answers2

1

You could try something like this:

var cmd = new Process {StartInfo = {FileName = "powercfg"}};
using (cmd) //This is here because Process implements IDisposable
{

   var inputPath = Path.Combine(Environment.CurrentDirectory, "Optimized.pow");

   //This hides the resulting popup window
   cmd.StartInfo.CreateNoWindow = true;
   cmd.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

   //Prepare a guid for this new import
   var guidString = Guid.NewGuid().ToString("D"); //Guid without braces

   //Import the new power plan
   cmd.StartInfo.Arguments = $"-import \"{inputPath}\" {guidString}";
   cmd.Start();

   //Set the new power plan as active
   cmd.StartInfo.Arguments = $"/setactive {guidString}";
   cmd.Start();
}

This fixes the Arguments parameter that is being overwritten/used twice, as well as correctly disposes of the cmd variable. Additional lines added to hide the resulting pop-up window, and for generating the Guid upfront and specifying it as part of the command line.

EggyBach
  • 4,148
  • 1
  • 18
  • 21
  • Thanks! Unfortunately, it still doesn't see a file, despite I put it in every folder of the project. What could be an issue? – DIY Mods Nov 07 '19 at 01:51
  • Answer modified to include the current path. – EggyBach Nov 07 '19 at 02:06
  • Awesome! It works! Thank you so much! BTW, Is there any way to hide the CMD window since it pop-up? – DIY Mods Nov 07 '19 at 02:18
  • Yes, there is - the CreateNoWindow and WindowStyle properties can be set on the StartupInfo property.This won't hide the console window of the app, though. – EggyBach Nov 07 '19 at 02:21
  • You are the best! The very last thing, maybe you know: Power Plans has a GUIDs. It seems like they are changing every time the power profile is imported. Is there any way to set the profile as active without GUID or identify which GUID profile has after importing? I truly appreciate your help, I was fighting with these issues two days in a row. – DIY Mods Nov 07 '19 at 02:41
  • At the risk of being entirely off-topic ;) You can actually specifiy the guid to be used in the import. I've modified the code to do this. – EggyBach Nov 07 '19 at 19:41
  • Man, you are a legend! :) Thanks a bunch! – DIY Mods Nov 08 '19 at 00:32
0

Your first snippet does not work because you're reassigning cmd.StartInfo.Arguments before executing the process. The first assignment is lost when you throw it out in favor of the second assignment.

The first snippet most likely doesn't work because when you set cmd.startInfo.FileName to just a filename with no path, it will search only the directory of your C# app's .exe (likely in project/bin/Debug/). Since the FileName is cmd.exe and there is probably no cmd.exe in your project folder, it can't find anything.

You may also consider setting cmd.StartInfo.WorkingDirectory to an appropriate directory with your .pow file so that your relative paths will resolve correctly.

Klaycon
  • 10,599
  • 18
  • 35