Link to home
Start Free TrialLog in
Avatar of steverey443
steverey443

asked on

Trying to create standalone executable in C++ with VS2005 to set Power Management properties on Windows 2000, XP, and Vista.

I'm trying to create standalone executable in C++ with VS2005to set Power Management properties on Windows 2000, XP, and Vista.

I got some code from here:
http://softwarecommunity.intel.com/articles/eng/2667.htm

But it uses SetCurrentPowerPolicies which is an invalid identifier.  Current code below.

I don't need to use any of this code but I do need this to not be dependent on .NET or any other software that doesn't come with 2000, XP, and Vista by default.

Totally new to C++.  I thinks this would have been done a long time ago if I could use .NET.


// IdleTime.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h";
#include "powrprof.h"
 
 
using namespace std;
 
 
int _tmain(int argc, _TCHAR* argv[])
{
    double tickCount;
double idleCount;
LASTINPUTINFO lpi;
lpi.cbSize = sizeof(LASTINPUTINFO);
 
if (!GetLastInputInfo(&lpi))
{
// failed, use GetLastError to get error code
}
 
// lpi.dwTime now holds the tick count when last input was made
 
//cout << lpi.dwTime << endl;
tickCount = GetTickCount();
idleCount = ( tickCount - lpi.dwTime );
cout << idleCount / 1000 << endl;
 
//GLOBAL_POWER_POLICY CurrentGP;
//POWER_POLICY CurrentPP;
//UINT id;
//GetActivePwrScheme(&id);                          //capture id of current scheme
//GetCurrentPowerPolicies(&CurrentGP,&CurrentPP);   //get active policies
////if(CanUserWritePwrScheme() == FALSE) {cout << "no";};
 
GLOBAL_POWER_POLICY CurrentGP;
POWER_POLICY CurrentPP;
ULONG savVidAC,savVidDC;
UINT id;
UINT ssav;
 
GetActivePwrScheme(&id);                          //capture id of current scheme
GetCurrentPowerPolicies(&CurrentGP,&CurrentPP);   //get active policies
savVidAC = CurrentPP.user.VideoTimeoutAc;         //save current values
savVidDC = CurrentPP.user.VideoTimeoutDc;
CurrentPP.user.VideoTimeoutAc = 15;                //disallow display shutoff
CurrentPP.user.VideoTimeoutDc = 14;
//set new values.  Not sure how to save values
SetCurrentPowerPolicies(id,CurrentGP,&CurrentPP); //set new values
// get error:  Error	1	error C3861: 'SetCurrentPowerPolicies': identifier not found	
//      c:\Programming\PowerManagement\SetPMSettingsCPlusPlus\IdleTime\IdleTime.cpp	50	
 
//SystemParametersInfo (SPI_GETSCREENSAVETIMEOUT,0,&ssav,0);  //save current value
//SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT,0,NULL,0);    //turn off screen saver
 
	return 0;
}

Open in new window

Avatar of jkr
jkr
Flag of Germany image

That seem be a typo  (or whatever) on the Intel side, did you mean to

WriteGlobalPwrPolicy(&CurrentPP);

?
Avatar of steverey443
steverey443

ASKER

Hi jkr

Getting closer.  This gives the following error.

Error      1      error C2664: 'WriteGlobalPwrPolicy' : cannot convert parameter 1 from 'POWER_POLICY *__w64 ' to 'PGLOBAL_POWER_POLICY'      c:\Programming\PowerManagement\SetPMSettingsCPlusPlus\IdleTime\IdleTime.cpp      50      
Is there a way to write the POWER_POLICY instead of the GLOBAL_POWER_POLICY?  I see the options here:
http://msdn2.microsoft.com/en-us/library/aa373163(VS.85).aspx

But I can't figure out how to save settings after making changes.
Sorry, make that
WriteGlobalPwrPolicy(&CurrentGP);

Open in new window

Thanks jkr.

I tried that but I get the three following errors.  Do I need to add something to my header file?  (New to C++ and am likely to be missing remedial things.)

error LNK2001: unresolved external symbol _GetActivePwrScheme@4
error LNK2001: unresolved external symbol _GetCurrentPowerPolicies@8      
error LNK2001: unresolved external symbol _WriteGlobalPwrPolicy@4
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks again for your help.  That worked like a charm.

It looks like I need to use WritePwrScheme instead which I have tried but am it required a PUINT and the ID is returned as a UINT.  Can I convert a UINT to a PUINT?
// IdleTime.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h";
#include "powrprof.h"
 
 
using namespace std;
 
 
int _tmain(int argc, _TCHAR* argv[])
{
    double tickCount;
double idleCount;
LASTINPUTINFO lpi;
lpi.cbSize = sizeof(LASTINPUTINFO);
 
if (!GetLastInputInfo(&lpi))
{
// failed, use GetLastError to get error code
}
 
// lpi.dwTime now holds the tick count when last input was made
 
//cout << lpi.dwTime << endl;
tickCount = GetTickCount();
idleCount = ( tickCount - lpi.dwTime );
cout << idleCount / 1000 << endl;
 
//GLOBAL_POWER_POLICY CurrentGP;
//POWER_POLICY CurrentPP;
//UINT id;
//GetActivePwrScheme(&id);                          //capture id of current scheme
//GetCurrentPowerPolicies(&CurrentGP,&CurrentPP);   //get active policies
////if(CanUserWritePwrScheme() == FALSE) {cout << "no";};
 
GLOBAL_POWER_POLICY CurrentGP;
POWER_POLICY CurrentPP;
ULONG savVidAC,savVidDC;
UINT id;
//UINT ssav;
 
 
GetActivePwrScheme(&id);                          //capture id of current scheme
GetCurrentPowerPolicies(&CurrentGP,&CurrentPP);   //get active policies
savVidAC = CurrentPP.user.VideoTimeoutAc;         //save current values
savVidDC = CurrentPP.user.VideoTimeoutDc;
 
CurrentPP.user.VideoTimeoutAc = 15;                
CurrentPP.user.VideoTimeoutDc = 14;
//set new values.  Not sure how to save values
WritePwrScheme(id,"test1","test1",&CurrentPP);
WriteGlobalPwrPolicy(&CurrentGP);
 
//SetCurrentPowerPolicies(id,CurrentGP,&CurrentPP); //set new values
// get error:  Error	1	error C3861: 'SetCurrentPowerPolicies': identifier not found	
//      c:\Programming\PowerManagement\SetPMSettingsCPlusPlus\IdleTime\IdleTime.cpp	50	
 
//SystemParametersInfo (SPI_GETSCREENSAVETIMEOUT,0,&ssav,0);  //save current value
//SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT,0,NULL,0);    //turn off screen saver
 
	return 0;
}

Open in new window

A PUINT is the address of an UINT, so '&' should help you, i.e.

WritePwrScheme(&id,"test1","test1",&CurrentPP);
Someone needs to buy a book :)

It runs fine now.

It doesn't work as expected since it sets the values to zero rather than 5 and 6 but it does run and make changes.
CurrentPP.user.VideoTimeoutAc = 5;                
CurrentPP.user.VideoTimeoutDc = 6;

I changed the code to follow another example and get the same results.  
powercfg /query
Field Description          Value
-----------------          -----
...
Turn off monitor (AC)      After 0 mins
Turn off monitor (DC)      After 0 mins
...


If you or anyone has advice on how to set these settings in a way that actually works that would be great.  Thanks for the help getting the code working.  If I don't hear back on a method that works I'll accept your solution since at least you got the example I was trying to use working.

BTW the second example I tried had a downloadable executable that also had the same results of setting the actual Power Management values to 0.
http://www.coises.com/software/monitorsleep.htm







unsigned int ps;
unsigned int timeout;
POWER_POLICY pp;
 
timeout = 5;
 
GetActivePwrScheme(&id);   
ReadPwrScheme(ps, &pp);
pp.user.VideoTimeoutAc = timeout;
SetActivePwrScheme(ps, 0, &pp);

Open in new window

I was able to get this to work using an example on setting processor throttle and modifying it.
http://softwarecommunity.intel.com/articles/eng/1048.htm

Working code below.  Just need to test on other operating systems now.

Thanks for your help!


POWER_POLICY CurrentPowerPolicy;
UINT	psIdx = 0;
 
#define TEST_VALUE_AC   7200
#define TEST_VALUE_DC   7200
 
GetActivePwrScheme(&psIdx); 
ReadPwrScheme(psIdx, &CurrentPowerPolicy);
CurrentPowerPolicy.user.VideoTimeoutAc = TEST_VALUE_AC;
CurrentPowerPolicy.user.VideoTimeoutDc = TEST_VALUE_DC;
WritePwrScheme(&psIdx,NULL,NULL, &CurrentPowerPolicy); 
SetActivePwrScheme(psIdx, NULL, NULL); 

Open in new window

Thanks for helping out a noob.