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

自制Windows 7 注册表键值修改服务(Service)

[复制链接]

尚未签到

发表于 2015-5-8 10:17:01 | 显示全部楼层 |阅读模式
  首先说说为什么要写这么一个服务。由于电脑要在公司域中使用,所以不可避免的会继承域中的组策略配置。域中95% 的计算机是XP系统,部分组策略对于Windows 7 系统来说有些多余而且带来很多麻烦。
  问题一、清除虚拟内存策略
  清除虚拟内存策略(Clear virtual memory pagefile)可以在一定程度上降低域中计算机病毒的传播。但问题是如果启动这个策略也会降低Windows 关机速度(3~5分钟),对于关机速度奇快(13~16秒)的Windows 7 系统来说简直是一个沉重的打击。
DSC0000.png
  修改这个组策略只需将[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management] 中的ClearPageFileAtShutdown 设为0x00000000 即可。
DSC0001.png
  问题二、系统更新策略
  在域中通过组策略可以使计算机通过WSUS 进行补丁更新,虽然是针对XP 系统设置的,但它却完全破坏了Windows 7 系统本身的更新机制,详情请参考《Windows Update Error: 80244019》。解决这个问题的办法只需将注册表中[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate] 完全删除。
  解决方法
  由此可见解决上面两个问题都可以通过修改注册表来实现,当然有人会说也可以通过修改域组策略来达到不在某一个域用户主机上应用组策略的效果,但这个方法还是不建议使用。起初写了一个Reg 文件运行一下就将注册表更新了,但总这么做也很麻烦。所以就想到创建一个服务让它在后台运行并修改注册表内容。
Windows Registry Editor Version 5.00
[-HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management]
"ClearPageFileAtShutdown"=dword:00000000
  创建一个Windows Service 项目,新建RegValueSet 类,并写入以下代码内容。在类中ChangeKeyValue() 方法用于完成上述注册表修改操作。其中Registry.LocalMachine.DeleteSubKeyTree(updatePath); 将删除系统更新组策略信息,RegSetValueEx(hKey, keyName, 0, RegistryValueKind.DWord, keyVal, 4); 会将ClearPageFileAtShutdown 键值修改为0。
DSC0002.png
  开始我尝试通过RegNotifyChangeKeyValue 方法监测SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management 下的键值是否被域组策略修改,如果被修改了便会执行RegSetValueEx 方法,但这种方式在服务中似乎行不通(启动服务时它会一直处于监听状态)。经测试发现其实只需在开/关机时进行ChangeKeyValue() 操作即可,所以便将代码改为以下方式。

using System;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace RegMonitor
{
class RegValueSet
{
private static UIntPtr HKEY_LOCAL_MACHINE = new UIntPtr(0x80000002u);
private static UIntPtr hKey;
private const int keyRights = 0xF003F; //KEY_ALL_ACCESS (0xF003F)
private const UInt32 INFINITE = 0xFFFFFFFF;
private const UInt32 WAIT_FAILED = 0xFFFFFFFF;
public static void ChangeKeyValue()
{
string clrPath = @"SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management";
string updatePath = @"SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate";
string keyName = "ClearPageFileAtShutdown";
//Delete Windows Update Settings
int vOpen = RegOpenKeyEx(HKEY_LOCAL_MACHINE, updatePath, 0, keyRights, out hKey);
if (vOpen == 0)
{
Registry.LocalMachine.DeleteSubKeyTree(updatePath);
}
//Change Clear Page File Value
RegOpenKeyEx(HKEY_LOCAL_MACHINE, clrPath, 0, keyRights, out hKey);
IntPtr hEvent = CreateEvent(IntPtr.Zero, true, false, null);
            RegNotifyChangeKeyValue(hKey, true, 4, hEvent, true);
            while (WaitForSingleObject(hEvent, INFINITE) != WAIT_FAILED)
{
RegistryKey key = Registry.LocalMachine.OpenSubKey(clrPath);
int val = (int)key.GetValue(keyName);
if (val != 0)
{
IntPtr keyVal = Marshal.AllocHGlobal(4);
Marshal.WriteInt32(keyVal, 0, 0);
RegSetValueEx(hKey, keyName, 0, RegistryValueKind.DWord, keyVal, 4);
key.Close();
}
RegCloseKey(hKey);
}
}
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int RegOpenKeyEx(
UIntPtr hKey,
string subKey,
int ulOptions,
int samDesired,
out UIntPtr hkResult);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern int RegSetValueEx(
UIntPtr hKey,
[MarshalAs(UnmanagedType.LPStr)] string lpValueName,
int Reserved,
RegistryValueKind dwType,
IntPtr lpData,
int cbData);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern int RegCloseKey(
UIntPtr hKey);
[DllImport("kernel32.dll")]
public static extern IntPtr CreateEvent(
IntPtr lpEventAttributes,
bool bManualReset,
bool bInitialState,
string lpName);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern int RegNotifyChangeKeyValue(
UIntPtr hKey,
bool watchSubtree,
int dwNotifyFilter,
IntPtr hEvent,
bool fAsynchronous);

[DllImport("kernel32.dll", SetLastError = true)]
        static extern UInt32 WaitForSingleObject(
            IntPtr hHandle,
            UInt32 dwMilliseconds);
    }
}
  
  最后在Service 属性中将CanShutdown 和CanStop 设为True,将Service 名称设为RegistryMonitor。并在OnStart(服务启动)、OnStop、OnShutdown(关机) 加入ChangeKeyValue() 方法就可以了,如下代码所示。
DSC0003.png

using System.ServiceProcess;
namespace RegMonitor
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
RegValueSet.ChangeKeyValue();
}
protected override void OnShutdown()
{
RegValueSet.ChangeKeyValue();
}
protected override void OnStop()
{
RegValueSet.ChangeKeyValue();
}
}
}
  编译项目后安装RegistryMonitor 服务(Installutil),并在Services.msc 中启动RegistryMonitor 服务。至此,就不用再担心组策略的继承问题了。
DSC0004.png
DSC0005.png

相关参考
  1. RegOpenKeyEx Function
http://msdn.microsoft.com/en-us/library/ms724897(VS.85).aspx
  2. RegSetValueEx Function
http://msdn.microsoft.com/en-us/library/ms724923(VS.85).aspx
  3. RegistryKey Methods
http://msdn.microsoft.com/en-US/library/microsoft.win32.registrykey_methods(v=VS.80).aspx

源程序下载

运维网声明 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-64902-1-1.html 上篇帖子: 《基于Windows 7特性的程序开发系列》视频分享 下篇帖子: 【爆牙齿】微软的坟墓:Windows 7。(五)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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