使用 PInvoke 创建系统还原点
如何在 C# 中使用 PInvoke 创建 Windows 的系统还原点

引言
系统还原是 Microsoft Windows ME、Windows XP 和 Windows Vista 操作系统的一个组件,它允许在系统出现故障或失败时,将系统文件、注册表项、已安装程序等回滚到先前的状态。1
系统还原的作用
每个 Windows 用户都知道,如果您的系统崩溃了,您只需要在安全模式下运行计算机,运行系统还原,然后希望它在下次重启时能正常工作,那么系统还原就非常有用。
它还会
- 创建还原点,以便计算机可以恢复到其先前状态
- 通过允许用户指定要为还原点分配多少硬盘空间来节省磁盘空间
- 在用户还原系统后创建一个新的还原点
- 备份注册表、某些文件扩展名、本地用户配置文件等等
- 从安全模式或 Vista 中的 Windows 恢复环境还原系统
系统还原不起作用的情况
- 通过注册表禁用系统还原的功能可能会导致病毒和木马禁用用户,使其无法摆脱病毒。
- 系统还原是在 Windows ME 中引入的,但尽管引入的时机有点晚,它们并未将其集成到 Windows 2000 或 Windows Server 中。但是,市面上有一些软件可以在没有该功能的操作系统中安装它。
- 系统还原点保存在特定目录中,Microsoft 禁止任何应用程序修改此目录。如果计算机感染了病毒并且创建了还原点,那么防病毒程序将无法将其从目录中删除,并在计算机还原时再次感染计算机。
- 如果您计划在 Windows ME 中使用系统还原功能,请注意,它不适用于 Microsoft .NET Framework 3.0 或更高版本。
- 如果磁盘空间不足,系统还原点将自动删除。如果出现问题,用户可能为时已晚,无法将计算机还原到正常工作状态。
- 更改到其他驱动器有时不会被监视,这可能导致安装在其他驱动器上的程序在还原后无法正常运行。
- 系统还原在 Windows Vista 和 7 上不适用于 FAT32 磁盘或小于 1GB 的驱动器。
- 考虑到系统还原的各种缺陷和限制,最好为您的软件配备某种内部备份数据库。这样,如果系统还原无法正常工作,用户就可以使用您的软件进行还原。
关于还原点
还原点是使用名为“srclient.dll”的 DLL 创建的。创建还原点有两种方法:通过 WMI(Windows Management Instruments)或 API(Application Programming Interface)。我将向您展示如何通过 API 实现,因为 WMI 仅适用于 XP,而且 WMI 令人沮丧。
代码工作原理

还原点信息
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct RestorePointInfo
{
public int dwEventType; // The type of event
public int dwRestorePtType; // The type of restore point
public Int64 llSequenceNumber; // The sequence number of the restore point
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MaxDescW + 1)]
public string szDescription; // The description to be displayed so
//the user can easily identify a restore point
}
启动还原点
在启动还原点时,RestorePointInfo
结构必须指定 dwEventType
、dwRestorePtType
和 szDescription
。llSequenceNumber
需要设置为 0
。
结束还原点
如果您正在结束一个还原点,结构需要 llSequenceNumber
和 dwEventType
。如果正在取消调用,它还需要 dwRestorePtType
。
状态管理器状态
当调用 SRSetRestorePoint
函数时,STATEMGRSTATUS
用作输出。序列号需要在启动还原点时保存到变量中,以便在结束还原点时再次使用。如果函数返回 false
,nStatus
将接收错误信息。要从错误代码中获取异常,请使用 throw new Win32Exception(STATEMGRSTATUS.nStatus);
[StructLayout(LayoutKind.Sequential)]
public struct STATEMGRSTATUS
{
public int nStatus; // The status code
public Int64 llSequenceNumber; // The sequence number of the restore point
}
还原类型
可以创建几种不同类型的还原点。它们非常直接……如果您正在安装应用程序,那将是 ApplicationInstall
;如果您是第一次运行应用程序,那将是 FirstRun
……等等……
public enum RestoreType
{
ApplicationInstall = 0, // Installing a new application
ApplicationUninstall = 1, // An application has been uninstalled
ModifySettings = 12, // An application has had features added or removed
CancelledOperation = 13, // An application needs to delete
// the restore point it created
Restore = 6, // System Restore
Checkpoint = 7, // Checkpoint
DeviceDriverInstall = 10, // Device driver has been installed
FirstRun = 11, // Program used for 1st time
BackupRecovery = 14 // Restoring a backup
}
事件类型
开始还原点时,事件应设置为 BeginSystemChange
,反之亦然。BeginNestedSystemChange
和 EndNestedSystemChange
仅在 Windows XP 上使用嵌套还原点时使用。有关更多信息,请参见 此链接。
public const Int16 BeginSystemChange = 100;
public const Int16 EndSystemChange = 101;
public const Int16 BeginNestedSystemChange = 102;
public const Int16 EndNestedSystemChange = 103;
函数
[DllImport("srclient.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SRSetRestorePointW
(ref RestorePointInfo pRestorePtSpec, out STATEMGRSTATUS pSMgrStatus);
启动还原点
- 在应用程序中初始化 COM 安全性,以便允许
NetworkService
、LocalService
和System
。(我找不到关于需要设置的确切权限的信息) - 确保程序正在运行的操作系统具有系统还原功能。
- 使用
RestorePointInfo
结构指定还原信息。将事件类型设置为BeginSystemChange
。然后,将dwRestorePtType
设置为您想要的还原点类型,并将szDescription
设置为描述。 - 调用
SRSetRestorePointW
。检查函数是否返回true
,如果没有,则表示它可能已被禁用或存在问题。 - 序列号非常重要,因为它需要在取消或结束还原点时使用。
注意...
在系统更改的开始和结束之间,系统还原将记录所有需要还原的内容。此时应该进行系统更改。
取消/结束还原点
- 仅当您要结束还原点时,才将
RestorePointInfo
中的事件类型设置为EndSystemChange
。 - 如果您要取消还原点,则将还原点类型设置为
CancelledOperation
,并将事件类型保留为EndSystemChange
。 - 将序列号设置为您在启动还原点时由
STATEMGRSTATUS
提供的数字。 - 调用
SRSetRestorePointW
。 - 如果函数返回
false
,则表示找不到序列号或操作系统不支持系统还原。
结论
我在 ZIP 存档中包含了创建还原点所需的所有代码。抱歉,我没有包含其他 API 或 WMI 类的文档。如果您想了解更多信息,请查看 MSDN。您还可以 此处 了解更多关于系统还原的信息。