Jump to content

Recommended Posts

What exactly do you mean by "offline"?

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2021-11-10 - Version 1.6.0.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (NEW 2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (NEW 2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to post
Share on other sites

I don't know if it is coincidence but my Windows 8 shows as Windows 6.2 and if you right click on Kernel32.dll it shows file version 6.2 and a whole bunch of trailing numbers.  If you have booted something Windows you could try calling FileGetVersion on the kernel32.dll that is on the offline disk.

 

Link to post
Share on other sites

I am using WinPE to capture a installed Windows on the HDD wich at that moment is an offline installation, i am using a little script to capture a .WIM file and saving it to a network share, only problem that i am having now is when i select the driveletter it does not show wich Windows is installed on that drive.

Does anyone have an idea how to get it to work?

V0.0.au3

Edited by Wingens
Link to post
Share on other sites

You need to learn a little about scopes. Local, Global, etc. This should be a good read. :)
https://www.autoitscript.com/wiki/Variables_-_using_Global,_Local,_Static_and_ByRef

Your script detects "Vista or Above" for me.

2015-05-27_1004.png

Also, I'm not sure checking for @ProgramFiles & "\Windows Mail" is the best way to determine a Windows Vista+ system. I recommend checking 'ntoskrnl.exe'.

Here is a little example I just threw together to detect offline OS version, by first detecting the NT kernel version.
An updated version if further down in this post.

#include <WinAPIFiles.au3>
_WinAPI_Wow64EnableWow64FsRedirection(False) ;Stops 32bit compiled programs
;from being redirected to C:\Windows\SysWOW64 on 64bit Systems, instead of C:\Windows\System32.

$Drive = FileSelectFolder("Select Drive", "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}")
$NT_Kernel = $Drive & "Windows\System32\ntoskrnl.exe"
If FileExists($NT_Kernel) Then
    $Version = FileGetVersion($NT_Kernel) ;Gets Complete NT Version.
    ConsoleWrite("OS Ver: " & $Version & @CRLF)
    $OS = _GetOSFromNTVersion($Version)
    ConsoleWrite("OS_Name: " & $OS)
EndIf

Func _GetOSFromNTVersion($pNT_Version)
    Local $lVersion_Array[1], $lOS_Name
    $lVersion_Array = StringSplit($pNT_Version, ".")
    If IsArray($lVersion_Array) Then
        Switch $lVersion_Array[1]
            Case 5
                Switch $lVersion_Array[2]
                    Case 0
                        $lOS_Name = "Windows 2000"
                    Case 1
                        $lOS_Name = "Windows XP"
                    Case 2
                        $lOS_Name = "Windows Server 2003";This NT version is used for XP X64, Server 2003, Server 2003 R2, and Windows Home Server. But primarily identifies as Server 2003, in my experience.
                    Case Else
                        Return SetError(1,0,0)
                EndSwitch
            Case 6
                Switch $lVersion_Array[2]
                    Case 0
                        $lOS_Name = "Windows Vista"
                    Case 1
                        $lOS_Name = "Windows 7"
                    Case 2
                        $lOS_Name = "Windows 8"
                    Case 3
                        Switch $lVersion_Array[3] ;Windows Build#, I think.
                            Case 9200-9600
                                $lOS_Name = "Windows 8.1"
                            Case Else
                                $lOS_Name = "Windows 10"
                        EndSwitch
                    Case Else
                        Return SetError(2,0,0)
                EndSwitch
            Case Else
                Return SetError(3,0,0)
        EndSwitch
    Else
        Return SetError(4, 0, 0)
    EndIf

    Return $lOS_Name

EndFunc   ;==>_GetOSFromNTVersion

;   6.3.10074 = Current Windows 10 Beta
;    6.3 = Windows 8.1
;    6.2 = Windows 8
;    6.1 = Windows 7
;    6.0 = Windows Vista
;    5.2 = Windows Server 2003
;    5.1 = Windows XP
;    5.0 = Windows 2000
;    4.0 = Windows NT 4

It is, by no means, complete or even tested very well... But should be a good start.

Here's the sources I tried to pull the NT Version information from.

http://en.wikipedia.org/wiki/Windows_NT

http://www.mskbfiles.com/ntoskrnl.exe.php

http://www.geoffchappell.com/studies/windows/km/ntoskrnl/history/index.htm

==== Added 3 hours after initial post ==== This might help more, just give it a look. B)

#include <WinAPIFiles.au3>
_WinAPI_Wow64EnableWow64FsRedirection(False) ;Stops 32bit compiled programs
;from being redirected to C:\Windows\SysWOW64 on 64bit Systems, instead of C:\Windows\System32.

$Drive = FileSelectFolder("Select Drive", "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}")
$OS_Name = _GetOfflineOS($Drive)
ConsoleWrite("OS: " & $OS_Name)

Func _GetOfflineOS($pDrive) ;Gets the OS Name from the default Windows Install
    $lWindows_DIR = _FindOSInstallDIR($pDrive)
    If @error Then Return SetError(5,0,0)

    $lNT_Kernel = $lWindows_DIR & "\System32\ntoskrnl.exe"
    $lNT_Version = FileGetVersion($lNT_Kernel)

    Local $lVersion_Array[1], $lOS_Name
    $lVersion_Array = StringSplit($lNT_Version, ".")
    If IsArray($lVersion_Array) Then
        Switch $lVersion_Array[1]
            Case 5
                Switch $lVersion_Array[2]
                    Case 0
                        $lOS_Name = "Windows 2000"
                    Case 1
                        $lOS_Name = "Windows XP"
                    Case 2
                        $lOS_Name = "Windows Server 2003";This NT version is used for XP X64, Server 2003, Server 2003 R2, and Windows Home Server. But primarily identifies as Server 2003, in my experience.
                    Case Else
                        Return SetError(1, 0, 0)
                EndSwitch
            Case 6
                Switch $lVersion_Array[2]
                    Case 0
                        $lOS_Name = "Windows Vista"
                    Case 1
                        $lOS_Name = "Windows 7"
                    Case 2
                        $lOS_Name = "Windows 8"
                    Case 3
                        Switch $lVersion_Array[3] ;Windows Build#, I think.
                            Case 9200 - 9600
                                $lOS_Name = "Windows 8.1"
                            Case Else
                                $lOS_Name = "Windows 10"
                        EndSwitch
                    Case Else
                        Return SetError(2, 0, 0)
                EndSwitch
            Case Else
                Return SetError(3, 0, 0)
        EndSwitch
    Else
        Return SetError(4, 0, 0)
    EndIf

    Return $lOS_Name

EndFunc   ;==>_GetOfflineOS

Func _FindOSInstallDIR($pDrive)
    Local $lSearch1, $lSearch2, $lFileName1, $lFileName2
    $lSearch1 = FileFindFirstFile($pDrive & "*.*") ; Initiate Search in Drive root.

    ; Check if the search was successful.
    If $lSearch1 = -1 Then Return SetError(1,0,0) ; Return if Search fails.

    While 1
        $lFileName1 = FileFindNextFile($lSearch1)
        If @error Then ExitLoop; ExitLoop after all files have been listed.
        If @Extended = 1 Then ; Restrict output to directories.
            ;ConsoleWrite("File: " & $lFileName1 & @CRLF) ; Print Directories for debugging.
            $lSearch2 = FileFindFirstFile($pDrive & $lFileName1 & "\*.*") ;Search within directories in root for Windows install.
            If $lSearch2 = -1 Then ContinueLoop ; Skip over bad directories.
            While 1
                $lFileName2 = FileFindNextFile($lSearch2)
                If @error Then ExitLoop
                If @extended = 1 Then
                    ;ConsoleWrite("File2: " & $lFileName2 & @CRLF)
                    If $lFileName2 = "System32" Then
                        ;Probably the Windows Install.
                        If FileExists($pDrive & $lFileName1 & "\" & $lFileName2 & "\ntoskrnl.exe") Then
                            FileClose($lSearch1)
                            FileClose($lSearch2)
                            Return $pDrive & $lFileName1
                        EndIf
                    EndIf
                EndIf
            WEnd
        EndIf
    WEnd
EndFunc

;X86 Versions
;5.1.2600.0 Windows XP
;5.1.2600.1106  Windows XP SP1
;5.1.2600.2180  Windows XP SP2
;5.1.2600.5512  Windows XP SP3
;5.2.3790.0     Windows Server 2003
;5.2.3790.1830  Windows Server 2003 SP1
;5.2.3790.3959  Windows Server 2003 SP2
;6.0.6000.16386     Windows Vista
;6.0.6001.18000     Windows Vista SP1, Windows Server 2008
;6.0.6002.18005     Windows Vista SP2
;6.1.7600.16385     Windows 7
;6.1.7601.17514     Windows 7 SP1
;6.2.9200.16384     Windows 8

;X64 Versions
;5.2.3790.1830 Windows Server 2003 SP1
;5.2.3790.3959 Windows Server 2003 SP2
;6.0.6000.16386 Windows Vista
;6.0.6001.18000 Windows Vista SP1, Windows Server 2008
;6.0.6002.18005 Windows Vista SP2
;6.1.7600.16385 Windows 7, Windows Server 2008 R2
;6.1.7601.17514 Windows 7 SP1, Windows Server 2008 R2 SP1
;6.2.9200.16384 Windows 8
;6.3.10074 = My current Windows 10 version.

 

Summery: The above script provides the base for detecting an offline install DIR, by searching through folders until the System32 folder is found and then checking for the existence of ntoskrnl.exe. I advise adding more parameters for identification. Ex; Check for "Users", the existence of registry hives, compare the size of the OS Install Folder (Windows?), and you could even compare against other files like "Kernel32.dll". Once the OS install folder has been identified, you can then take note of the version outputs of ntoskrnl.exe and Kernel32.dll to determine the installed OS. My version is incomplete and could possibly say that certain version of Windows 8 are actually Windows 10, because I used "Case Else" rather than specifics.

Another possibility is loading the offline registry hive and checking values for more information. ^.^

Edited by BinaryBrother

SIGNATURE_0X800007D NOT FOUND

Link to post
Share on other sites

For what it's worth, on my machine ntoskrnl.exe and kernel32.dll both show product version 6.2.9200.16384

​That script would tell you that you're running Windows 8, pre 8.1.

The 6.2 kernel is quickly becoming outdated. Well... it is outdated, technically. A lot of the changes occurring in Windows 10, are actually present in the 6.3 kernel, as well. You need to update to 6.3 or Windows 8.1 for some performance and stability improvements! :rambo:

I would recommend Windows 10, but it's pretty much Beta and I have a few functionality issues with it. Not to mention the "Updates" for one version to another are OS reinstalls, right now... :mad2:  The performance improvement is too vast to ignore, though. I am running Windows 10 on an old IBM ThinkCentre, 3GB DDR2, Pentium 4 HT 3.2Ghz, and it is actively being used as the entire office server for;

1.) A Windows Offline Update Server.
2.) CIFS backup server which syncs [in realtime] to a cloud source. Hosting all customer and office backups.
3.) Runs my "TechCenter", which is a compilation of network shared tools that are updated every day @ 7am.
4.) A partial mirror of MSDN. [Just OS ISOs and Office Suits]. Which, surprisingly, is only around ~40GB.
5.) A source for me to Burn OS discs and make bootable flashdrives.

I pretty much use this thing for everything... I've got a Dual-Core i3 3Ghz, 6GB DDR3, sitting right next to it that is never used. They are very competitive in the speed that they complete tasks. I am only limited on the IBM by the speed of the HDD, it seams, which is 1.5Gbps, because of old SATA. However, with a 1Gbps NIC, It's still a faster server than the i3, because the i3 has a 10/100 NIC. All in all, I average around 700-900Mbps. *Which I just tried to confirm, but I am using a 10 year old Cat5 cable that I need to change, so I couldn't generate an accurate report.

My primary point is that, if Windows 10 can be installed onto a 12 year old IBM and run like a $349 Walmart special... Then Windows 10 is accomplishing something. ^.^
For the record, I did see similar performance from Windows 8.1 on this same machine, but Windows 10 performance is more comparable to Windows XP, on this machine. With Windows 10's memory management being much better, Windows 10 is unusually responsive on this unit... I don't know enough about hardware specs to know exactly why, but someone said the front-side bus is 800Mhz, which attributes a bit to making these units snappy. Outside that, though, Windows 10 just makes this thing worth something again, after 12 years.

Also, sorry for being so far off topic, I just Love Windows 10... :P

 

 

​Let us know how it turns out! ^_^

Edited by BinaryBrother
BrewManNH... >.>

SIGNATURE_0X800007D NOT FOUND

Link to post
Share on other sites

BinaryBrother, interesting information but what exactly does any of that have to do with what the OP was looking to do? You want to praise Windows 10? I'd suggest another thread for that, you're completely off topic for this one, even you realized that in your post so why do it?

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to post
Share on other sites

... what exactly does any of that have to do with what the OP was looking to do? ...

Why are you even picking on me BrewManNH? :laser:
I feel like I've helped more than hurt! I was just expressing a quick opinion! :ermm:

I've re-written this response like 5 times and I'm just going to leave it at this; My post did provide some relevant information that you have either ignored or overlooked. I have edited my previous post to better represent the relevant material. However, nothing was added or removed. Your post, ultimately, served only as a Personal Message to me, indicating that you'd prefer to keep opinions to a minimum... :huh:

ConsoleWrite(@CRLF& "FileGetVersion('winver.exe') = "&FileGetVersion("winver.exe") &@CRLF &@CRLF)

​I completely thought you goofed! Getting the version number of an app that returns the version number?! :blink:

After some testing, though... I can see that the version output of WinVer.exe reflects the actual version of WinVer.exe itself, which is the OS Kernel version. No difference appears to exist in collecting the version from WinVer, ntoskrnl.exe, and Kernel32.dll. They should all report the exact same Kernel version #, up to Major.Minor.Build... The 4th attribute may be some-sort of build variant, but doesn't seem to cause any issues. The 4th attribute may vary between ntoskrnl.exe and Kernel32.dll, but everything else should be the same.

*Ahem, all of the below is related to Windows 10, ignore if unneeded...

I'm not sure if offline Windows 10 installations are being messed with, by the OP, but here's a warning nonetheless.
AutoIt and Windows 10 aren't working well together for the collection of kernel version numbers... Check this out.

OS: Windows 10
WinVer:           AutoIt - 6.3.10074.1 |  Manual Check: 10.0.10074.0
Ntoskrnl.exe: AutoIt - 6.3.10074.1 |  Manual Check: 10.0.10074.1
Kernel32.dll:  AutoIt - 6.3.10074.1 |  Manual Check: 10.0.10074.0

When you run this in AutoIt on Windows 10, Build 10074;

$lNT_Kernel = @SystemDir & "\ntoskrnl.exe"
$lNT_Version = FileGetVersion($lNT_Kernel)
ConsoleWrite($lNT_Version)

It will output "6.3.10074.1".

However, if you manually look at the version number of ntoskrnl.exe, in my case, it is 10.0.10074.1!

2015-05-29_1518.png

So AutoIt is seeing a different version than what is actually installed on Windows 10! I have tried with and without #RequireAdmin, with and without the 32bit redirect, and compiled as both X64 and X86 programs with all outputs being incorrect! I've also checked for compatibility mode and it was disabled.

Edited by BinaryBrother

SIGNATURE_0X800007D NOT FOUND

Link to post
Share on other sites

It's also possible to retrieve the OS full name in the offline Software registry hive by loading it with "reg load".

Windows version and service pack are stored in the two values ProductName and CSDVersion under the {sofware hive}\Microsoft\Windows NT\CurrentVersion

Sure, it's more complicated than using FileGetVersion, but it could work.

I cannot test it and don't know if it works with a WindowsPE environment (I think it's what you're using ?)

 

So maybe you can try my registry-based code and give me a feedback ?

#RequireAdmin

#include <WinAPIReg.au3>
#include <Security.au3>
#include <WinAPI.au3>


$sDrive = "X:"

$ret = _WinAPI_RegLoadKey($HKEY_USERS, "OfflineWindows", $sDrive "\windows\system32\config\software")
If Not @error Then
    $sVersion = RegRead("HKEY_USERS\OfflineWindows\Microsoft\Windows NT\CurrentVersion", "ProductName")
    $sServicePack = RegRead("HKEY_USERS\OfflineWindows\Microsoft\Windows NT\CurrentVersion", "CSDVersion")
    If $sVersion & $sServicePack <> "" Then MsgBox(0, "", "Offline operating system is : " & $sVersion & " " & $sServicePack)
    _WinAPI_RegUnloadKey($HKEY_USERS, "OfflineWindows")
EndIf


Func _WinAPI_RegUnloadKey($hKey, $sSubkey)
    _SetRESTORE_NAMEPrivilege()
    If @error Then Return SetError(@error)
    _SetBACKUP_NAMEPrivilege()
    If @error Then Return SetError(@error)

    Local $aRet = DllCall('advapi32.dll', 'long', 'RegUnLoadKeyW', 'handle', $hKey, 'wstr', $sSubkey)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aRet[0], 0, $aRet[0] = 0)
EndFunc

Func _WinAPI_RegLoadKey($hKey, $sSubkey, $sFile)
    _SetRESTORE_NAMEPrivilege()
    If @error Then Return SetError(@error)
    _SetBACKUP_NAMEPrivilege()
    If @error Then Return SetError(@error)
    
    Local $aRet = DllCall('advapi32.dll', 'long', 'RegLoadKeyW', 'handle', $hKey, 'wstr', $sSubkey, 'wstr', $sFile)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aRet[0], 0, $aRet[0] = 0)
EndFunc



Func _SetRESTORE_NAMEPrivilege()
; thanks SMOKE_N : https://www.autoitscript.com/forum/topic/165774-two-process-with-same-name-but-diferent-folder-how-close-one-specific/?do=findComment&comment=1210720

    Local $h_curproc = _WinAPI_GetCurrentProcess()
    Local $h_token = _Security__OpenProcessToken($h_curproc, _
        BitOR($TOKEN_ADJUST_PRIVILEGES, $TOKEN_QUERY))
    If Not $h_token Then
        Return SetError(2, 0, 0)
    EndIf

    Local $n_sdn = _Security__LookupPrivilegeValue("", $SE_RESTORE_NAME)

    Local $t_tokenpriv = DllStructCreate("dword;dword;long;dword")
    Local $p_tokenpriv = DllStructGetPtr($t_tokenpriv)
    DLLStructSetData($t_tokenpriv, 1, 1)
    DLLStructSetData($t_tokenpriv, 2, $n_sdn)
    DLLStructSetData($t_tokenpriv, 3, 0)
    DLLStructSetData($t_tokenpriv, 4, $SE_PRIVILEGE_ENABLED)
    Local $n_tokensize = DllStructGetSize($t_tokenpriv)

    Local $b_ret = _Security__AdjustTokenPrivileges($h_token, False, _
        $p_tokenpriv, $n_tokensize)

    _WinAPI_CloseHandle($h_token)

    Return SetError(Not $b_ret, 0, $b_ret)
EndFunc

Func _SetBACKUP_NAMEPrivilege() ; thanks SMOKE_N : https://www.autoitscript.com/forum/topic/165774-two-process-with-same-name-but-diferent-folder-how-close-one-specific/?do=findComment&comment=1210720
    Local $h_curproc = _WinAPI_GetCurrentProcess()
    Local $h_token = _Security__OpenProcessToken($h_curproc, _
        BitOR($TOKEN_ADJUST_PRIVILEGES, $TOKEN_QUERY))
    If Not $h_token Then
        Return SetError(2, 0, 0)
    EndIf

    Local $n_sdn = _Security__LookupPrivilegeValue("", $SE_BACKUP_NAME)

    Local $t_tokenpriv = DllStructCreate("dword;dword;long;dword")
    Local $p_tokenpriv = DllStructGetPtr($t_tokenpriv)
    DLLStructSetData($t_tokenpriv, 1, 1)
    DLLStructSetData($t_tokenpriv, 2, $n_sdn)
    DLLStructSetData($t_tokenpriv, 3, 0)
    DLLStructSetData($t_tokenpriv, 4, $SE_PRIVILEGE_ENABLED)
    Local $n_tokensize = DllStructGetSize($t_tokenpriv)

    Local $b_ret = _Security__AdjustTokenPrivileges($h_token, False, _
        $p_tokenpriv, $n_tokensize)

    _WinAPI_CloseHandle($h_token)

    Return SetError(Not $b_ret, 0, $b_ret)
EndFunc


 

Edited by jguinch
Link to post
Share on other sites

or just run DISM /Get-WIMInfo

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to post
Share on other sites

It's also possible to retrieve the OS full name in the offline Software registry hive by loading it with "reg load".

Windows version and service pack are stored in the two values ProductName and CSDVersion under the {sofware hive}\Microsoft\Windows NT\CurrentVersion

Sure, it's more complicated than using FileGetVersion, but it could work.

I cannot test it and don't know if it works with a WindowsPE environment (I think it's what you're using ?)

 

So maybe you can try my registry-based code and give me a feedback ?

#RequireAdmin

#include <WinAPIReg.au3>
#include <Security.au3>
#include <WinAPI.au3>


$sDrive = "X:"

$ret = _WinAPI_RegLoadKey($HKEY_USERS, "OfflineWindows", $sDrive "\windows\system32\config\software")
If Not @error Then
    $sVersion = RegRead("HKEY_USERS\OfflineWindows\Microsoft\Windows NT\CurrentVersion", "ProductName")
    $sServicePack = RegRead("HKEY_USERS\OfflineWindows\Microsoft\Windows NT\CurrentVersion", "CSDVersion")
    If $sVersion & $sServicePack <> "" Then MsgBox(0, "", "Offline operating system is : " & $sVersion & " " & $sServicePack)
    _WinAPI_RegUnloadKey($HKEY_USERS, "OfflineWindows")
EndIf


Func _WinAPI_RegUnloadKey($hKey, $sSubkey)
    _SetRESTORE_NAMEPrivilege()
    If @error Then Return SetError(@error)
    _SetBACKUP_NAMEPrivilege()
    If @error Then Return SetError(@error)

    Local $aRet = DllCall('advapi32.dll', 'long', 'RegUnLoadKeyW', 'handle', $hKey, 'wstr', $sSubkey)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aRet[0], 0, $aRet[0] = 0)
EndFunc

Func _WinAPI_RegLoadKey($hKey, $sSubkey, $sFile)
    _SetRESTORE_NAMEPrivilege()
    If @error Then Return SetError(@error)
    _SetBACKUP_NAMEPrivilege()
    If @error Then Return SetError(@error)
    
    Local $aRet = DllCall('advapi32.dll', 'long', 'RegLoadKeyW', 'handle', $hKey, 'wstr', $sSubkey, 'wstr', $sFile)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aRet[0], 0, $aRet[0] = 0)
EndFunc



Func _SetRESTORE_NAMEPrivilege()
; thanks SMOKE_N : https://www.autoitscript.com/forum/topic/165774-two-process-with-same-name-but-diferent-folder-how-close-one-specific/?do=findComment&comment=1210720

    Local $h_curproc = _WinAPI_GetCurrentProcess()
    Local $h_token = _Security__OpenProcessToken($h_curproc, _
        BitOR($TOKEN_ADJUST_PRIVILEGES, $TOKEN_QUERY))
    If Not $h_token Then
        Return SetError(2, 0, 0)
    EndIf

    Local $n_sdn = _Security__LookupPrivilegeValue("", $SE_RESTORE_NAME)

    Local $t_tokenpriv = DllStructCreate("dword;dword;long;dword")
    Local $p_tokenpriv = DllStructGetPtr($t_tokenpriv)
    DLLStructSetData($t_tokenpriv, 1, 1)
    DLLStructSetData($t_tokenpriv, 2, $n_sdn)
    DLLStructSetData($t_tokenpriv, 3, 0)
    DLLStructSetData($t_tokenpriv, 4, $SE_PRIVILEGE_ENABLED)
    Local $n_tokensize = DllStructGetSize($t_tokenpriv)

    Local $b_ret = _Security__AdjustTokenPrivileges($h_token, False, _
        $p_tokenpriv, $n_tokensize)

    _WinAPI_CloseHandle($h_token)

    Return SetError(Not $b_ret, 0, $b_ret)
EndFunc

Func _SetBACKUP_NAMEPrivilege() ; thanks SMOKE_N : https://www.autoitscript.com/forum/topic/165774-two-process-with-same-name-but-diferent-folder-how-close-one-specific/?do=findComment&comment=1210720
    Local $h_curproc = _WinAPI_GetCurrentProcess()
    Local $h_token = _Security__OpenProcessToken($h_curproc, _
        BitOR($TOKEN_ADJUST_PRIVILEGES, $TOKEN_QUERY))
    If Not $h_token Then
        Return SetError(2, 0, 0)
    EndIf

    Local $n_sdn = _Security__LookupPrivilegeValue("", $SE_BACKUP_NAME)

    Local $t_tokenpriv = DllStructCreate("dword;dword;long;dword")
    Local $p_tokenpriv = DllStructGetPtr($t_tokenpriv)
    DLLStructSetData($t_tokenpriv, 1, 1)
    DLLStructSetData($t_tokenpriv, 2, $n_sdn)
    DLLStructSetData($t_tokenpriv, 3, 0)
    DLLStructSetData($t_tokenpriv, 4, $SE_PRIVILEGE_ENABLED)
    Local $n_tokensize = DllStructGetSize($t_tokenpriv)

    Local $b_ret = _Security__AdjustTokenPrivileges($h_token, False, _
        $p_tokenpriv, $n_tokensize)

    _WinAPI_CloseHandle($h_token)

    Return SetError(Not $b_ret, 0, $b_ret)
EndFunc


 

​Thank you this works, i changed one register value that i use instead of the CSDVERSION i use: EditionID then i get a readout like: Starter, Home Premium etc.

More user friendly.

 

Thank you sow much guys!

Link to post
Share on other sites

​That script would tell you that you're running Windows 8, pre 8.1.

 

 

 

​Let us know how it turns out! ^_^

That is what I am running. I see no reason to update to 8.1.  This Laptop has booting issues.  It doesn't want to complete a Restore Point so I can just imagine how it would do with a live OS update through the store.  Afa day to dayuse, it ain't broke so I'm not gonna' fix it.  :)

 

 

Edited by MilesAhead
Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By DanielRossinsky
      What i'm trying to achieve is to bundle a few folders within the executable script and from what I've read it can be done with:
      #include <FileConstants.au3> FileInstall(src, dest, $FC_OVERWRITE) I know that src must be a literal string and cant be a variable or macro. However, I also learned that I cant just install a folder but there is a workaround that uses 7zip or winrar so that FileInstall extracts the folder to the desired location (e.g. to dest) so I wend and tried both variants: 
      I zipped a single folder just for testing. I winrared a single folder just for testing. Keep in mind that both the .zip and .rar are the same folder with the same content.
      The problem I ran into is that FileInstall simply moves the .rar or .zip folder to the desired location but it doesn't extract it!
      #RequreAdmin #include <FileConstants.au3> Func installESPLibraries() Local Const $sLibrariesPath = @LocalAppDataDir & "\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries" FileInstall("esp-libraries\ESP32-ADXL345.rar", $sLibrariesPath & "\", $FC_OVERWRITE) EndFunc installESPLibraries() The result I'm left with is that ESP32-ADXL345.rar just gets moved to $sLibrariesPath (so it does kinda work). The result I want is to have ESP32-ADXL345.rar extracted to the same location so that I have only a folder with the name ESP32-ADXL345 without any winrar files. Is there a way to achieve such a thing ? (because i'm sure there is).
      NOTE: I already did search the forum for such a solution:
      how to use fileinstall want to bundle my exe foldersfiles embedding images folders in exe However, They all show practical examples with files and none with folders (the third link mentions folders but has no examples) so I am at a loss as to how it should be done.
       
      EDIT:
      Thanks to @Musashi and @Nine for pointing out what I was missing! Also, I would like to add my solution:
      #RequreAdmin #include <FileConstants.au3> ; Create a local constant string to hold a path to the folder where we will be installing the libraries Local Const $sLibrariesPath = @LocalAppDataDir & "\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\" ; Unpack libraries.rar to the path we defined FileInstall("libraries.rar", $sLibrariesPath, $FC_OVERWRITE) ; Run the batch script to extract libraries.rar at the path we defined RunWait("unrar.bat " & $sLibrariesPath & " libraries.rar", "", @SW_HIDE) ; Deletes libraries.rar FileDelete($sLibrariesPath & "libraries.rar") I attached the .bat file I wrote to make it work. The reasoning for this solution is to show how its done cleanly with .rar files as I didn't see anyone do it this way. Hope it helps people in the future!
      unrar.bat
    • By nacerbaaziz
      hello autoit team
      please i need your help today
      am trying to make the list of features in list view and control it
      am using the dism command line to read output
      i've made the code
      but i found some problems
      what i need is the list of features in 2d array
      $array[$n][0]= name $array[$i][1] = state
      when i tested the code
      it give me some results that i don't need to it e.g
      ------ ------  | --------
      or
      name       | state
      i need just the list of features and there state
      please help me to do that
      here is my example
      #RequireAdmin #NoTrayIcon #include <AutoItConstants.au3> Wow64EnableWow64FsRedirection(false) _Windows_Get_Features() func _Windows_Get_Features() local $a_FeaturesArray[1][2] $a_FeaturesArray[0][0] local $i_Dism_Run = Run("DISM /online /english /get-features /format:table", "", @sw_hide, BitOR($STDERR_CHILD, $STDOUT_CHILD)) local $s_OutputDism = "", $a_OutPutDism While 1 $s_OutputDism = StdoutRead($i_Dism_Run) If @error Then exitLoop if ($s_OutputDism = "") or (StringRegExp($s_OutputDism, "^((\-){1,})?(?:\s)\|?(?:\s)((\-){1,})$", 0) = 1) then ContinueLoop if (StringRegExp($s_OutputDism, "((([\s\d\-\+\_\,]{1})\|([\s\d\-\+\_\,]{1})){1,})", 0) = 1) then $a_OutPutDism = StringSplit($s_OutputDism, @lf) for $i = 1 to $a_OutPutDism[0] if msgBox(1, $i, $a_OutPutDism[$i]) = 1 then exitLoop next endIf Wend endFunc func Wow64EnableWow64FsRedirection($b_Enabled) local $h_OpenFS = DLLOpen("kernel32.dll") local $Return = DllCall($h_OpenFS, "boolean", "Wow64EnableWow64FsRedirection", "boolean", $b_Enabled) if @error then DLLClose($h_OpenFS) Return SetError(@error, @extended, -1) else DLLClose($h_OpenFS) Return $Return[0] endIf endFunc  
    • By nacerbaaziz
      hello autoit team
      is there any wey to check if any process run as admin or no?
      i mean e.g if i want to restart any process, now i have the ability to get the process path and commands line
      what i need is a wey to check if the process was runing as admin or no to restart it with the same state.
      here is the part that am using it to restart the process
      func _processRestart($i_pid, $s_ProcessPath) if not (ProcessExists($i_ProcessPid)) then return SetError(1, 0, -1) local $s_ProcessWorkDir = _WinAPI_GetProcessWorkingDirectory($i_ProcessPid) ProcessClose($i_ProcessPid) ProcessWaitClose($i_ProcessPid) ProcessWait(ShellExecute($i_pid,"", $s_ProcessWorkDir)) ProcessesGetList() return true endFunc thanks in advance
    • By nacerbaaziz
      question about _WinAPI_CreateWindowEx
      good morning
      welcome autoit team
      please i need your help
      i've searched a lot about how to use the _WinAPI_CreateWindowEx
      finally i found an example
      but i found some problem i hope you can help me
      firstly, i want to set the controls focussable with the keyboard input
      i already used the ws_tabStop but it did not work with me.
      secondly, i want to set some access keys linked with the window
      such as control+o enable the open button and control+f4 exit the app
      note: i need a local access keys and not a global hotkeys
      such as GUISetAccelerators
      finaly, before i will put the code here i must clarify a few things.
      1. you will ask me why you don't use the GUICreate function
      here i'll tell you that it as dialog and It is a little heavy in motion with screen readers.
      the screen readers for blind has some function that work with dialogs and others work with full windows style
      2. you will ask me why you didn't search the net for that?
      i will tell you that all examples that i found in the internet with pdfs and Picture books.
      i found some examples in microsoft but it with cpp.
      ok here is the code
      i hope you can help me to do what i want
      thank you in advance
       
      ; Small AutoIt Application that uses Windows API ; Written by Yuraj #NoTrayIcon #include <_RegisterClassEx.au3> #include <WinAPI.au3> #include <WindowsConstants.au3> #include <ButtonConstants.au3> #include <EditConstants.au3> #include <FontConstants.au3> AutoItSetOption("MustDeclareVars", 1) ; Window definitions Const $WinWidth = 370 Const $WinHeight = 350 Const $WinXPos = (@DesktopWidth / 2) - ($WinWidth / 2) Const $WinYPos = (@DesktopHeight / 2) - ($WinHeight / 2) Const $WinTitle = "Win32 Application - Text reader" Const $WinClass = "mainapp" Const $WinIcon = _WinAPI_LoadIcon(_WinAPI_GetModuleHandle("shell32.dll"), 13) ; Windows handles Global $hwnd, $edit1, $btn1, $btn2 ; Fonts Global $fnt1 ; Register class, Create the window Local $retVal = __WinAPI_RegisterClassEx($WinClass, "WindowCallback", $WinIcon, 0, _WinAPI_GetSysColor($COLOR_BTNFACE), BitOR($CS_DEFAULTSTYLE, $CS_DROPSHADOW)) ; If $retVal == 0 Then ; If registerclass fails MsgBox(16, "Error", "Error while registering window class!") Exit EndIf ; Create windows/controls $hwnd = _WinAPI_CreateWindowEx($WS_EX_STATICEDGE, $WinClass, $WinTitle, BitOR($WS_OVERLAPPED,$WS_SYSMENU, $WS_MINIMIZEBOX, $WS_GROUP, $WS_DLGFRAME), $WinXPos, $WinYPos, $WinWidth, $WinHeight, 0) $btn1 = _WinAPI_CreateWindowEx(0, "button", "Open file ...", BitOR($WS_VISIBLE, $WS_CHILD, $WS_TABSTOP, $WS_CLIPCHILDREN), 25, 270, 100, 30,$hwnd) $btn2 = _WinAPI_CreateWindowEx(0, "Button", "Exit", BitOR($WS_VISIBLE, $WS_CHILD, $WS_TABSTOP, $WS_CLIPCHILDREN), 235, 270, 100, 30, $hwnd) $edit1 = _WinAPI_CreateWindowEx(0, "edit", "text", BitOR($WS_VISIBLE, $WS_CHILD, $WS_VSCROLL, $ES_AUTOVSCROLL, $es_readOnly, $WS_TABSTOP), 5, 5, $WinWidth - 15, $WinHeight - 100, $hwnd) ; Set controls identifiers _WinAPI_SetWindowLong($btn1,$GWL_ID,150) _WinAPI_SetWindowLong($btn2,$GWL_ID,160) ; Set (controls) fonts $fnt1 = _CreateFont("MS Sans Serif", 15) _WinAPI_SetFont($btn1, $fnt1) _WinAPI_SetFont($btn2, $fnt1) _WinAPI_SetFont($edit1, $fnt1) ; Set focus to edit _WinAPI_SetFocus($edit1) ; Show window _WinAPI_ShowWindow($hwnd) _WinAPI_UpdateWindow($hwnd) ; Main loop that keep application opened While 1 Sleep(100) WEnd ;=================================================================; ; WINDOW CALLBACK ... ;=================================================================; Func WindowCallback($_hwnd, $iMsg, $wParam, $lParam) Local $iNC, $iID Switch $iMsg ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Case $WM_CLOSE ; Show message on closing If MsgBox(48 + 4, $WinTitle, "Do you want really exit?", 0, $hwnd) <> 6 Then Return 0 ; Call destructor and then exit main thread FinalizeApp() Exit ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Case $WM_COMMAND $iNC = _WinAPI_HiWord($wParam) $iID = _WinAPI_LoWord($lParam) Switch $iNC Case $BN_CLICKED ; When is control clicked Switch _WinAPI_GetDlgCtrlID($iID) Case _WinAPI_GetDlgCtrlID($btn1) BtnOpenFileClick() Case _WinAPI_GetDlgCtrlID($btn2) BtnExitClick() EndSwitch EndSwitch ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EndSwitch Return _WinAPI_DefWindowProc($_hwnd, $iMsg, $wParam, $lParam) EndFunc ;==>WindowCallback Func FinalizeApp() _WinAPI_DeleteObject($fnt1) _WinAPI_DestroyWindow($hwnd) __WinAPI_UnregisterClass($WinClass) EndFunc ;==>FinalizeApp Func _CreateFont($fontName, $height = 16, $style = $FW_NORMAL, $italic = False, $underline = False, $strikeout = False) Local $hFont = _WinAPI_CreateFont($height, 0, 0, 0, $style, $italic, $underline, $strikeout, $DEFAULT_CHARSET, _ $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, $DEFAULT_PITCH, $fontName) Return $hFont EndFunc ;==>_CreateFont ;=================================================================; ; WINDOW EVENTS ;=================================================================; Func BtnOpenFileClick() Local $ret = _WinAPI_GetOpenFileName("", "Text files (*.txt)|All files (*.*)", ".", "", "", 1, 0, 0, $hwnd) If ($ret[0] > 0) Then Local $path = $ret[1] & "\" & $ret[2] Local $file = _WinAPI_CreateFile($path, 2, 2) Local $buf = DllStructCreate("byte[" & _WinAPI_GetFileSizeEx($file) & "]") Local $i = 0 _WinAPI_ReadFile($file, DllStructGetPtr($buf), _WinAPI_GetFileSizeEx($file), $i) ; Close file handle _WinAPI_CloseHandle($file) _WinAPI_SetWindowText($edit1, BinaryToString(DllStructGetData($buf, 1))) EndIf EndFunc ;==>BtnOpenFileClick Func BtnExitClick() FinalizeApp() Exit EndFunc ;==>BtnExitClick  
      _RegisterClassEx.au3
    • By Saravanan2213
      Hi everyone,
      i just need your help. i have script for cleaning browsing history and other unwanted file but the problem is i don't want to see the GUI i have attached below. It should not show anything on the screen. is it possible to do it in autoit. thanks in advance.
       
      So for i have tried flag
      Run("rundll32.exe InetCpl.cpl,ClearMyTracksByProcess 255", "", @SW_HIDE)
      @SW_DISABLE
       
      Looking forward your help.........

×
×
  • Create New...