|
![]() |
|
Registriert seit: 16. Mai 2007 403 Beiträge |
#1
Ich habe einen neuen Versuch unternommen einen Code zu erstellen der zuverlässig System Restore Punkte unter Windows 10 erstellt.
Angehängt ist ein TestProjekt mit drei verschiedenen Methoden um einen Wiederherstellungspunkt zu erstellen. Methode 1: SrClient.dll wird geladen, SRSetRestorePointA aufgerufen Methode 2: Über ein TScriptControl wird mit VBScript ein getobject("winmgmts:\\.\root\default:Systemrestore ") erzeugt und CreateRestorePoint() aufgerufen Methode 3: Über CreateOleObject('WbemScripting.SWbemLocator') wird bemObjectSet.CreateRestorePoint() aufgerufen Dazu gibt es einen Button mit dem man System Restore aufrufen kann um zu überprüfen ob die Wiederherstellungspunkte erstellt wurden oder nicht. Installation: Sourcecode inkl vorkompilierter Exe (Delphi 7) ist angehängt Um TScriptControl zu erhalten (wird für Methode 2 benötigt) Menü "Komponente" den Menüpunkt "ActiveX importieren". In der Listbox "Microsoft Script Control 1.0" auswählen und "Installieren..." anklicken. Ohne TScriptControl kann man Methode 1 und 3 Testen (einfach die #2 auskommentieren). Test-Ergebnisse und daraus schlussfolgern wieso ich euch um Hilfe bitte. System 1, Windows 7: Test1: SystemRestoreTest.exe als Admin gestartet. Methode 1,2,3 funktionieren problemlos. Es werden nacheinander 3 Wiederherstellungspunkte erstellt. Test2: SystemRestoreTest.exe als Admin erneut gestartet. Methode 1,2,3 funktionieren problemlos. Es werden nacheinander 3 Wiederherstellungspunkte erstellt. System 2, Windows 10 Pro Build 14939 frisch installiert in einer VMWare VM: Nach Installation nur Sichergestellt dass Systemwiederherstellung aktiv ist, sonst nichts angefasst. Test 1: SystemRestoreTest.exe als Admin zum ersten Mal gestartet. Methode 1: Zu 50% kommt ein Marshalling Interfaces Init Fehler, zu 50% wird ein Wiederherstellungspunkt erstellt. Methode 2: Ein Wiederherstellungspunkt wird erstellt. Methode 3: Ein Wiederherstellungspunkt wird erstellt. Test 2: SystemRestoreTest.exe als Admin zum zweiten Mal (oder x-tem Mal) gestartet. Methode 1: Nach 1 Sekunde wird success gemeldet, es wird KEIN Wiederherstellungspunkt erstellt. Methode 2: Nach 1 Sekunde wird success gemeldet, es wird KEIN Wiederherstellungspunkt erstellt. Methode 3: Nach 1 Sekunde wird success gemeldet, es wird KEIN Wiederherstellungspunkt erstellt. Es macht keinen Unterschied wenn man zwischen Test 1 und 2 Programme installiert oder deinstalliert. System 3, Windows 10 Pro Build 14939, Installation ein Jahr alt, mein Entwicklungs-PC. UAC is deaktiviert! Test1: SystemRestoreTest.exe als Admin gestartet. Methode 1: meldet nach 1 Sekunde success, es wird KEIN Wiederherstellungspunkt erstellt. Methode 2,3: funktionieren problemlos. Es werden nacheinander 2 Wiederherstellungspunkte erstellt. Test2: SystemRestoreTest.exe als Admin erneut gestartet. Methode 1: meldet nach 1 Sekunde success, es wird KEIN Wiederherstellungspunkt erstellt. Methode 2,3: funktionieren problemlos. Es werden nacheinander 2 Wiederherstellungspunkte erstellt. -- Der ganze Test kommt davon dass ich Methode 3 in einer meiner Programme habe. Viele User meldeten dass diese Funktion keine Auswirkung auf Ihren Windows 10 Systemen hat. Es gibt wiederum Windows 10 User bei denen sie problemlos funktioniert. Ich bin für jegliche Vorschläge und Hilfe dankbar.
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Forms, Classes, SysUtils, Controls, StdCtrls, ActiveX, ComLib, OleCtrls, ComObj, MSScriptControl_TLB, ShellAPI; const MIN_EVENT = 100; {$EXTERNALSYM MIN_EVENT} BEGIN_SYSTEM_CHANGE = 100; {$EXTERNALSYM BEGIN_SYSTEM_CHANGE} END_SYSTEM_CHANGE = 101; {$EXTERNALSYM END_SYSTEM_CHANGE} BEGIN_NESTED_SYSTEM_CHANGE = 102; // for Whistler only - use this to prevent nested restore pts {$EXTERNALSYM BEGIN_NESTED_SYSTEM_CHANGE} END_NESTED_SYSTEM_CHANGE = 103; // for Whistler only - use this to prevent nested restore pts {$EXTERNALSYM END_NESTED_SYSTEM_CHANGE} MAX_EVENT = 103; {$EXTERNALSYM MAX_EVENT} // // Type of Restore Points // MIN_RPT = 0; {$EXTERNALSYM MIN_RPT} APPLICATION_INSTALL = 0; {$EXTERNALSYM APPLICATION_INSTALL} APPLICATION_UNINSTALL = 1; {$EXTERNALSYM APPLICATION_UNINSTALL} DESKTOP_SETTING = 2; // Not implemented {$EXTERNALSYM DESKTOP_SETTING} ACCESSIBILITY_SETTING = 3; // Not implemented {$EXTERNALSYM ACCESSIBILITY_SETTING} OE_SETTING = 4; // Not implemented {$EXTERNALSYM OE_SETTING} APPLICATION_RUN = 5; // Not implemented {$EXTERNALSYM APPLICATION_RUN} RESTORE = 6; {$EXTERNALSYM RESTORE} CHECKPOINT = 7; {$EXTERNALSYM CHECKPOINT} WINDOWS_SHUTDOWN = 8; // Not implemented {$EXTERNALSYM WINDOWS_SHUTDOWN} WINDOWS_BOOT = 9; // Not implemented {$EXTERNALSYM WINDOWS_BOOT} DEVICE_DRIVER_INSTALL = 10; {$EXTERNALSYM DEVICE_DRIVER_INSTALL} FIRSTRUN = 11; {$EXTERNALSYM FIRSTRUN} MODIFY_SETTINGS = 12; {$EXTERNALSYM MODIFY_SETTINGS} CANCELLED_OPERATION = 13; // Only valid for END_SYSTEM_CHANGE {$EXTERNALSYM CANCELLED_OPERATION} BACKUP_RECOVERY = 14; {$EXTERNALSYM BACKUP_RECOVERY} MAX_RPT = 14; {$EXTERNALSYM MAX_RPT} MAX_DESC = 64; {$EXTERNALSYM MAX_DESC} MAX_DESC_W = 256; // longer for Whistler type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Memo1: TMemo; Button3: TButton; ScriptControl1: TScriptControl; Button4: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); private { Private declarations } public { Public declarations } procedure log(s:string); function CreateRestorePointVB(sName:string):boolean; function CreateRestorePointSR(s: string): boolean; function CreateRestorePointOLE(s: string): boolean; end; function ChangeFSRedirection(bDisable: Boolean): Boolean; type // Restore point information PRESTOREPTINFOA = ^_RESTOREPTINFOA; _RESTOREPTINFOA = packed record dwEventType: DWORD; // Type of Event - Begin or End dwRestorePtType: DWORD; // Type of Restore Point - App install/uninstall llSequenceNumber: INT64; // Sequence Number - 0 for begin szDescription: array [0..MAX_DESC] of CHAR; // Description - Name of Application / Operation end; RESTOREPOINTINFO = _RESTOREPTINFOA; PRESTOREPOINTINFOA = ^_RESTOREPTINFOA; // Status returned by System Restore PSMGRSTATUS = ^_SMGRSTATUS; _SMGRSTATUS = packed record nStatus: DWORD; // Status returned by State Manager Process llSequenceNumber: INT64; // Sequence Number for the restore point end; STATEMGRSTATUS = _SMGRSTATUS; PSTATEMGRSTATUS = ^_SMGRSTATUS; TSetRestorePoint = Function(pRestorePtSpec: PRESTOREPOINTINFOA; pSMgrStatus: PSTATEMGRSTATUS): Bool; stdcall; var hSrClientDLL : THandle; FSetRestorePoint : TSetRestorePoint; Form1: TForm1; implementation {$R *.dfm} procedure TForm1.log(s:string); begin Memo1.Lines.Add(s); end; function ChangeFSRedirection(bDisable: Boolean): Boolean; type TWow64DisableWow64FsRedirection = Function(Var Wow64FsEnableRedirection: LongBool): LongBool; StdCall; TWow64EnableWow64FsRedirection = Function(var Wow64FsEnableRedirection: LongBool): LongBool; StdCall; var hHandle: THandle; Wow64DisableWow64FsRedirection: TWow64DisableWow64FsRedirection; Wow64EnableWow64FsRedirection: TWow64EnableWow64FsRedirection; Wow64FsEnableRedirection: LongBool; begin Result := false; try hHandle := GetModuleHandle('kernel32.dll'); @Wow64EnableWow64FsRedirection := GetProcAddress(hHandle, 'Wow64EnableWow64FsRedirection'); @Wow64DisableWow64FsRedirection := GetProcAddress(hHandle, 'Wow64DisableWow64FsRedirection'); if bDisable then begin if (hHandle <> 0) and (@Wow64DisableWow64FsRedirection <> nil) then begin Wow64DisableWow64FsRedirection(Wow64FsEnableRedirection); Result := True; end; end else begin if (hHandle <> 0) and (@Wow64EnableWow64FsRedirection <> nil) then begin Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection); Result := True; end; end; Except end; end; function TForm1.CreateRestorePointVB(sName:string):boolean; var sr: OLEVAriant; sSystemRestoreStatus: string; begin Result := False; sSystemRestoreStatus := 'System Restore status: not available'; try ScriptControl1.Language := 'VBScript'; sr := ScriptControl1.Eval('getobject("winmgmts:\\.\root\default:Systemrestore")'); if sr.CreateRestorePoint(sName, 0, 100) = 0 then begin log('CreateRestorePointVB SUCCESS'); Result := True; log('New Restore Point successfully created my method 2'); end else begin log('CreateRestorePointVB FAILURE') end; except on e: exception do begin log('CreateRestorePointVB EXCEPT'); log(e.Message); Exit; end; end; end; function TForm1.CreateRestorePointOLE(s: string): boolean; const WbemUser = ''; WbemPassword = ''; WbemComputer = 'localhost'; var RestorePtSpec: RESTOREPOINTINFO; SMgrStatus: STATEMGRSTATUS; r: Integer; FSWbemLocator: OLEVariant; FWMIService: OLEVariant; FWbemObjectSet: OLEVariant; begin Result := False; try FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\DEFAULT', WbemUser, WbemPassword); FWbemObjectSet := FWMIService.Get('SystemRestore'); r := FWbemObjectSet.CreateRestorePoint(s, APPLICATION_INSTALL, BEGIN_SYSTEM_CHANGE); if r = 0 then begin log('New Restore Point successfully created.'); Result := True; end else log( 'Error: ' + IntToStr(r)); except on E: EOleException do log(Format('EOleException %s %x', [E.Message, E.ErrorCode])); on E: Exception do log(E.Classname + ': ' + E.Message); end; end; function TForm1.CreateRestorePointSR(s: string): boolean; var RestorePtSpec: RESTOREPOINTINFO; SMgrStatus: STATEMGRSTATUS; begin Result := False; try CoInitializeEx(0, COINIT_MULTITHREADED); InitializeCOMSecurity(0, 2); if not assigned(FSetRestorePoint) then begin log('opening SrClient.dll'); hSrClientDLL := LoadLibrary('SrClient.dll'); if hSrClientDLL = 0 then begin log('load error'); Exit; end; @FSetRestorePoint := GetProcAddress(hSrClientDLL, 'SRSetRestorePointA'); if not assigned(FSetRestorePoint) then begin log('function error'); Exit; end; end; RestorePtSpec.dwEventType := BEGIN_SYSTEM_CHANGE; RestorePtSpec.dwRestorePtType := APPLICATION_INSTALL; RestorePtSpec.llSequenceNumber := 0; copymemory(@RestorePtSpec.szDescription[low(RestorePtSpec.szDescription)],@s[1],sizeof(RestorePtSpec.szDescription)); if FSetRestorePoint(@RestorePtSpec, @SMgrStatus) then begin Result := True; end; finally; CoUninitialize; if hSrClientDLL > 0 then FreeLibrary(hSrClientDLL); end; end; procedure TForm1.Button1Click(Sender: TObject); begin log('Creating restore point by method 1'); if CreateRestorePointSR('Test1 Restore Point '+timetostr(now)) then log('method 1 success') else log( 'method 1 error'); end; procedure TForm1.Button2Click(Sender: TObject); begin log('Creating restore point by method 2'); if CreateRestorePointVB('Test2 Restore Point '+timetostr(now)) then log('method 2 success') else log( 'method 2 error'); end; procedure TForm1.Button3Click(Sender: TObject); begin log('Creating restore point by method 3'); if CreateRestorePointOLE('Test3 Restore Point'+timetostr(now)) then log('method 3 success') else log( 'method 3 error'); end; procedure TForm1.Button4Click(Sender: TObject); begin ChangeFSRedirection(True); ShellExecute(0, 'open', 'rstrui.exe', '', nil, SW_SHOWNORMAL); ChangeFSRedirection(False); end; (* initialization CoInitializeEx(0, COINIT_MULTITHREADED); finalization CoUninitialize; *) end. Geändert von Shark99 (18. Mär 2017 um 04:36 Uhr) |
![]() |
t.roller
(Gast)
n/a Beiträge |
#2
Die 3 Methoden funktionieren bei WIN8.1 nicht, deshalb kann ich es mir ersparen, sie bei WIN10 zu testen.
Folgende Codes funktionieren bei mir: 1. CreateRestorePoint 2. RestorePoints auslesen
Delphi-Quellcode:
//You can use the CreateRestorePoint from the SystemRestore WMI class
program CreateRestorePoint; {$APPTYPE CONSOLE} uses // SysUtils, ActiveX, ComObj; System.SysUtils, Winapi.ActiveX, System.Win.ComObj; procedure CreateRestorePoint2(const Description : string); const WbemUser =''; WbemPassword =''; WbemComputer ='localhost'; BEGIN_SYSTEM_CHANGE = 100; APPLICATION_INSTALL = 0; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet : OLEVariant; begin FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\DEFAULT', WbemUser, WbemPassword); FWbemObjectSet:= FWMIService.Get('SystemRestore'); Writeln(FWbemObjectSet.CreateRestorePoint(Description, APPLICATION_INSTALL, BEGIN_SYSTEM_CHANGE)); // end; begin try CoInitialize(nil); try CreateRestorePoint2('Sample restore point'); finally CoUninitialize; end; except on E:EOleException do Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode])); on E:Exception do Writeln(E.Classname, ':', E.Message); end; Writeln('Press Enter to exit'); Readln; end.
Delphi-Quellcode:
program RestorePoint;
//Author Rodrigo Ruz 14/04/2010. {$APPTYPE CONSOLE} uses // SysUtils,ActiveX,ComObj,Variants; System.SysUtils,Winapi.ActiveX,System.Win.ComObj,System.Variants; function RestorePointTypeToStr(RestorePointType:Integer):string; begin case RestorePointType of 0 : Result:='APPLICATION_INSTALL'; 1 : Result:='APPLICATION_UNINSTALL'; 13 : Result:='CANCELLED_OPERATION'; 10 : Result:='DEVICE_DRIVER_INSTALL'; 12 : Result:='MODIFY_SETTINGS' else Result:='Unknow'; end; end; function EventTypeToStr(EventType:integer) : string; begin case EventType of 102 : Result:='BEGIN_NESTED_SYSTEM_CHANGE'; 100 : Result:='BEGIN_SYSTEM_CHANGE'; 103 : Result:='END_NESTED_SYSTEM_CHANGE'; 101 : Result:='END_SYSTEM_CHANGE' else Result:='Unknow'; end; end; function WMITimeToStr(WMITime:string) : string; //convert to dd/mm/yyyy hh:mm:ss begin //20020710113047.000000420-000 example source http://technet.microsoft.com/en-us/library/ee156576.aspx result:=Format('%s/%s/%s %s:%s:%s',[copy(WMITime,7,2),copy(WMITime,5,2),copy(WMITime,1,4),copy(WMITime,9,2),copy(WMITime,11,2),copy(WMITime,13,2)]); end; procedure GetRestorePoints; var oSWbemLocator : OLEVariant; objWMIService : OLEVariant; colItems : OLEVariant; colItem : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; begin oSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); objWMIService := oSWbemLocator.ConnectServer('localhost', 'root\default', '', ''); colItems := objWMIService.ExecQuery('SELECT * FROM SystemRestore','WQL',0); oEnum := IUnknown(colItems._NewEnum) as IEnumVariant; while oEnum.Next(1, colItem, iValue) = 0 do begin WriteLn(Format('%s %-15s',['Description',colItem.Description])); WriteLn(Format('%s %-15s',['RestorePointType',RestorePointTypeToStr(colItem.RestorePointType)])); WriteLn(Format('%s %-15s',['EventType',EventTypeToStr(colItem.EventType)])); WriteLn(Format('%s %-15s',['SequenceNumber',colItem.SequenceNumber])); WriteLn(Format('%s %-15s',['CreationTime',WMITimeToStr(colItem.CreationTime)])); Writeln; colItem:=Unassigned; end; end; begin try CoInitialize(nil); try GetRestorePoints; finally CoUninitialize; end; except on E:Exception do Writeln(E.Classname, ': ', E.Message); end; Readln; end. |
![]() |
Registriert seit: 6. Mär 2013 6.196 Beiträge Delphi 10 Seattle Enterprise |
#3
Die MSDN-Doku zu z.B.
![]() |
![]() |
Der schöne Günther |
Öffentliches Profil ansehen |
Mehr Beiträge von Der schöne Günther finden |
Registriert seit: 16. Mai 2007 403 Beiträge |
#4
@t.roller
Der Code den du gepostet hast ist der meiner Methode 3 mit zwei Zeilen Unterschied (CoInitialize(nil); und CoUninitialize ![]() Zusätzlich, um ganz sicher zu gehen habe ich deinen Code ohne Änderungen kompiliert als CreateRestorePoint.exe und RestorePoint.exe. Unter Win 7 und Win 10 mit UAC aus getestet. Geht problemlos. Danach die Win10 VM zurückgesetzt auf dem Stand kurz nach der Installation. Die beiden Exes hinkopiert und dann zwei Videos erstellt. Video 1 (restore_delphi.mp4): ![]() - cmd.exe wird mit Adminrechten geöffnet - CreateRestorePoint.exe werkelt 5 Sekunden lang mit viel IO Aktivität, meldet dann eine 0 - RestorePoint.exe hängt, da es keinen Restorepunkt gibt - Ich zeige dann noch in der Windows UI dass wirklich kein Punkt erstellt wurde Video 2 (restore_manual.mp4): ![]() - in dem zweiten Video welches kurz danach erstellt wurde zeige ich dass mit Windows 10 Boardmitteln man problemlos einen Wiederherstellunbgspunkt erstellen kann und RestorePoint.exe diesen auch anzeigt - Habe nach dem Video sofort wieder einen zweiten erstellt und das funktionierte auch (also kein 24h Limit bei den Boardmitteln) Es funktioniert also leider vorne und hinten nicht. Was mir aufgefallen ist dass die mit Boardmitteln erstellten Punkte immer vom Typ Manuell sind. Die von SystemRestoreTest erstellten vom Typ Installation. Vielleicht ist das der Schlüssel zum erfolgt. Ich habe deshalb dwRestorePtType geändert, BACKUP_RECOVERY, MODIFY_SETTINGS, und CHECKPOINT ändert die Sache aber von Installation auf System, nicht auf Manuell. Angehängt: Die zwei Projekte mit Code von t.roller inkl vorkompilierten Exes, Version 0.4 von SystemRestoreTest mit diesen Änderungen:
Delphi-Quellcode:
initialization
//CoInitializeEx(0, COINIT_MULTITHREADED); CoInitialize(nil); finalization CoUninitialize; @Der schöne Günther Danke für die Info. Es ist ja merkwürdig dass es diese Einschränkung nicht gibt wenn man die Wiederherstellungspunkte unter Windows 7, oder unter Windows 10 mit UAC aus erstellt. Da gehen beliebig viele mit gleichen Code. Ich werde mehr danach googeln. Was auch sehr merkwürdig ist dass es öfters Marshalling Fehler gibt beim InitializeCOMSecurity(). Wenn so ein Fehler kommt startet man die App neu und danach ist er meistens nicht mehr da. Geändert von Shark99 (19. Mär 2017 um 18:33 Uhr) |
![]() |
Registriert seit: 10. Apr 2006 Ort: Leverkusen 981 Beiträge Delphi 6 Professional |
#5
Hmm..
ALSO: Das mit einer Sicherung alle 24 h ist ab Windows 8 von MS eingebaut worden! Damit es öfter geht, muss ein Registry-Eintrag erstellt werden! ![]() Und da scheint es egal, welche deiner Versionen du verwendest! |
![]() |
Registriert seit: 16. Mai 2007 403 Beiträge |
#6
Ja, das habe ich ja gelesen nachdem Der schöne Günther den Link gepostet hat.
Die Boardmittel scheinen diese Einschränkung nicht zu haben, auch ohne die Registry Änderung. Die Erstellung von nur einem einzigen Punkt (also 24h Limit greift nicht) ist sehr unzuverlässig, d.h. funktioniert öfters gar nicht unter Windows 10. Siehe die Videos weiter oben. Ich denke da ist der Code noch wo Fehlerhaft. Wahrscheinlich ein CoInitializeSecurity() Problem oder irgendwas mit BEGIN_SYSTEM_CHANGE | END_SYSTEM_CHANGE. UAC aus scheint alle Probleme zu beheben, es ist aber ja keine Lösung. Edit: Wenn man innerhalb von der 24h Einschränkung ist meldet CreateRestorePoint() immer einen Success. Es wird aber kein Restore Point erstellt. Welcher Komiker von MS hat sich sowas einfallen lassen? Geändert von Shark99 (18. Mär 2017 um 20:14 Uhr) |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |