2012-06-04 1 views

답변

5

Sysinternals 및 기타 프로그램에서 프로그램 (예 : Sysinternals 'Process Explorer)의 리소스 섹션에 드라이버 나 필요한 DLL (또는 x64 버전의 프로그램)을 가져 오는 데 사용되는 방법을 Microsoft Visual 이 NewPath을 제기 할 모듈에서 자원 유형 (ResType) (예 : DLL) Instance의 주어진 자원 (BinResName)를 저장

BOOL ExtractResTo(HINSTANCE Instance, LPCTSTR BinResName, LPCTSTR NewPath, LPCTSTR ResType) 
{ 
    BOOL bResult = FALSE; 
    HRSRC hRsrc; 
    if(hRsrc = FindResource(HMODULE(Instance), BinResName, ResType)) 
    { 
     HGLOBAL hGlob 
     if(HGLOBAL hGlob = LoadResource(Instance, hRsrc)) 
     { 
      DWORD dwResSize = SizeofResource(Instance, hRsrc); 
      HANDLE hFileWrite = CreateFile(NewPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, 0); 
      if(hFileWrite != INVALID_HANDLE_VALUE) 
      __try 
      { 
       DWORD dwSizeWritten = 0; 
       bResult = (WriteFile(hFileWrite, LockResource(hGlob), dwResSize, &dwSizeWritten, NULL) && (dwSizeWritten == dwResSize)); 
      } 
      __finally 
      { 
       CloseHandle(hFileWrite); 
      } 
     } 
    } 
    return bResult; 
} 

:이 코드를 사용할 수 있습니다 C. 분명히 C가 __try__finally을 이해하지 못한다면 그에 따라 코드를 조정해야합니다.

취향이 here (SIDT.rar)이며 C로 조정되었습니다.이 코드는 웹 사이트에 따라 자유주의 BSD 라이센스하에 있습니다.

BOOL GetResourcePointer(HINSTANCE Instance, LPCTSTR ResName, LPCTSTR ResType, LPVOID* ppRes, DWORD* pdwResSize) 
{ 
    // Check the pointers to which we want to write 
    if(ppRes && pdwResSize) 
    { 
     HRSRC hRsrc; 
     // Find the resource ResName of type ResType in the DLL/EXE described by Instance 
     if(hRsrc = FindResource((HMODULE)Instance, ResName, ResType)) 
     { 
      HGLOBAL hGlob; 
      // Make sure it's in memory ... 
      if(hGlob = LoadResource(Instance, hRsrc)) 
      { 
       // Now lock it to get a pointer 
       *ppRes = LockResource(hGlob); 
       // Also retrieve the size of the resource 
       *pdwResSize = SizeofResource(Instance, hRsrc); 
       // Return TRUE only if both succeeded 
       return (*ppRes && *pdwResSize); 
      } 
     } 
    } 
    // Failure means don't use the values in *ppRes and *pdwResSize 
    return FALSE; 
} 

전화 같은 : 당신은 데이터에 대한 포인터 (ppRes)와 크기 (pwdResSize) 도착하기를 원한다면 지금

LPVOID pResource; 
DWORD pResourceSize; 
if(GetResourcePointer(hInstance, _T("somename"), _T("sometype"), &pResource, &pResourceSize)) 
{ 
    // use pResource and pResourceSize 
    // e.g. store into a string buffer or whatever you want to do with it ... 
} 

참고,이 또한 리소스에 대한 작업 정수 ID 포함. IS_INTRESOURCE 매크로를 사용하여이를 감지 할 수 있습니다.

리소스 스크립트. myresources.rc 그 자체는 간단하다 :

GetResourcePointer(hInstance, _T("somename"), RT_RCDATA, &pResource, &pResourceSize) 
:
#include <winnt.rh> 
"somename" "sometype" "path\to\file\to\embed" 

RCDATA 대신 sometype의

당신이 수 위의 호출을 조정할 수 있는데,이 경우에 합리적인 선택

#include <winnt.rh> // for RCDATA to be known to rc.exe 
"somename" RCDATA "path\to\file\to\embed" 

입니다 ...


위의 GetResourcePointer을 사용한 완전한 예. 포인터 변수가 char* buf이고 리소스가 실제 텍스트라는 것을 알고 있다고 가정하면 문자열로 사용될 때 이것이 zero-terminated인지 확인해야합니다.

는 자원 스크립트 : 물론 당신이 단순히 의미하지 않는

#include <winnt.rh> 

"test" RCDATA "Test.txt" 

코드가

char* buf = NULL; 
LPVOID pResource; 
DWORD pResourceSize; 
if(GetResourcePointer(hInstance, _T("test"), RT_RCDATA, &pResource, &pResourceSize)) 
{ 
    if(buf = calloc(pResourceSize+1, sizeof(char))) 
    { 
     memcpy(buf, pResource, pResourceSize); 
     // Now use buf 
     free(buf); 
    } 
} 

접근은 링커 명령 행에 전달하여 작동하는 .res 파일을 링크 .

+0

나는 xml 파일, 텍스트 파일 및 ps1 파일에 액세스하기 만하면됩니다. C 프로그램에서 나는 theses 파일을 호출한다. 나는 그들을 exe에 임베드하고 싶습니다. 나는 VS와 C 프로그래밍에 익숙하지 않다. 사실 나는 대학에서 다음 학기에 첫 수업을 듣는다. 나는 배우기가 너무 불안하여 프로그램을 작성하기로 결정했습니다. – arynhard

+0

@arynhard : 음, 위 기능은 당신이 원하는 것을 수행합니다.대신 버퍼로 읽을 수있는 약간 파생 된 버전을 추가합시다 ... – 0xC0000022L

+0

주목할 가치가 있는지 모르겠지만 Microsoft Visual C를 사용하지 않고 Visual Studio Pro 11을 사용하고 있습니다. – arynhard

관련 문제