Why creating a system restore point is only successful the first time in Windows 10

Steven Young 261 Reputation points
2021-07-05T12:02:47.727+00:00

Hi, i used the code below to create the restore point, but when the restore point is successfully created for the first time, if i changed the name to "test2" to create restore point again, but it doesn't work anymore, why?

Imports System.Management
Imports System.Runtime.InteropServices

Public Class SystemRestore

Public Enum RestorePointType
    ''' <summary>An application has been installed.</summary>
    ApplicationInstall = 0
    ''' <summary>An application has been uninstalled.</summary>
    ApplicationUninstall = 1
    ''' <summary>A device driver has been installed.</summary>
    DeviceDriverInstall = 10
    ''' <summary>An application has had features added or removed.</summary>
    ModifySettings = 12
    ''' <summary>An application needs to delete the restore point it created. For example, an application would use this flag when a user cancels an installation.</summary>
    CancelledOperation = 13
End Enum

Public Enum EventType
    ''' <summary>A system change has begun. A subsequent nested call does not create a new restore point.</summary>
    BeginNestedSystemChange = 102
    ''' <summary>A system change has begun.</summary>
    BeginSystemChange = 100
    ''' <summary>A system change has ended.</summary>
    EndNestedSystemChange = 103
    '''<summaY>A system change has ended.</summary>
    EndSystemChange = 101
End Enum

<StructLayout(LayoutKind.Sequential, Size:=4, Pack:=4)>
Public Structure HResult
    Implements IEquatable(Of HResult)

    Private Const severity As UInteger = &H8000_0000UI
    Private Const reserved_Conflict As UInteger = &H7800_0000UI
    Private Const facility_Conflict As UInteger = &H7FF_0000UI
    Private Const code_Conflict As UInteger = &H0_FFFFUI

    Private Const reservedShift As Integer = 32 - 5
    Private Const facilityShift As Integer = 32 - 16

    Private ReadOnly value_Conflict As UInteger

    Public Sub New(ByVal hr As Integer)
        Me.value_Conflict = CUInt(hr)
    End Sub

    Public ReadOnly Property Value() As Integer
        Get
            Return CInt(value_Conflict)
        End Get
    End Property
    Public ReadOnly Property Success() As Boolean
        Get
            Return 0 = (Me.value_Conflict And severity)
        End Get
    End Property
    Public ReadOnly Property Reserved() As Integer
        Get
            Return CInt((Me.value_Conflict And reserved_Conflict) >> reservedShift)
        End Get
    End Property
    Public ReadOnly Property Facility() As Integer
        Get
            Return CInt((Me.value_Conflict And facility_Conflict) >> facilityShift)
        End Get
    End Property
    Public ReadOnly Property Code() As Integer
        Get
            Return CInt(Me.value_Conflict And code_Conflict)
        End Get
    End Property

    Public Sub ThrowOnFailure()
        If Not Success Then
            Marshal.ThrowExceptionForHR(Value)
        End If
    End Sub

    Public Overrides Function ToString() As String
        Return $"0x{Me.value_Conflict:x8} ({NameOf(Facility)} = {Facility}, {NameOf(Code)}={Code})"
    End Function

    Public Shared Narrowing Operator CType(ByVal hr As Integer) As HResult
        Return New HResult(hr)
    End Operator

    Public Shared Function FromInt32(ByVal hr As Integer) As HResult
        Return New HResult(hr)
    End Function

    Public Shared Widening Operator CType(ByVal hResult_Conflict As HResult) As Integer
        Return hResult_Conflict.Value
    End Operator

    Public Function ToInt32() As Integer
        Return Value
    End Function

    Public Overrides Function Equals(ByVal obj As Object) As Boolean
        Dim tempVar As Boolean = TypeOf obj Is HResult
        Dim other As HResult = If(tempVar, CType(obj, HResult), Nothing)
        Return If(tempVar, Me.value_Conflict = other.Value, False)
    End Function

    Public Overrides Function GetHashCode() As Integer
        Return Value
    End Function

    Public Shared Operator =(ByVal l As HResult, ByVal r As HResult) As Boolean
        Return l.value_Conflict = r.value_Conflict
    End Operator

    Public Shared Operator <>(ByVal l As HResult, ByVal r As HResult) As Boolean
        Return l.value_Conflict <> r.value_Conflict
    End Operator

    Public Overloads Function Equals(ByVal other As HResult) As Boolean Implements IEquatable(Of HResult).Equals
        Return Me.value_Conflict = other.value_Conflict
    End Function
End Structure

Public Shared Function CreateRestorePoint(ByVal restorePointName As String, ByVal eventType As EventType, ByVal restorePointType As RestorePointType) As HResult
    Dim managementPath = New ManagementPath("\\.\ROOT\DEFAULT:SystemRestore")
    Dim systemRestoreClass = New ManagementClass(managementPath)
    Dim methodParameters = systemRestoreClass.Methods("CreateRestorePoint").InParameters

    methodParameters.Properties("Description").Value = restorePointName
    methodParameters.Properties("EventType").Value = CUInt(eventType)
    methodParameters.Properties("RestorePointType").Value = CUInt(restorePointType)

    Dim outParameters = systemRestoreClass.InvokeMethod("CreateRestorePoint", methodParameters, Nothing)
    Dim hresult = CType(CInt(CUInt(Math.Truncate(outParameters("ReturnValue")))), HResult)

    Return hresult
End Function

End Class

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim restorePointName = "test1"
Dim eventType As SystemRestore.EventType = eventType.BeginSystemChange
Dim restorePointType As SystemRestore.RestorePointType = restorePointType.ModifySettings

    Dim hresult As SystemRestore.HResult = CreateRestorePoint(restorePointName, eventType, restorePointType)
    If hresult.Success Then
        MessageBox.Show("success")
    End If

End Sub
VB
VB
An object-oriented programming language developed by Microsoft that is implemented on the .NET Framework. Previously known as Visual Basic .NET.
2,561 questions
{count} vote

1 answer

Sort by: Most helpful
  1. Katrien D'Hoker 5 Reputation points
    2023-03-28T11:46:02.96+00:00

    This might be related to the interval in which you create a system restore point.
    In case the interval is smaller than the system restore point creation frequency (default interval 24 hours), the system restore point won't be created. However, this limitation is not applicable to manually creating system restore points using the System Restore user interface.
    Modifying the frequency interval can be done in the registry: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRestore (add or modify DWORD SystemRestorePointCreationFrequency). The time unit is minutes, value 0 minutes will never skip creating a new restore point.

    1 person found this answer helpful.
    0 comments No comments