이클립스 플러그인을 만들고나서…

Core-A 툴체인 지원을 위한 이클립스의 CDT를 확장한 플러그인을 3일정도 시간을 투자하여 만들어 보았습니다.

툴 체인역시 cygwin의 종속성을 탈피하고자 MinGW 4.x로 재 컴파일하였는데, cygwin보다 빨라진 느낌입니다. (아니 확실히 빨라졌습니다.)

결국 이클립스 플러그인을 만들고 나니 빌드도 잘 되고,
GDB 서버와의 연동으로 디버깅도 잘 되고.. 대만족입니다.

core-a_plugin

사실 처음 개발할때 자바를 거의 해본적 없어서 고민을 좀 했는데…

만들어 놓고 보니 기존 플러그인을 상속받아 확장하는건 그래도 쉽더라구요.
(단 확장 포인트지점 알아내는것… 힘들더라구요.)

하지만 전혀 새로운 플러그인을 만들려면 자바를 알아야겠더라구요. ㅠ_ㅠ

그래도 이클립스 플러그인을 만드는건 확실히 감을 잡았습니다. 만족!!

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