设为首页 收藏本站
查看: 2104|回复: 0

基于Visual C#2010 与WPF开发Windows 7电源管理

[复制链接]

尚未签到

发表于 2015-5-11 14:01:06 | 显示全部楼层 |阅读模式
  关注微软动态的用户还记得他发布的那份“Windows 7 Power Management”白皮书吗?这个白皮书详细的讲述了Win7的电源管理技术方案,和如何降低电能消耗的原理。那么这个原理是怎么样的呢?
   
  1. 空闲资源的能耗
  这是众多省电技术中最根本的一项节电技术。在Win7里,空闲时的耗电量得到有效改善,当某个硬件一定时间不工作后就会进入低功耗状态已达到省电的目的。包括CPU,硬盘,内存以及网络部分都采用了这种技术。举例说就是当系统在空闲状态下基本能耗就是0W。
  2. 通过触发来启动服务
  在Win7里,部分系统服务只有被一些事件触发后才会启动,如插入某个设备或者更改IP。这样可以减少后台进程里长时间运行的服务数量。
  3. 增强的处理器电源管理
  Win7里集成了最新的电源管理技术,该技术能够让Win7根据当前负载情况和性能要求来动态的调节CPU性能。也就是我们常说的自动降频技术。
  4. 自适应的显示亮度调节
  搭载Win7的笔记本中将会内置光线感应器,用来感应使用环境的光线强度,这样操作系统会自动根据周围环境亮度来调整显示器亮度达到省电的目的。
  5. 低功率音频
  Win7将会支持Intel的低功耗HD音频规范,它能让编解码器进入极低的功耗状态。Win7还支持选择性挂起技术,将处于闲置状态的设备关闭,比如麦克风和摄像头这类USB设备。
  6. 计时器整合
  处理器通过利用处理指令的间隙空余时间来达到节能目的,但大部分节能技术都需要一定长度的空闲时间才能获得节能效果。而这项技术通过让Windows内核在同一时间内终止并集中原本较为分散的多个计时器,在短时间内处理完毕,从而增加了处理器的空闲时间。当笔记本在使用电池的情况下,Win7会减少非关键后台程序的活动频率。
  7. 蓝牙设备功耗改进
  当Win7检测到蓝牙设备处于低功耗状态时,会自动切换到“选择性挂起”状态一旦蓝牙设备提高功耗,便将激活蓝牙功能。
  8. 网络设备功耗改进
  Win7中对于无线网络控制器低功耗模式的兼容性得到了加强,只有在无线AP设备支持低功耗模式的情况下才会启用。Win7会先检测无线AP是否支持低功耗模式,避免无线网络连接突然中断的发生。
  9. 典型应用的优化方案
  另外Win7还可以将其他硬件能耗降低,如在不影响播放性能的前提下让CPU保持低功耗模式,通过改变架构来改进桌面窗口管理器和GPU的功耗,智能数据缓存能降低光驱转速。
  
  
  我们来基于Visual C#2010 与WPF实践一下,开发一个Windows 7电源管理演示程序!启动VS2010
  
  
http://hi.iyunv.com/attachment/201005/29/0_12751226208PCC.gif
  
  创建一个基于.net4.0的WPF文件,然后布局好下列按钮
  XAML代码如下
  
  
http://hi.iyunv.com/attachment/201005/30/0_12752392601I2v.gif
  
  
  
  
http://hi.iyunv.com/attachment/201005/30/0_1275239355j7t2.gif
  
  具体代码如下,详细请见代码注释
  
  
  
  using System;using System.ComponentModel;using System.Runtime.InteropServices;using System.Threading;using System.Windows;using System.Windows.Controls;using System.Windows.Interop;using System.Windows.Threading;using Microsoft.WindowsAPICodePack.ApplicationServices;using Microsoft.WindowsAPICodePack.Shell;namespace Microsoft.WindowsAPICodePack.Samples.PowerMgmtDemoApp{/// /// Interaction logic for Window1.xaml/// /// public partial class Window1 : Window{[DllImport("user32.dll")]private static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);public delegate void MethodInvoker();private MyPowerSettings settings;private BackgroundWorker backgroundWorker = new BackgroundWorker();private string cancelReason = string.Empty;private System.Windows.Threading.DispatcherTimer TimerClock;public Window1(){InitializeComponent();settings = (MyPowerSettings)this.FindResource("powerSettings");backgroundWorker.WorkerReportsProgress = true;backgroundWorker.WorkerSupportsCancellation = true;backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);// 设置时钟监视电源变化TimerClock = new DispatcherTimer();TimerClock.Interval = new TimeSpan(0, 0, 5);TimerClock.IsEnabled = true;TimerClock.Tick += new EventHandler(TimerClock_Tick);}void TimerClock_Tick(object sender, EventArgs e){GetPowerSettings();}void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){// 更新按钮标题if (string.IsNullOrEmpty(cancelReason)){SetLabelButtonStatus(IndexerCurrentFileLabel, "寻找完成!");SetLabelButtonStatus(IndexerStatusLabel, "点击开始寻找按钮继续开始寻找.");SetLabelButtonStatus(StartStopIndexerButton, "开始寻找电源事件!");}// 清除所有信息cancelReason = "";}void backgroundWorker_DoWork(object sender, DoWorkEventArgs e){SetLabelButtonStatus(IndexerCurrentFileLabel, "检索进行中 ....");IKnownFolder docs;if (ShellLibrary.IsPlatformSupported)docs = KnownFolders.DocumentsLibrary;elsedocs = KnownFolders.Documents;ShellContainer docsContainer = docs as ShellContainer;foreach (ShellObject so in docs){RecurseDisplay(so);if (backgroundWorker.CancellationPending){SetLabelButtonStatus(StartStopIndexerButton, "开始检索");SetLabelButtonStatus(IndexerStatusLabel, "点击开始寻找按钮继续开始寻找.");SetLabelButtonStatus(IndexerCurrentFileLabel, (cancelReason == "电源改变") ?"因为电源放弃检索" :"因为使用者放弃检索");return;}Thread.Sleep(1000); // 休眠1秒,以指示该文件的索引}}private void Window_Loaded(object sender, RoutedEventArgs e){CapturePowerManagementEvents();GetPowerSettings();}//获取从PowerManager的当前属性值。//此方法是在启动时调用。private void GetPowerSettings(){settings.PowerPersonality = PowerManager.PowerPersonality.ToString();settings.PowerSource = PowerManager.PowerSource.ToString();settings.BatteryPresent = PowerManager.IsBatteryPresent;settings.UpsPresent = PowerManager.IsUpsPresent;settings.MonitorOn = PowerManager.IsMonitorOn;settings.MonitorRequired = PowerManager.MonitorRequired;if (PowerManager.IsBatteryPresent){settings.BatteryShortTerm = PowerManager.IsBatteryShortTerm;settings.BatteryLifePercent = PowerManager.BatteryLifePercent;BatteryState batteryState = PowerManager.GetCurrentBatteryState();string batteryStateStr = string.Format("ACOnline: {1}{0}最大充电: {2} mWh{0}兆瓦时电流充电: {3} mWh{0}兆瓦时放电率: {4} {0}估计剩余时间: {5}{0}建议临界电池更换: {6} mWh{0}建议兆瓦电池充电警告: {7} mWh{0}",Environment.NewLine, batteryState.ACOnline, batteryState.MaxCharge, batteryState.CurrentCharge, batteryState.ACOnline == true ? "N/A" : batteryState.DischargeRate.ToString() + " mWh", batteryState.ACOnline == true ? "N/A" : batteryState.EstimatedTimeRemaining.ToString(), batteryState.SuggestedCriticalBatteryCharge, batteryState.SuggestedBatteryWarningCharge);settings.BatteryState = batteryStateStr;}}// 增加了对PowerManager的事件的事件处理程序。private void CapturePowerManagementEvents(){PowerManager.IsMonitorOnChanged += new EventHandler(MonitorOnChanged);PowerManager.PowerPersonalityChanged += new EventHandler(PowerPersonalityChanged);PowerManager.PowerSourceChanged += new EventHandler(PowerSourceChanged);if (PowerManager.IsBatteryPresent){PowerManager.BatteryLifePercentChanged += new EventHandler(BatteryLifePercentChanged);SetLabelButtonStatus(batteryLifePercentLabel, string.Format("{0}%", PowerManager.BatteryLifePercent.ToString()));}PowerManager.SystemBusyChanged += new EventHandler(SystemBusyChanged);}// PowerManager的事件处理程序。void MonitorOnChanged(object sender, EventArgs e){settings.MonitorOn = PowerManager.IsMonitorOn;AddEventMessage(string.Format("显示器状态改变 (new status: {0})", PowerManager.IsMonitorOn ? "On" : "Off"));}void PowerPersonalityChanged(object sender, EventArgs e){settings.PowerPersonality = PowerManager.PowerPersonality.ToString();AddEventMessage(string.Format("电源变化(current setting: {0})", PowerManager.PowerPersonality.ToString()));}void PowerSourceChanged(object sender, EventArgs e){settings.PowerSource = PowerManager.PowerSource.ToString();AddEventMessage(string.Format("电源设置变化 (current source: {0})", PowerManager.PowerSource.ToString()));//if (backgroundWorker.IsBusy){if (PowerManager.PowerSource == PowerSource.Battery){cancelReason = "电源变化";backgroundWorker.CancelAsync();}}else{if (PowerManager.PowerSource == PowerSource.AC || PowerManager.PowerSource == PowerSource.Ups){SetLabelButtonStatus(IndexerStatusLabel, "点击开始寻找按钮继续开始寻找.");}}}void BatteryLifePercentChanged(object sender, EventArgs e){settings.BatteryLifePercent = PowerManager.BatteryLifePercent;AddEventMessage(string.Format("电源电量变化了 (new value: {0})", PowerManager.BatteryLifePercent));// 设置剩余电源电量SetLabelButtonStatus(batteryLifePercentLabel, string.Format("{0}%", PowerManager.BatteryLifePercent.ToString()));}//事件处理程序必须使用窗口的调度//更新用户界面直接。这是必要的,因为//事件处理程序被调用在非UI线程。void SystemBusyChanged(object sender, EventArgs e){AddEventMessage(string.Format("系统忙碌变化 at {0}", DateTime.Now.ToLongTimeString()));}void AddEventMessage(string message){this.Dispatcher.Invoke(DispatcherPriority.Normal,(Window1.MethodInvoker)delegate{ListBoxItem lbi = new ListBoxItem();lbi.Content = message;messagesListBox.Items.Add(lbi);messagesListBox.ScrollIntoView(lbi);});}private void StartIndexer(object sender, RoutedEventArgs e){if (backgroundWorker.IsBusy && ((Button)sender).Content.ToString() == "停止索引"){cancelReason = "userCancelled";backgroundWorker.CancelAsync();SetLabelButtonStatus(IndexerStatusLabel, "点击按钮开始寻找");return;}//如果运行在使用电池,不启动索引if (PowerManager.PowerSource != PowerSource.Battery){backgroundWorker.RunWorkerAsync();SetLabelButtonStatus(IndexerStatusLabel, "索引进行中....");SetLabelButtonStatus(StartStopIndexerButton, "停止 索引");}else{SetLabelButtonStatus(IndexerCurrentFileLabel, "电池上运行。没有启动的索引");}}private void RecurseDisplay(ShellObject so){if (backgroundWorker.CancellationPending)return;SetLabelButtonStatus(IndexerCurrentFileLabel,string.Format("Current {0}: {1}", so is ShellContainer ? "文件夹" : "文件", so.ParsingName));// 通过此对象的子项,如果它是一个对象容器ShellContainer container = so as ShellContainer;if (container != null){foreach (ShellObject child in container)RecurseDisplay(child);}}private void SetLabelButtonStatus(ContentControl control, string status){this.Dispatcher.Invoke(DispatcherPriority.Normal,(Window1.MethodInvoker)delegate{control.Content = status;});}}}
  
  
  
  编译运行,见效果
  
  
  
  
  
  
http://hi.iyunv.com/attachment/201005/30/0_1275238979WP3E.gif
  
http://hi.iyunv.com/attachment/201005/30/0_1275239085hIdp.gif
  
http://hi.iyunv.com/attachment/201005/30/0_1275239035ZG2f.gif

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-65964-1-1.html 上篇帖子: Windows 7下的Aero效果 下篇帖子: Windows Server 2008(R2)配置apache+php+mysql环境(14年3月7日做备忘)(原创)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表