DLL 버전비교 플러그인

아래의 코드는 DLL 버전을 비교하는 플러그인이다. 회사제품 인스톨러 제작시 필요하여 직접 제작해 보았다. 이 플러그인은 이미 설치되어 있는 버전을 비교하여 때에 따라 설치할때(최신 버전일때..) 사용하면 유용하다.

DllUtil.c

/*
 *
 * Programming by inhak.min@gmail.com
 * Dynalith Systems 2009
 *
 * NSIS plugin - DLL related commands
 *
 */

#include <windows.h>
#include <shlwapi.h>
#include "extdll.h"

#include <sys/stat.h> 

BOOL FileExists(char* strFilename) { 
  struct stat stFileInfo; 
  BOOL blnReturn; 
  int intStat; 

  intStat = stat(strFilename,&stFileInfo); 
  if(intStat == 0) { 
    blnReturn = TRUE; 
  } else { 
    blnReturn = FALSE; 
  } 
   
  return(blnReturn); 
}

BOOL GetFileVersion(LPCTSTR lpszFilePath, VS_FIXEDFILEINFO *pvffi) 
{ 
   BOOL                bRet = FALSE; 
   DWORD               dwSize; 
   BYTE                *pByte; 
   VS_FIXEDFILEINFO    *pvffi0; 
   UINT                nLen = sizeof *pvffi0;
   dwSize = GetFileVersionInfoSize(lpszFilePath, NULL);
   if(dwSize > 0) 
   { 
       pByte = malloc(dwSize);
       if(GetFileVersionInfo(lpszFilePath, NULL, dwSize, pByte) == TRUE &&
          VerQueryValue(pByte, "\\", (LPVOID*) &pvffi0, &nLen) == TRUE) 
       { 
           memcpy(pvffi, pvffi0, sizeof *pvffi); 
           bRet = TRUE; 
       }
       free(pByte); 
   }
   return bRet; 
}

int CompareVersion(VS_FIXEDFILEINFO *f0, VS_FIXEDFILEINFO *f1) 
{ 
   int nRet = 0; 
   int diffMS, diffLS;
   diffMS = f1->dwFileVersionMS - f0->dwFileVersionMS; 
   diffLS = f1->dwFileVersionLS - f0->dwFileVersionLS;
   if(diffMS == 0) 
       nRet = diffLS; 
   else 
       nRet = diffMS;
   return nRet; 
}

// DLL version check
void __declspec(dllexport) CompVer(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)
{
	VS_FIXEDFILEINFO f0; 
	VS_FIXEDFILEINFO f1; 

	char file1[256], file2[256];

        EXDLL_INIT();

	popstring(file1);
	popstring(file2);

	// 비교할 파일이 없으므로 1로 셋팅 (무조건 설치)
	if ( FileExists(file1) == FALSE ) goto error;

	if ( GetFileVersion(file1, &f0) == FALSE ) goto error;
	if ( GetFileVersion(file2, &f1) == FALSE ) goto error;

	if(CompareVersion(&f0, &f1) > 0) 
	{
		// new
		setuservariable(INST_R0, "1");
		return;
	}
	else
	{
		// older or same
		setuservariable(INST_R0, "0");
		return;
	}
		
error:
	setuservariable(INST_R0, "1");
	return;
} 

make.bat

@call vcvars32.bat
@cl -c DllUtil.c
if errorlevel 1 goto error
@cl /LD /o DllUtil.dll DllUtil.obj version.lib user32.lib
:error
@pause

update.bat

@copy DllUtil.dll "C:\Program Files\NSIS\Plugins"
@pause

test.nsi

;--------------------------------

; The name of the installer
Name "CompDllVer"

; The file to write
OutFile "test.exe"

; The default installation directory
InstallDir $PROGRAMFILES\DllUtil

;--------------------------------

; Pages

Page components
Page directory
Page instfiles

UninstPage uninstConfirm
UninstPage instfiles

;--------------------------------

; The stuff to install
Section "CompDllVer (required)"
  ; Set output path to the installation directory.
  SetOutPath $INSTDIR
  
  DllUtil::CompVer "$SYSDIR\test.dll" "test.dll"
  Pop $R0

  ; 설치되어 있는 파일보다 최신이면 설치
  StrCmp $R0 '0' skip
          SetOutPath $SYSDIR
	  File "test.dll"
	  goto +3
  skip:
  MessageBox MB_OK "skipped"

  SetOutPath $INSTDIR
  WriteUninstaller "uninstall.exe"
  
SectionEnd

;--------------------------------

; Uninstaller

Section "Uninstall"
  ; Remove files and uninstaller
  Delete $SYSDIR\\test.dll
  Delete $INSTDIR\uninstall.exe

  ; Remove directories used
  RMDir "$SMPROGRAMS\DllUtil"
  RMDir "$INSTDIR"
SectionEnd
이 글은 카테고리: Programming에 포함되어 있으며 태그: , , , (이)가 사용되었습니다. 고유주소를 북마크하세요.

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다


This site uses Akismet to reduce spam. Learn how your comment data is processed.