System Information

From NSIS Wiki
Jump to navigationJump to search
Author: Anders (talk, contrib)


Gets various information about the computer using the System plug-in and the Windows API.

!macro GetWindowsShortName outvar build srv
!if "${NSIS_PTR_SIZE}" <= 4
!if "${NSIS_CHAR_SIZE}" < 2
${IfThen} ${build} >= 950 ${|} StrCpy ${outvar} "95" ${|}
!endif
${IfThen} ${build} >= 1381 ${|} StrCpy ${outvar} "NT4" ${|}
!if "${NSIS_CHAR_SIZE}" < 2
${IfThen} ${build} >= 1998 ${|} StrCpy ${outvar} "98" ${|}
${IfThen} ${build} >= 2222 ${|} StrCpy ${outvar} "98 SE" ${|}
!endif
!endif
${If} ${build} = 2195
	StrCpy ${outvar} "2000" /*"2000 Professional"
	${IfThen} ${srv} <> 0 ${|} StrCpy ${outvar} "2000 Server" ${|}*/
${ElseIf} ${build} >= 22000
	StrCpy ${outvar} "11"
${ElseIf} ${build} >= 9999 ; 10240
	StrCpy ${outvar} "10"
	${If} ${srv} <> 0
		StrCpy ${outvar} "2016"
		${IfThen} ${build} >= 17763 ${|} StrCpy ${outvar} "2019" ${|}
		${IfThen} ${build} >= 20348 ${|} StrCpy ${outvar} "2022" ${|} ; betawiki.net/wiki/Windows_Server_2022
	${EndIf}
${ElseIf} ${build} >= 9600
	StrCpy ${outvar} "8.1"
	${IfThen} ${srv} <> 0 ${|} StrCpy ${outvar} "2012 R2" ${|}
${ElseIf} ${build} >= 9200
	StrCpy ${outvar} "8"
	${IfThen} ${srv} <> 0 ${|} StrCpy ${outvar} "2012" ${|}
${ElseIf} ${build} >= 7600
	StrCpy ${outvar} "7"
	${IfThen} ${srv} <> 0 ${|} StrCpy ${outvar} "2008 R2" ${|}
${ElseIf} ${build} >= 6000
	StrCpy ${outvar} "Vista"
	${IfThen} ${srv} <> 0 ${|} StrCpy ${outvar} "2008" ${|}
${ElseIf} ${build} >= 3790
	StrCpy ${outvar} "2003" ; TODO: IsWin2003R2
	${IfThen} ${srv} = 0 ${|} StrCpy ${outvar} "XP" ${|} ; XPx64
${ElseIf} ${build} >= 2600
	StrCpy ${outvar} "XP"
!if "${NSIS_PTR_SIZE}" <= 4
!if "${NSIS_CHAR_SIZE}" < 2
${ElseIf} ${build} >= 3000
	StrCpy ${outvar} "ME"
!endif
!endif
${EndIf}
!macroend
 
Name "System Information"
Caption "$(^Name)"
RequestExecutionLevel User
Icon "res://$%WINDIR%/system32/TaskMgr.exe/#Icon/#30651"
!include LogicLib.nsh
!include WinVer.nsh
!include x64.nsh
 
Section
 
${WinVerGetBuild} $1
StrCpy $2 0
${IfThen} ${IsServerOS}  ${|} StrCpy $2 1 ${|}
StrCpy $0 ""
!insertmacro GetWindowsShortName $0 $1 $2
!if "${NSIS_PTR_SIZE}" > 4
	StrCpy $3 64
!else
	StrCpy $3 32
	${IfThen} ${RunningX64}  ${|} StrCpy $3 64 ${|}
!endif
${IfThen} $0 != "" ${|} DetailPrint "Windows $0 ($3-bit)" ${|}
 
System::Call '*(&l4,i,l,l,l,l,l,l,l)p.r1'
System::Call 'KERNEL32::GlobalMemoryStatusEx(pr1)i.r0' ; 2000+
System::Call '*$1(i,i,l.r2,l,l.r5)'
!if "${NSIS_PTR_SIZE}" <= 4
${If} $0 = 0
	System::Call '*$1(&l4,i,i,i,i,i,i,i)'
	System::Call 'KERNEL32::GlobalMemoryStatus(pr1)'
	System::Call '*$1(i,i,i.r2,i,i.r5)'
${EndIf}
!endif
System::Free $1
System::Int64Op $2 / 0x100000
Pop $4
IntOp $3 $4 % 1024
StrCpy $3 $3 1
IntOp $2 $4 / 1024
DetailPrint "Physical RAM: $2.$3 GiB ($4 MiB)"
System::Int64Op $5 / 0x100000
Pop $4
IntOp $3 $4 % 1024
StrCpy $3 $3 1
IntOp $2 $4 / 1024
DetailPrint "Total Memory: $2.$3 GiB ($4 MiB)"
 
System::Call 'KERNEL32::GetActiveProcessorCount(i0xffff)i.r1' ; 7+
${If} $1 = 0
	System::Call 'KERNEL32::GetSystemInfo(@r1)'
	System::Call '*$1(i,i,p,p,p,i.r1)'
${EndIf}
DetailPrint "Logical CPU cores: $1"
 
System::Call 'USER32::GetSystemMetrics(i0)i.r1'
System::Call 'USER32::GetSystemMetrics(i1)i.r2'
System::Call 'USER32::GetSystemMetrics(i80)i.r3'
!if "${NSIS_PTR_SIZE}" <= 4
${IfThen} $3 < 1 ${|} StrCpy $3 "1" ${|}
!endif
DetailPrint "Primary monitor: $1x$2 ($3 monitor(s))"
 
!define /IfNDef OPEN_EXISTING 3
!define /IfNDef FILE_FLAG_BACKUP_SEMANTICS 0x02000000
!define /IfNDef IOCTL_STORAGE_QUERY_PROPERTY 0x2d1400
!define /IfNDef PropertyStandardQuery 0
!define /IfNDef StorageDeviceSeekPenaltyProperty 7
!define /IfNDef StorageDeviceTrimProperty 8
System::Call 'KERNEL32::GetLogicalDrives()i.r1'
StrCpy $2 -1
disks_loop:
IntOp $2 $2 + 1
${If} $2 < 26
	IntOp $3 1 << $2
	${If} $1 & $3
		IntOp $3 $2 + 65
		IntFmt $5 "%c:" $3
		System::Call 'KERNEL32::GetDiskFreeSpaceEx(t"$5\", *l, *l, *l.r3)i.r0' ; Note: Not supported until Win95 OSR2.
		${If} $3 != 0
			System::Int64Op $3 / 0x100000
			Pop $3
			IntOp $4 $3 % 1024
			StrCpy $4 $4 1
			System::Int64Op $3 / 1024
			Pop $3
			System::Call 'KERNEL32::GetVolumeInformation(t"$5\", t, i${NSIS_MAX_STRLEN}, *i, *i, *i, t""r6, i${NSIS_MAX_STRLEN})'
			${IfThen} $6 != "" ${|} StrCpy $6 ", $6" ${|}
			StrCpy $7 "" ; This is only going to work on Win7+
			System::Call 'KERNEL32::CreateFile(t"\\.\$5", i0, i7, p0, i${OPEN_EXISTING},i${FILE_FLAG_BACKUP_SEMANTICS}, p0)p.r8' #devblogs.microsoft.com/oldnewthing/20201023-00/?p=104395
			${If} $8 P<> 0
				System::Call 'KERNEL32::DeviceIoControl(pr8, i${IOCTL_STORAGE_QUERY_PROPERTY}, *l${StorageDeviceSeekPenaltyProperty}, i 12, @r9, i${NSIS_MAX_STRLEN}, *i, p0)i.r0'
				System::Call '*$9(i,i,&i1.r9)'
				${If} $0 <> 0
				${AndIf} $9 = 0
					System::Call 'KERNEL32::DeviceIoControl(pr8, i${IOCTL_STORAGE_QUERY_PROPERTY}, *l${StorageDeviceTrimProperty}, i 12, @r9, i${NSIS_MAX_STRLEN}, *i, p0)i.r0'
					System::Call '*$9(i,i,&i1.r9)'
					${If} $0 <> 0
					${AndIf} $9 <> 0
						StrCpy $7 " (Solid state)" ; While not 100% accurate, this smells like a SSD
					${EndIf}
				${EndIf}
				FileClose $8
			${EndIf}
			DetailPrint "$5 $3.$4 GiB free$6$7"
		${EndIf}
	${EndIf}
	Goto disks_loop
${EndIf}
 
SectionEnd

The output might look something like this:

Windows 10 (64-bit)
Physical RAM: 15.7 GiB (16136 MiB)
Total Memory: 19.6 GiB (20136 MiB)
Logical CPU cores: 8
Primary monitor: 1920x1080 (2 monitor(s))
C: 2.4 GiB free, NTFS (Solid state)
D: 9.7 GiB free, NTFS
F: 0.6 GiB free, FAT