Seite 1 von 1

Systemwiederherstellungspunkt erstellen

Verfasst: 29.04.2011 12:24
von RSBasic
Hi,


vor einem Jahr wollte ich mal eine Funktion aus einer DLL-Datei, die in PB natürlich nicht bekannt ist, fürs Erstellen eines Systemwiederherstellungspunktes nutzen, aber damals bin ich leider nicht weit gekommen. Deshalb habe ich damals einen Thread im PBL-Forum erstellt. Ich habe dort zwar eine Antwort erhalten, aber so richtig schlauer war ich danach leider doch nicht. Wie auch immer, nun versuche ich hier, vielleicht kann mir hier jemand helfen.

Und zwar, ich möchte gerne die WinAPI "CreateRestorePoint" aus der Datei "SrClient.dll" (ab Windows XP) benutzen, um einen Systemwiederherstellungspunkt zu erstellen.
In Foren (PBL, PBoard, PBEng) habe ich schon geguckt, aber da gibt es nichts zu finden.

Mein damaliger Code, mit dem ich versuche, einen Systempunkt zu erstellen:

Code: Alles auswählen

;http://msdn.microsoft.com/en-us/library/aa378941%28VS.85%29.aspx
;http://msdn.microsoft.com/en-us/library/aa378847%28VS.85%29.aspx

EnableExplicit

Define text.s="Restore Point"
Define Libef
Define *Func

Libef = LoadLibrary_("SrClient.dll")

Debug Libef

If Libef
  ;*Func = GetProcAddress_(Libef, "SRSetRestorePoint")
  *Func = GetProcAddress_(Libef, "CreateRestorePoint")
 
  Debug *Func
 
  If *Func
    CallFunctionFast(*Func, @text , #APPLICATION_INSTALL, #BEGIN_SYSTEM_CHANGE)
  EndIf
EndIf
FreeLibrary_(Libef)
Heute wüsste ich immernoch nicht, wie ich das am besten realisieren könnte. Bin zu doof für sowas.

Re: Systemwiederherstellungspunkt erstellen

Verfasst: 29.04.2011 13:01
von shadow
HI,

also ich find das MSDN-Beispiel schön verständlich. Gut, der gute alte Struktur-Pointer-Quatsch der guten alten WIN-API ist wie gehabt verwirrend :mrgreen:
Jedenfalls könnte ich dir den Code heute abend nach PB umstricken (wenn mir niemand zuvor kommt :wink: )

Re: Systemwiederherstellungspunkt erstellen

Verfasst: 29.04.2011 13:39
von ts-soft
http://news.jrsoftware.org/news/innosetup/msg58979.html
Das alte ScriptControl von mir oder COMate sollten weiterhelfen.

Re: Systemwiederherstellungspunkt erstellen

Verfasst: 29.04.2011 22:28
von shadow
Also, ich habe es jetzt nach PB umgesetzt. Und ja, ich weiß, der Code ist schlampig und nicht gerade optimiert/ressourcenaufräumend, aber hey, das hab ich so zusammengetippt. Aber es funktioniert :bounce:

Nicht vergessen: Diese Version ist nicht Unicode-fähig und den Administratormodus unbedingt einschalten.

Code: Alles auswählen

;typedef BOOL (WINAPI *PFN_SETRESTOREPTW) (PRESTOREPOINTINFOW, PSTATEMGRSTATUS);
EnableExplicit

#RPC_C_AUTHN_LEVEL_DEFAULT 		= 0
#RPC_C_IMP_LEVEL_IMPERSONATE 	= 3
#EOAC_NONE										= 0

; typedef struct _RESTOREPTINFO {
;   DWORD dwEventType;
;   DWORD dwRestorePtType;
;   INT64 llSequenceNumber;
;   TCHAR szDescription[MAX_DESC];
; } RESTOREPOINTINFO, *PRESTOREPOINTINFO;
Structure RESTOREPOINTINFO
	dwEventType.i
	dwRestorePtType.i
	llSequenceNumber.q
	szDescription.s{#MAX_COLUMN_DESC_LEN}
EndStructure

; typedef struct _SMGRSTATUS {
;   UINT  nStatus;
;   INT64 llSequenceNumber;
; } STATEMGRSTATUS, *PSTATEMGRSTATUS;
Structure STATEMGRSTATUS
	nStatus.l
	llSequenceNumber.q
EndStructure

Procedure.b Failed(hr.l)
	ProcedureReturn hr <> #S_OK
EndProcedure

Procedure.s PBSetRestorePoint()
   Protected RestorePtInfo.RESTOREPOINTINFO
   Protected SMgrStatus.STATEMGRSTATUS
   Protected dwErr.l = #ERROR_SUCCESS
   Protected hSrClient.l = #Null
   Protected hr.i = #S_OK
   Protected fRet.b = #False
   Protected *pFunc.l = #Null
  
   hr = CoInitializeEx_(#Null, #COINIT_MULTITHREADED )
   If Failed(hr)
   	ProcedureReturn "Unexpected error: CoInitializeEx() failed with " + Str(hr) + "."
   EndIf

   ; Initialize COM security To enable NetworkService,
   ; LocalService And System To make callbacks To the process
   ; calling  System Restore. This is required For any process
   ; that calls SRSetRestorePoint.
   
   ; fRet = InitializeCOMSecurity_()
		hr =  CoInitializeSecurity_(#Null, -1, #Null, #Null, #RPC_C_AUTHN_LEVEL_DEFAULT, #RPC_C_IMP_LEVEL_IMPERSONATE, #Null, #EOAC_NONE, #Null);
   If Failed(hr)
   	ProcedureReturn "Unexpected error: failed to initialize COM security. (" + Str(hr) + ")"
   EndIf
   
   ; Initialize the RESTOREPOINTINFO Structure
   RestorePtInfo\dwEventType = #BEGIN_SYSTEM_CHANGE;

   ; Notify the system that changes are about To be made.
   ; An application is To be installed.
   RestorePtInfo\dwRestorePtType = #APPLICATION_INSTALL;

   ; RestPtInfo.llSequenceNumber must be 0 when creating a Restore point.
   RestorePtInfo\llSequenceNumber = 0

   ; String To be displayed by System Restore For this Restore point.
   ;StringCbCopyW(RestorePtInfo.szDescription,
   ;      SizeOf(RestorePtInfo.szDescription),
   ;      L"First Restore Point");
   RestorePtInfo\szDescription = "PB Test Restore Point"
   
   ; Load the DLL, which may Not exist on Windows server
   ;hSrClient = LoadLibraryW(L"srclient.dll");
   hSrClient = LoadLibrary_("SrClient.dll")
   If hSrClient = #Null
   	ProcedureReturn "System Restore is not present."
   EndIf

   ; If the library is loaded, find the entry point
;    fnSRSetRestorePointW = (PFN_SETRESTOREPTW) GetProcAddress(
;       hSrClient, "SRSetRestorePointW");
;    If (NULL == fnSRSetRestorePointW)
;    {
;       wprintf(L"Failed to find SRSetRestorePointW.\n");
;       Goto exit;
;    }
	*pFunc = GetProcAddress_(hSrClient, "SRSetRestorePointA")
	If *pFunc = #Null
		ProcedureReturn "Failed to find SRSetRestorePointW. " + Str(GetLastError_())
	EndIf


;    fRet = fnSRSetRestorePointW(&RestorePtInfo, &SMgrStatus);
;    If(!fRet)
;    {
;       dwErr = SMgrStatus.nStatus;
;       If(dwErr == ERROR_SERVICE_DISABLED)
;       {
;          wprintf(L"System Restore is turned off.\n");
;          Goto exit;
;       }
;       wprintf(L"Failure to create the restore point; error=%u.\n", dwErr);
;       Goto exit;
;    }
; 
;    wprintf(L"Restore point created; number=%I64d.\n", SMgrStatus.llSequenceNumber);
	fRet = CallFunctionFast(*pFunc, @RestorePtInfo, @SMgrStatus)
	If Not fRet
		dwErr = SMgrStatus\nStatus
		If dwErr = #ERROR_SERVICE_DISABLED
			ProcedureReturn "System Restore is turned off. (Error code: " + Str(dwErr) + ")"
		EndIf
	EndIf

	; The application performs some installation operations here.
	MessageBox_(#Null, "ich mache was ;o)", "", #MB_OK)

   ; It is Not necessary To call SrSetRestorePoint To indicate that the
   ; installation is complete except in the Case of ending a nested
   ; Restore point. Every BEGIN_NESTED_SYSTEM_CHANGE must have a
   ; corresponding END_NESTED_SYSTEM_CHANGE Or the application cannot
   ; create new Restore points.

   ; Update the RESTOREPOINTINFO Structure To notify the
   ; system that the operation is finished.
   RestorePtInfo\dwEventType = #END_SYSTEM_CHANGE;

   ; End the system change by using the sequence number
   ; received from the first call To SRSetRestorePoint.
   RestorePtInfo\llSequenceNumber = SMgrStatus\llSequenceNumber;

   ; Notify the system that the operation is done And that this
   ; is the End of the Restore point.
;    fRet = fnSRSetRestorePointW(&RestorePtInfo, &SMgrStatus);
;    If(!fRet)
;    {
;       dwErr = SMgrStatus.nStatus;
;       wprintf(L"Failure to end the restore point; error=%u.\n", dwErr);
;       Goto exit;
;    }
	fRet = CallFunctionFast(*pFunc, @RestorePtInfo, @SMgrStatus)
	If Not fRet
		dwErr = SMgrStatus\nStatus
		ProcedureReturn "Failure to end the restore point; error=" + Str(dwErr)
	EndIf	
	
	If hSrClient <> #Null
		FreeLibrary_(hSrClient)
	EndIf
	CoUninitialize_()
	
	ProcedureReturn "alles gut :)"
 EndProcedure 
 
 
 MessageBox_(#Null, PBSetRestorePoint(), "", #MB_OK)
 
 End

Re: Systemwiederherstellungspunkt erstellen

Verfasst: 29.04.2011 22:54
von RSBasic
:shock:
Hallo shadow,


vielen lieben Dank für deine großzügige Arbeit! Ich bin begeistert. :allright:
Dein Code habe ich unter Windows XP getestet und funktioniert einwandfrei. :allright:
Funktioniert dieser Code auch unter Windows 7/Vista? (Ich kann den Code zurzeit nur unter XP testen.)
Danke nochmal für deine Umsetzung. :)

Re: Systemwiederherstellungspunkt erstellen

Verfasst: 29.04.2011 22:56
von shadow
Freut mich wenn ich helfen konnte :allright:

Ja, den Code habe ich unter Windows 7 getestet. Also unter Vista müsste es auch funktionieren.

Re: Systemwiederherstellungspunkt erstellen

Verfasst: 29.04.2011 22:58
von RSBasic
Danke. :)