C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[1097] [Application] Process의 Module-Version Dialog 만들기
장성호 [nasilso] 8404 읽음    2012-06-21 01:26
음...

[개요]

RAD2010 의 About화면에서  "Version Info ..." 버튼을 클릭하면
다음과 같은 화면을 볼수 있다.





이 "Version Infomation" 폼에는
현재 process(bds.exe) 에   Load된 dll 들의 이름과 경로 버젼을 표시해 주고 있다.



[어플에 VersionInfo의 필요성 ]

그렇지 않는 프로그램도 많이 있지만
어플자체에 현재 사용중인 모듈의 버젼을 보여주는 화면이 있는경우가 상당히 많이 있다.


현재 회사에서 프로그램을 개발할때
회사 자체에서 만든 모듈(라이브러리)를  1개에서 최대 6~7가지 씩 사용한다
프로그램에 문제가 발생했을때 정확히 배포버젼을 알려면
exe뿐만 아니라 각모듈의 버젼정보도 필요하다.

문론 모듈(exe나 dll 또는 bpl 등)의 버젼 정보를  Windows탐색기에서 확인이 가능하지만..
한두개도 아닌 여러개의 모듈으 버젼을 일일이 확인하기는 쉽지 않는 일이다.


그래서 한번 Process의 모듈을 보여주는 dialog를 만들어 보았다.



[file의 Version정보 가져오는 함수]

//---------------------------------------------------------------------------
//filename을 이용해 , Version정보 , 회사명 , 설명 등을 구해주는 함수 
//---------------------------------------------------------------------------
void __fastcall GetModuleVersionInfo(AnsiString filename,AnsiString &sVer,AnsiString &sCompN,AnsiString &sFDesc)
{
	sVer="";
	sCompN="";
	sFDesc="";
	AnsiString sFileVersion; // Return 될 Version 정보.
	DWORD dwHandle = 0, dwVersionInfoSize;
	UINT uLength;
	LPVOID pFileInfo, ptr;

	dwVersionInfoSize = GetFileVersionInfoSize(filename.c_str(), &dwHandle);
	if (dwVersionInfoSize < 2) return ; // 실행화일에 버젼 정보 표시가 되어 있지 않을 경우
	pFileInfo = (LPVOID)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwVersionInfoSize);

	GetFileVersionInfo(filename.c_str(), dwHandle, dwVersionInfoSize, pFileInfo);
	VerQueryValue(pFileInfo, TEXT("\\VarFileInfo\\Translation"), &ptr, &uLength);

	WORD *id = (WORD*)ptr;
																						AnsiString szString;
        szString = "\\StringFileInfo\\" + IntToHex(id[0], 4) + IntToHex(id[1], 4) + "\\ProductVersion";
	VerQueryValue(pFileInfo, szString.c_str(), &ptr, &uLength);
	sVer = (char*)ptr;

	szString = "\\StringFileInfo\\" + IntToHex(id[0], 4) + IntToHex(id[1], 4) + "\\CompanyName";
	VerQueryValue(pFileInfo, szString.c_str(), &ptr, &uLength);
	sCompN = (char*)ptr;

	szString = "\\StringFileInfo\\" + IntToHex(id[0], 4) + IntToHex(id[1], 4) + "\\FileDescription";
	VerQueryValue(pFileInfo, szString.c_str(), &ptr, &uLength);
	sFDesc = (char*)ptr;

	HeapFree(GetProcessHeap(), 0, pFileInfo);

}
//---------------------------------------------------------------------------



[Process의 모듈 정보를 가져오는 함수]
//---------------------------------------------------------------------------
// process의 모듈 정보를 모두 읽어서 ListView에 뿌려준다.
//---------------------------------------------------------------------------
void __fastcall TForm1::ResetModuleInfo()
{
	ListView1->Items->BeginUpdate();
	ListView1->Items->Clear();
	char buf[256]={0};
	HINSTANCE MODList[1000];
	HWND ph=(HWND )GetCurrentProcess();
	AnsiString sVer,sCompN,sDesc;

	unsigned long modNeeded=0;
	if(!EnumProcessModules(ph,MODList, 1000, &modNeeded))return;
	for(int i=0;i< (modNeeded / 4 );i++)
	{
		if(GetModuleFileNameExA(ph,MODList[i],buf,256)>0)
		{
			AnsiString sFName=buf;
			TListItem *Item=ListView1->Items->Add();
			Item->Caption=IntToStr(Item->Index+1);
			Item->SubItems->Add(ExtractFileName(sFName));
			GetModuleVersionInfo(sFName,sVer,sCompN,sDesc);
			Item->SubItems->Add(sVer);
			Item->SubItems->Add(sCompN);
			Item->SubItems->Add(sDesc);
			Item->SubItems->Add(sFName);
		}
	}
	ListView1->Items->EndUpdate();
}




[사용은?]

//---------------------------------------------------------------------------
// 폼 Show이벤트에서 모듈정보를 Reset해준다.
//---------------------------------------------------------------------------

void __fastcall TForm1::FormShow(TObject *Sender)
{
	ResetModuleInfo();
}
//---------------------------------------------------------------------------
// Copy버튼을 클릭하면 TSV로 Clipboard에 복사해준다.
//---------------------------------------------------------------------------
void __fastcall TForm1::B_CopyClick(TObject *Sender)
{
	TStringList *pLst=new TStringList;

	for(int i=0 ; i < ListView1->Items->Count ; i++)
	{
		TListItem *item=ListView1->Items->Item[i];
		item->SubItems->Delimiter='\t';
		item->SubItems->StrictDelimiter=true;
		pLst->Add(item->SubItems->DelimitedText );

	}

	Clipboard()->AsText = pLst->Text;
	delete pLst;
}



위와같이 모든 모듈을 다 화면에 뿌려주는 것도 좋지만
RadStudio 사용자는   BPL만  뿌려주는것도 괜찮을것 같다.


그럼..

+ -

관련 글 리스트
1097 [Application] Process의 Module-Version Dialog 만들기 장성호 8404 2012/06/21
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.