WinSxS QueryAssemblyInfo to check if assembly is installed

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


This code has been tested by the author on Windows XP SP2, and by others on Windows XP SP2, Windows XP x64, Windows XP "vanilla" (no service-pack), and Windows Vista "vanilla".


The Function

Function WinSxS_HasAssembly ;legacyDllName,(Strong)AssemblyName
/*
push 'msvcr80.dll'
push 'Microsoft.VC80.CRT,version="8.0.50727.42",type="win32",processorArchitecture="x86",publicKeyToken="1fc8b3b9a1e18e3b"'
call WinSxS_HasAssembly
pop $0 ;0 on fail, 1 if it is in WinSxS or 2 if LoadLibrary worked on pre xp (call GetDLLVersion to make sure if you require a minimum version)
*/
Exch $8
Exch
Exch $7
push $9
StrCpy $9 0
push $0
push $R0
push $R1
${If} ${AtLeastWinXP}
	System::Call "sxs::CreateAssemblyCache(*i.R0,i0)i.r0"
	${If} $0 = 0
		System::Call '*(i 24,i0,l,i0,i0)i.R1' ;TODO,BUGBUG: check alloc success
		System::Call `$R0->4(i 0,w '$8',i $R1)i.r0` ;IAssemblyCache::QueryAssemblyInfo
		${If} $0 = 0
			System::Call '*$R1(i,i.r0)'
			IntOp $0 $0 & 1 ;ASSEMBLYINFO_FLAG_INSTALLED=1
			${IfThen} $0 <> 0 ${|} StrCpy $9 1 ${|}
		${EndIf}
		System::Free $R1
		System::Call $R0->2() ;IAssemblyCache::Release
	${EndIf}
${Else}
	System::Call kernel32::LoadLibrary(t"$7")i.r0
	${If} $0 <> 0
		StrCpy $9 2
		System::Call 'kernel32::FreeLibrary(i r0)'
	${EndIf}
${EndIf}
pop $R1
pop $R0
pop $0
Exch 2
pop $8
pop $7
Exch $9
FunctionEnd


!include LogicLib.nsh
!include WinVer.nsh
Section
var /GLOBAL hasCRT
!define CRTCHECKDLL msvcr80.dll
!define CRTCHECKNAME 'Microsoft.VC80.CRT,version="8.0.50727.42",type="win32",processorArchitecture="x86",publicKeyToken="1fc8b3b9a1e18e3b"'
push '${CRTCHECKDLL}'
push '${CRTCHECKNAME}'
call WinSxS_HasAssembly
pop $hasCRT
DetailPrint ${CRTCHECKDLL}=$hasCRT
SectionEnd

Credits

Written by Anders (For fun and profit?)

Inspired by code found @

http://blogs.msdn.com/junfeng/articles/229648.aspx

http://kobyk.wordpress.com/2008/04/12/deploying-the-visual-c-libraries-with-an-nsis-installer/