ReneMiner
03-07-2021, 14:48
system image repair script
(required 7z.exe & 7z.dll (https://www.thinbasic.com/www.7-zip.org/download.html) and your windows installation media)
this uses DISM via Batch to proceed 5 steps of scanning, cleaning, repairing checking and verifying
the integrity of your windows components. It requires to repair some windows install media file
(install.wim) usually located in the sources-folder of a windows installation disk. Mostly these contain
multiple products as Windows Home, Pro, Education etc. the script will find the matching images
index - important that your image-version is not too much different from your systems build.
if your windows is maybe 10.0.19041 then you should not use anything lower than 10.0.18042
and the other way: if you have an install-media with a build number higher than your current os
then do not bother to repair but boot or load setup from the media sources and select "Update only"
that will not overwrite any of your data nor format your drive and whatever drives you to feel in
need to repair something of your os might be fixed in the newer version of windows.
Anyway the first two steps will tell you whether your system image is healthy or not and step 3
would repair corrupted data, step 4 is to check the integrity of the repairs and the final scan will
test the complete image to be able to announce a reliable result. Depending on your system all
can be done within 2 and 35 minutes.
If Dism complains about invalid syntax or unknown commands then your system is really in bad
condition. Run CMD as Admin and enter "sfc /scanNow"
btw.for thinAir.exe and thinBasic.exe i have set compatibillity-settings - both run as Admin always
so i dont know if you require elevated rights
uses "Console", "Ini", "UI"
' this script makes use of commandline functions and of the 7z-commandline-version
' to get access to all by 7z supported types of archives. If 7z is installed on your pc
' it might find it through registry-settings. If you have it somewhere - unregistered - and its not
' somewhere nearby the script it will prompt you to point a location or to download it
' It uses 7z.exe and 7z.dll only, so its enough to have these 2 files somewhere but since 7z.exe
' will not work without 7z.dll - both files should be in the same directory
' Here it's used to search some information about windows image media (wim-files).
'#########################################################################
'### 7z ### 7z ### 7z ### 7z ### 7z ### 7z ### 7z ### 7z ### 7z ### 7z ###
'#########################################################################
' #############################################=+
' ##############################################+
' ####~~~~~~~~~~~~~~~~+*##=.~~~~~~~~~~~~~~.-=###+
' ##=+ -=##=. .-=###+
' ###=~-+***++~-. -=###=. .-=###+ **
' #########=*+-. -~+*##=. .-=###+
' #######=*+-. -~+*=###=. .-=###+
' #####=*+-. -~+*=#####=~ ............ .-=###+
' ###=*+-. -~+*=#######=. =##########= .~=###+
' #####= .~+*=########=. +=#=+- .-=###+
' ####=. .~=###########=. +=#=+- .-=###+
' ####= .=#############=. +=#=+- .-=###+
' ###=~ .=#############=. +=#=+- .-=###+
' ###=~ .+=############=. +=#=+-.... .-=###+
' ####= .=##############=. ~=########=+ .-=###+
' #####=..~=##############=................~=###+
' #########################===============+*=###+
' ##############################################+
' (c) by Igor Pavlov 1999 - 2019
' credits for his great, worldwide appreciated, outstanding tool
' to the genious IGOR PAVLOV
' for further information and the latest updates on 7z visit
' ###################
' # #
' www.7-zip.org
' # #
' ###################
' find help and support about 7z on: www.7-zip.org/support.html
'===============================================================================
' If your windows installation media comes as .ESD-file look for
' a tool named "DISM++' that is capable of extracting data from
' esd to become generic wim .
'===============================================================================
' Anything else here is just minimum of commandline-functions (extracted of a unit that covers
' nearly all commandline-keywords but its size would not make sense with the just 5 executed
' commands of this script , a tiny bit of UI for the dialogs only and ini for this and that
FUNCTION Exist(byval sPath as string) as Boolean
' commandline-check if a pathname is an existing object.
' Must end with "\" to test for a folder
' may contain %environment_variables% and wildcards * ?
string sCMD, sResult
if lenf(sPath) then
sCMD = "cmd.exe /c " & $DQ & "cmd /c IF EXIST " & IIf$(instr(sPath, Any $MustBeQuoted,1), wrap$(sPath, $DQ, $DQ), sPath) & " ECHO TRUE ELSE ECHO FALSE " & $DQ
sResult = Shell_CaptureOutput(sCMD,"", %sw_HIDE, 2000)
function = ( instr(sResult, "TRUE", 1) <>0 )
EndIf
End Function
'===============================================================================
function Reg_FixRoot(byref sKey as string) as Boolean
' check for the correct abbrev.
sKey = ucase$(sKey)
if instr(sKey,"HKEY",1) then
sKey = Replace$(sKey,"HKEY_CLASSES_ROOT\", "HKCR\")
sKey = Replace$(sKey,"HKEYCR\", "HKCR\")
sKey = Replace$(sKey,"HKEY_CURRENT_USER\", "HKCU\")
sKey = Replace$(sKey,"HKEYCU\", "HKCU\")
sKey = Replace$(sKey,"HKEY_LOCAL_MACHINE\", "HKLM\")
sKey = Replace$(sKey,"HKEYLM\", "HKLM\")
sKey = Replace$(sKey,"HKEY_USERS\", "HKU\")
sKey = Replace$(sKey,"HKEYU\", "HKU\")
sKey = Replace$(sKey,"HKEY_CURRENT_CONFIG\", "HKCC\")
sKey = Replace$(sKey,"HKEYCC\", "HKCC\")
EndIf
End Function
'===============================================================================
function Reg_GetVal( byval sKeyPath as string,
optional byval sSetting as string ) as string
'"[\\computername\]{HKCR|HKCU|HKLM|HKU|HKCC}\[...\]subkey"
' returns the value for ONE in sSetting specified setting as string
' this function will not take wildcards (*) since it returns a specific setting only
' pass "" or "@" to sSetting to get the standard settings value
' or pass a name of the setting thats value you request
' returns "" if setting is empty (Reg_SZ, Reg_MultiSZ or Reg_ExpandSZ, Reg_BINARY)
' "0x00000000" Dword (10 digits including 0x)
' 0x0000000000000000 QWORD
' if startswith(sResult, $NUL) then
' means Error
' if lenf(sResult) = 1 then
' means error in the parameters that you passed
' else
' Error-message = remove$(sResult,$NUL)
' ( localized to users language )
' Endif
'Endif
' for remotecomputers only HKU and HKLM are available
string sResult, sPart()
long nParts
if lenf(sKeypath) < 5 then return $nul
if instr(sSetting, "*", 1) then return $Nul
Reg_FixRoot(sKeyPath)
select case ucase$(sSetting)
case "", "@", "/VE"
sSetting ="/ve"
case else
if startswith(ucase$(sSetting), "/V ") then RETURN $nul
if instr(sSetting, $Spc, 1) then
sSetting = "/v " & $dq & sSetting & $dq
else
sSetting = "/v " & sSetting
endif
sSetting &= " /reg:64"
end select
sResult = Shell_CaptureOutput("Reg Query " & $DQ & sKeypath & $DQ & $spc & sSetting, ,%SW_Hide, 1500)
while instr(sResult," ",1)
sResult=replace$(sResult, " "," ")
wend
nParts=Parse sResult, sPart, " "
if nParts < 4 then return $NUL & sResult
WHILE nParts >= 4
sPart(nParts)=remove$(sPart(nParts), any $DQ & crlf)
sPart(nParts)=TrimFull$(sPart(nParts))
if lenf(sPart(nParts)) then return sPart(nParts)
decr nParts
Wend
function = ""
end function
'===============================================================================
function LocateInstallWim( byref toPath as string,
byval sProduct as string,
byval sBuild as string ) as Long
' returns image-index
' byref passed toPath will hold the selected path then
string sPath, sData, sVersion, sImage()
long nImages, i , b1, b2, b3
toPath = Dialog_OpenFile(%hwnd_desktop, "Select your installation media",
sLastMediapath, "Windows Install Media (*.WIM)|*.wim|All Files (*.*)|*.*",
"Install.wim", %OFN_EXTENSIONDIFFERENT | %OFN_EXPLORER |
%OFN_LONGNAMES | %OFN_ENABLESIZING | %OFN_PATHMUSTEXIST | %OFN_FILEMUSTEXIST )
if toPath = "" then return 0
if $7z="NoCheck" then return 1
PrintL
printl "Verify build and product..." in %ccolor_fyellow
nImages = parse toPath, sImage, "\"
sLastMediaPath = remove$(toPath, sImage(nImages))
ini_setkey(APP_IniFile, "LastMedia", "Path", sLastMediaPath)
shell( $7z ," e " & toPath & " -o" & App_scriptpath & " -aoa [1].xml" )
sData=Load_File(APP_ScriptPath & "[1].xml")
if not IsUtf8(sData) then sData = WideCharToUTF8$(sData)
sVersion = GrabF$(sData, "<PKEYCONFIGVERSION>","</PKEYCONFIGVERSION>")
if lenf(sVersion) = 0 then
printl "No build version found" in %ccolor_flightred
else
if instr(sVersion, ";", 1) then sVersion=leftf$(sVersion, instr(sVersion, ";", 1) - 1)
printl "Build version detected: " & sVersion in %CColor_fintensewhite
nimages=1
parse sBuild, sImage, "."
while nImages < ubound(sImage)
if startswith(sVersion, sImage(1)) then
incr nImages
sImage(1) &= "." & sImage(nImages)
else
exit While
endif
wend
PrintL
sImage(1)=leftf$(sBuild,instr(sBuild,".",1)-1)
printl $Divide in %CCOLOR_FLIGHTCYAN
select case nImages
Case 1
printl "Not matching Windows " & str$(sImage(1)) in %ccolor_flightred
printl "this is for sure not a source to repair your OS"
return 0
case 2
printl "Matching Windows " & sImage(1) & ", but not the same edition." in %ccolor_fyellow
printl "Can not be the media of your installation." in %ccolor_flightred
printl "insufficient match " & sImage(1) & "." & sImage(2) in %ccolor_flightred
return 0
case 3
printl "Matching your windows version" & sImage(1) & "." & sImage(2) in %ccolor_flightgreen
printl "But a different build :" & sImage(3) in %ccolor_fyellow
sVersion = rightf$(sVersion, lenf(sVersion) -( lenf(sImage(1)) +lenf(sImage(2))+2))
sVersion = leftf$(sVersion, instr(sVersion,".",1)-1)
b1= val(sImage(3))
b2= val(sVersion)
if b2 + 999 < b1 then
printl "This image " & sVersion & " is too old to be used for repairs of " & sImage(3) in %ccolor_flightred
elseif b1 +500 < b2 Then
printl "Your installed OS is way older than the selected windows image" & sVersion in %ccolor_flightred
printl "Recommended to upgrade over repair. Boot the media or choose setup from sources and select update only" in %ccolor_flightblue
elseif b1 < b2 then
printl "Your installed OS is slightly older than the selected windows image" & sVersion in %ccolor_fyelLOW
printl "If your installation needs to be fixed it were probably better to think about" in %ccolor_flightblue
printl "upgrading your windows to " & version & " instead of repairing issues that might be" in %ccolor_flightblue
printl "fixed already in the newer version. Boot the media or choose setup from sources and select update only" in %ccolor_flightblue
endif
case 4
printl "Matching build detected. It is another revision" & str(sImage(4)) in %ccolor_fyelLOW
printl "but can be used for repairs." in %ccolor_flightgreen
b1 = val(sImage(4))
b2 = val(rightf$(sVersion, lenf(sVersion)-instr(sVersion,".",3)))
if b2 > b1 Then
printl "If your OS is having any problems, especially such that appeared repeatedly" in %ccolor_fyelLOW
printl "and were fixed before you should consider to upgrade windows using the image" in %ccolor_fyelLOW
printl "that you selected as repair-source. Start as if you want to install - but then" in %ccolor_flightblue
printl "when you are asked what to do, select update only and there is a good chance" in %ccolor_fyelLOW
printl "that the reason of your issue is already fixed in the newer version." in %ccolor_fyelLOW
EndIf
case 5
printl "Matching 100%. Its an identical source, fitting exactly and can be" in %ccolor_flightgreen
printl "used to repair your installation without any doubt" in %ccolor_flightgreen
End Select
endif
printl $Divide in %CCOLOR_FLIGHTCYAN
nImages=parse sData, sImage, "<IMAGE INDEX=" & $DQ
if nImages > 1 then
for i= 1 to nImages - 1
sImage(i) = grabf$(sImage(i+1), "<DISPLAYNAME>", "</DISPLAYNAME>")
printl i, sImage(i)
if ucase$(sProduct) = ucase$(sImage(i)) then
PRINTL "Image " & tstr$(i) & " contains the same type of product as the one that you have installed" in %ccolor_fLightblue
return i
endif
next
endif
printl $Divide in %CCOLOR_FLIGHTCYAN
printl "There was no matching product to your current OS found." in %ccolor_flightmagenta
printl "I am not able to decide which or if any of this disk is" in %ccolor_flightmagenta
printl "the correct image and could be used without a doubt." in %ccolor_flightmagenta
FUNCTION = -1
end function
'===============================================================================
function Detect_7z() as string
long lPos, nFiles
local b as byte at 0
string sPath, s7z, sFile()
s7z = Reg_getval("HKLM\SOFTWARE\7-Zip", "Path")
Console_BackgroundRGB(0,0,1,0)
if all(lenf(s7z), not startswith(s7z, $Nul) ) then
s7z &= "7z.exe"
if exist(s7z) then
if exist( replace$(s7z, "exe", "dll" ) ) then return s7Z
endif
endif
s7z = Reg_GetVal( "HKCR\7-Zip.7z\shell\open\command" )
if all(lenf(s7z), not startswith(s7z, $Nul), not startswith(s7z, "(") ) then
IF ENDSWITh(ucase$(s7z), "7ZFM.EXE %1") then s7z = leftf$(s7z, lenf(s7z) - 9 ) & ".exe"
if exist(s7z) then
if exist( replace$(s7z, "exe", "dll" ) )then return s7Z
endif
EndIf
s7z = Shell_CaptureOutput( "Dir " & $DQ & APP_Path & "*7z.exe /a-D /b /s", "", %sw_hide, 250)
if not instr(ucase$(s7z), "7Z.EXE", 1 ) then
s7z = Shell_CaptureOutput( "Dir " & $DQ & APP_scriptPath & "*7z.exe /a-D /b /s", "", %sw_hide, 250)
if not instr(ucase$(s7z), "7Z.EXE", 1 ) then
s7z = Shell_CaptureOutput ("Dir ""%programfiles% (x86)\7*z*\7z.exe"" /a-D /b", "", %sw_hide, 250)
if not instr(ucase$(s7z), "7Z.EXE", 1 ) then
s7z = Shell_CaptureOutput ("Dir ""%programfiles%\7*z*\7z.exe"" /a-D /b", "", %sw_hide, 250)
endif
endif
endif
if instr(ucase$(s7z), "7Z.EXE", 1) Then
nFiles = parse s7z, sFile, crlf
lPos = 1
while nFiles >= lPos
s7z=trimfull$(sFile(lPos))
IF ENDSWITH(S7z,"7Z.EXE") then
sFile(1)=replace$(s7z, ".EXE", ".DLL")
if exist(sFile(1)) then
if Exist(s7z) then return s7Z
endif
endif
incr lpos
wend
endif
printl $Divide in %CCOLOR_FLIGHTCYAN
printl "Unable to locate 7z.exe, It is required to verify the windows-image"
printl "that is to be used to repair defective data matches the version of"
printl "the operating system, Select an option please:"
printl
printl $Divide in %CCOLOR_FLIGHTCYAN
printl " [1] navigate to the path where 7z can be found" in %ccolor_fintensewhite
printl " [2] download and install 7-zip" in %ccolor_fintensewhite
printl "[ESC] abort this script" in %ccolor_fintensewhite
printl
select case waitkey
case "[ESC]"
Stop
case "[1]"
sPath = Dialog_BrowseForFolder( %hWnd_desktop, "Select a folder that contains 7z.exe and 7z.dll", App_scriptpath, true)
if lenf(sPath) then
if exist(sPath & "7z.exe" ) then
if exist( sPath & "7z.dll") then return sPath & "7z.exe"
endif
EndIf
case "[2]"
lPos = 999
end Select
printl $Divide in %CCOLOR_FLIGHTCYAN
if not LPos = 999 Then
msgbox("Suggest to download 7z." & crlf _
& "Select what fits to your" & crlf _
& "system and meets your needs" & crlf _
& "Restart this script when 7z" & crlf _
& "is ready to be used.", %mb_iconinformation,
"get some essential software...")
endif
sPath=app_path & "samplescripts\ui\webbrowser\"
s7z = ini_getKey(sPath & "miniWebbrowser.ini", "LAST", "URL", "https://www.thinbasic.com/community")
INI_SetKey(sPath & "miniWebbrowser.ini", "LAST", "URL", "https://www.7-zip.org/download.html")
shell( sPath & "miniWebbrowser.tBasic", "" )
INI_SetKey(sPath & "miniWebbrowser.ini", "LAST", "URL", s7z)
SHELL("EXPLORER.exe " & $DQ & APP_ScriptPath & $DQ,"")
End Function
'===============================================================================
#region "FixedValues"
begin const
%CaseSensitivityOff = Off
$Divide = $crlf & repeat$(40,"><") & $crlf
$MustBeQuoted = " %()[]{}^=;!'+,`~" ' chars that must be wrapped in $DQ if used in a path
$7z = Detect_7z
end const
#EndRegion
'===============================================================================
global sLastMediapath as string = INI_GetKey(APP_IniFile, "LastMedia", "Path", app_scriptpath )
function tbmain()
string order, sPath, sProductName, sBuild, sTest, sPart()
Long i, Index, nParts
printl $Divide in %CCOLOR_FLIGHTCYAN
printl " +++ 5-Step-OS-CleanUp-Program +++" in %CCOLOR_FLIGHTCYAN
printl $Divide in %CCOLOR_FLIGHTCYAN
printl
sProductName = Reg_GetVal( "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "Productname")
Save_File(APP_ScriptPath & "version.bat", "@echo off" & crlf & "Dir %systemroot%\servicing\version\1* /AD /B >" & app_scriptpath & "version.txt" & crlf & $spc )
Shell(APP_ScriptPath & "version.bat", "")
sBuild=Load_File(APP_ScriptPath & "version.txt")
printl "servicing installation of " & sProductname & ", Build " & sBuild in %CCOLOR_FLIGHTMAGENTA
printl
printl "It requires the installation media of your operating system" in %ccolor_fyellow
printl "or the install.wim-file, usually to find in the ""\sources-folder""" in %ccolor_fyellow
printl "if the windows-image is located within an .iso-file, please mount it" in %ccolor_fyellow
printl "and then navigate to its root or \sources-path." in %ccolor_fyellow
printl $Divide
repeat
PrintL
printl "Press [esc] to cancel or any other key or just click here when ready to browse for the location"
select case waitkey
case "[ESC]"
stop
case else
Index = LocateInstallWim(sPath, sProductname, sBuild)
end Select
until Index<>0
IF INDEX <0 then index=1
for i = 1 to iif($7z="NoFix",3,5)
order = "dism /online /cleanup-image /" & choose$(i, "scanhealth", "checkhealth", "restorehealth /source:wim:" & sPath & ":" & tstr$(Index) & " /limitAccess", "startcomponentcleanup", "AnalyzeComponentstore") & crlf & $spc
printl i, order
save_file( app_scriptpath & "Step" & tstr$(i) & ".bat", "@echo off" & crlf & order)
shell( app_scriptpath & "Step" & tstr$(i) & ".bat", "")
next
printl $Divide in %CCOLOR_FLIGHTmagenta
printl
if i > 4 then
printl "Cleaning program completed" in %ccolor_flightgreen
Else
printl "Program ends here since it only checked if repairs are necessary"
EndIf
PrintL
printl $Divide in %CCOLOR_FLIGHTCYAN
printl "press any key to end" in %ccolor_fyellow
waitkey
end function