3

I am trying to write a program that will automate some setup for new computers at my job. One of the tasks is changing power options for Windows 7. I am trying to run a command that imports a power configuration file and returns the string output which contains a GUID to a variable. When I run the program, it does not return any value to my string. I'm sure I'm messing something up, can someone look and help? Here is my code:

if(chkPowerSettings.Checked == true && radioDesktop.Checked == true)
        {
            //Establish the path to the power configuration file
            string DesktopFileName = "WTCPowerDesktop.pow";
            string CFGFileSource = @"\\\\ops-data\\Apps\\Builds";
            string TargetPath = @"c:\\";

            //Creates the strings for the whole path
            string source = System.IO.Path.Combine(CFGFileSource, DesktopFileName);
            string destination = System.IO.Path.Combine(TargetPath, DesktopFileName);

            //Copies the file, the true will overwrite any already existing file
            System.IO.File.Copy(source, destination, true);
            System.Diagnostics.ProcessStartInfo importCFG = new System.Diagnostics.ProcessStartInfo("cmd","/c" + "powercfg –import C:\\WTCPowerDesktop.pow");
            importCFG.RedirectStandardOutput = true;
            importCFG.UseShellExecute = false;
            importCFG.CreateNoWindow = false;
            System.Diagnostics.Process runImport = new System.Diagnostics.Process();
            runImport.StartInfo = importCFG;
            runImport.Start();
            string PowerCFGResult = runImport.StandardOutput.ReadToEnd();
            MessageBox.Show(PowerCFGResult);
        }
Crispy
  • 5,557
  • 3
  • 30
  • 35
BigDevJames
  • 2,650
  • 5
  • 21
  • 36
  • Are you sure the output is on stdout instead of stderr? – Jon Skeet Jun 20 '13 at 14:47
  • I just tried changing the .StandardOutput to .StandardError just to see if that would return me anything, and it just returned me an exception. – BigDevJames Jun 20 '13 at 14:52
  • Why not use the option provided that allows you to pass *in* a `Guid`? I.e. generate one in your code, run the command, after it's finished you already know what the correct value is? `POWERCFG -IMPORT ` – Damien_The_Unbeliever Jun 20 '13 at 14:53
  • 1
    There is no space between the `"/c"` and `"power"` in your second startup parameter. Curious why you are concating there anyway. – Jay Jun 20 '13 at 14:57
  • I just added the space, thank you for that. However, my message box still returns nothing. – BigDevJames Jun 20 '13 at 14:58
  • Add a breakpoint just before `runImport.Start();`, take a look at the command it is about to execute and run it manually. – Jay Jun 20 '13 at 15:00
  • I added the breakpoint and ran it step by step, what should I be looking for? – BigDevJames Jun 20 '13 at 15:18
  • If you change the output `runImport.StandardError.ReadToEnd()`, you have to match with `importCFG.RedirectStandardError = true` accordingly. That's why you got an exception. – Alex Jun 20 '13 at 15:18
  • That is it. It is returning an error, now I have to figure out why it is. Thank you. – BigDevJames Jun 20 '13 at 15:58
  • Also consult http://stackoverflow.com/questions/919803/, http://stackoverflow.com/questions/1040706/, http://stackoverflow.com/questions/1765493/ – Dour High Arch Jun 20 '13 at 16:58

4 Answers4

2

The MSDN docs suggest waiting till the program closes after reading from the stream

        string DesktopFileName = "WTCPowerDesktop.pow";
        string CFGFileSource = "\\\\ops-data\\Apps\\Builds";
        string TargetPath = "c:\\";

        //Creates the strings for the whole path
        string source = System.IO.Path.Combine(CFGFileSource, DesktopFileName);
        string destination = System.IO.Path.Combine(TargetPath, DesktopFileName);

        //Copies the file, the true will overwrite any already existing file
        System.IO.File.Copy(source, destination, true);
        System.Diagnostics.ProcessStartInfo importCFG = 
            new System.Diagnostics.ProcessStartInfo("powercfg",
            string.Format("–import {0}", TargetPath))
        {
            RedirectStandardOutput = true,
            UseShellExecute = false,
            CreateNoWindow = false,
        };

        System.Diagnostics.Process runImport = new System.Diagnostics.Process(importCFG);
        runImport.Start();
        string PowerCFGResult = runImport.StandardOutput.ReadToEnd();
        runImport.WaitForExit(); //Add this line--
        MessageBox.Show(PowerCFGResult);

However I cannot test this myself as I do not have the application you are executing.

Update: I just noticed you used @ and escaped strings ("\\"). This could also be a problem

Jay
  • 6,224
  • 4
  • 20
  • 23
  • PowerCFGResult is a string without the option to place a .WaitForExit(); after. I tried placing a runImport.WaitForExit(); before the string declaration, and that didn't work either. – BigDevJames Jun 20 '13 at 15:42
  • You can also try executing the command directly instead of through the command prompt. – Jay Jun 20 '13 at 15:53
  • I have tried the update and my message box still returns me nothing. I appreciate all your help though. Do I have the right idea for trying to output a command line to a string in this method? – BigDevJames Jun 20 '13 at 15:53
  • I just saw your comment about executing the command directly, can you point me to a tutorial on how to do that? I found a tutorial that showed me how to do it this way. Sorry, I'm kind of new at this. – BigDevJames Jun 20 '13 at 15:54
  • Yes according to the [MSDN Documentation](http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput.aspx) you have done everything correctly. I would guess something on the command side isn't working. – Jay Jun 20 '13 at 15:54
0

I cannot comment... so i post it as an answer.

String with @ at the beginning does not need the double \. I'm thinking about the TargetPath variable, don't know about the previous one.

http://msdn.microsoft.com/en-us/library/362314fe(v=vs.110).aspx

Davide Lettieri
  • 326
  • 2
  • 13
0

If I understand correctly, you're trying to copy from a network location into C: drive, I think that needs elevated privileges to your program. try for testing purposes to copy from e:\source to e:\dest

Tamim Al Manaseer
  • 3,554
  • 3
  • 24
  • 33
  • The file copies correctly, I have verified that. I have admin privileges, so that isn't the concern here, but thank you. – BigDevJames Jun 20 '13 at 15:48
0

You should not store directly to C:\ but to C:\Users\Username\AppData if you do choose to write to C:\ then you may need to follow this how-to-force-my-net-app-to-run-as-administrator-on-windows-7 and force administrator rights.

Community
  • 1
  • 1
Bit
  • 1,068
  • 1
  • 11
  • 20
  • The file copies just fine, I am not having permissions issues for the file copy, that was one of my first concerns, but I made sure the file copied just fine. – BigDevJames Jun 20 '13 at 15:49
  • I was really just pointing out good protest on where files should be store; the administrator link was about running a command prompt from inside a program. I do not believe it will read the file because it is located at C:\ and the command prompt is not admin level. At least that is my understanding. – Bit Jun 20 '13 at 16:58
  • ahhh... I see, I'll have to give it a try in a different location when I get a chance – BigDevJames Jun 20 '13 at 17:12