티스토리 뷰

반응형

모듈 내부에서 경로 구하기

프로그램을 만들고 실행을 하다 보먄 자신의 경로 및 디렉토리 프로세스의 경로등이 필요한 경우가 상당히 많다.
우리가 흔히 알고 있는 WIN32 API 인 ::GetModuleFileName()을 사용하면 된다. 사용법은 아래와 같다. 

 

 Code1 자신의 경로 구하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/******************************************************************************
* _    _                 _       _  __  _____               _           _     
*| |  | |               | |     | |/ / |  __ \             | |         | |    
*| |__| | __ _  ___     | |_   _| ' /  | |  | | _____   __ | |     __ _| |__  
*|  __  |/ _` |/ _ \_   | | | | |  <   | |  | |/ _ \ \ / / | |    / _` | '_ \ 
*| |  | | (_| |  __/ |__| | |_| | . \  | |__| |  __/\ V /  | |___| (_| | |_) |
*|_|  |_|\__,_|\___|\____/ \__,_|_|\_\ |_____/ \___| \_(_) |______\__,_|_.__/ 
*
* Copyright (c) HaeJuK Dev Lab All Rights Reserved.
*
*******************************************************************************/                                                                             
#include "stdafx.h"
#include <Windows.h>
 
//--------------------------------------------------------------------
//PathRemoveFileSpec()
#include <shlwapi.h>
#pragma comment(lib,"Shlwapi.lib")
 
//--------------------------------------------------------------------
// StringCchPrintf()
#include <strsafe.h>
 
//--------------------------------------------------------------------
// c++ 등등등
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
 
 
void nullTerminateString()
{
    //1. GetModuleFileName() 
    TCHAR szFilePath[MAX_PATH] = {NULL,};
    //::GetModuleHandle(0)의 0은 자신의 HANDLE을 리턴한다. 
    ::GetModuleFileName(::GetModuleHandle(0),szFilePath,MAX_PATH);
 
    // NULL Terminate문자열의 맨 끝부터 "\\"를 찾아 강제로 0을 만들어 출력을 못하게 한다. 
    TCHAR *pSplitPath = NULL;
    pSplitPath  = _tcsrchr(szFilePath,'\\');
    if(pSplitPath != NULL)
    {
        *pSplitPath = 0
    }
    // 경로를 획득 
    _tprintf(_T("[PATH 1]: %s\r\n"),szFilePath);
}
 
void SafeShlwapi()
{
    TCHAR szFilePath[MAX_PATH] = {NULL,};
    ::GetModuleFileName(::GetModuleHandle(0),szFilePath,MAX_PATH);
    ::PathRemoveFileSpec(szFilePath);
    ::PathRemoveBackslash(szFilePath);
    
    // 경로를 획득 
    _tprintf(_T("[PATH 2]: %s\r\n"),szFilePath);
}
void SafeString()
{
    TCHAR szFilePath[MAX_PATH] = {NULL,};
    ::GetModuleFileName(::GetModuleHandle(0),szFilePath,MAX_PATH);
 
    TCHAR szDrive[MAX_PATH] = {NULL,} , szDirectory[MAX_PATH] = {NULL,} ; 
    _tsplitpath(szFilePath,szDrive,szDirectory,NULL,NULL);
 
    TCHAR szPath[MAX_PATH] = {NULL,};
 
    HRESULT hr = ::StringCchPrintf(szPath,MAX_PATH,_T("%s%s"),szDrive,szDirectory);
    if( FAILED( hr) )
    {
        _tprintf(_T("[ERROR]: 0x%x\r\n"),hr);
    }
    
    // 경로를 획득 
    ::PathRemoveBackslash(szPath);
    _tprintf(_T("[PATH 3]: %s\r\n"),szPath);
}
 
 
vector<string> GetTokens(const string& str, const string& delimiters)
{
    string::size_type lastPos = str.find_first_not_of(delimiters, 0); // 맨 처음 문자가 구분자일 때
    string::size_type pos = str.find_first_of(delimiters, lastPos);     // 구분자 찾기
    vector<string> tokens;
    while (string::npos != pos || string::npos != lastPos)
    {
        tokens.push_back(str.substr(lastPos, pos - lastPos)); // 찾은 token을 vector에 저장
        lastPos = str.find_first_not_of(delimiters, pos);        // 구분자 다음으로 이동
        pos = str.find_first_of(delimiters, lastPos);        // 다음구분자 찾기
    }
    return tokens;
}
 
void UsingVector()
{
    string ssPath;
    char szFilePath[MAX_PATH] = {NULL,};
    ::GetModuleFileNameA(::GetModuleHandle(0),szFilePath,MAX_PATH);
    vector<string> vPaths =  GetTokens(szFilePath,"\\");
 
    for(int i = 0 ; i < vPaths.size()-1; i++ )
    {
        ssPath += vPaths[i]; 
        ssPath += "\\";
    }
    printf("[PATH 4]: %s\r\n",ssPath.c_str());
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    //----------------------------------------------------------------------
    // EXE의 실행 경로룰 알아 봅시다.
    nullTerminateString();
    
    SafeShlwapi();
    
    SafeString();
    
    UsingVector();
    
    system("pause");
 
    return 0;
}
cs

 

Code2 DLL 내부에서 본인의 위치 구하기

DLL내부에서 위의 코드를 이용하여 경로를 구하면 EXE의 경로가 나오게 된다.
본인의 이름을 알고 있다면 GetModuleHandle("")에서 자기 자신의 모듈 이름이나 경로를 받아 처리하면 되지만 그럼 구할 이유가 없다.

아래와 같이 하면 DLL 본인의 위치를 알아 낼 수 있다. 

1
2
3
4
5
EXTERN_C IMAGE_DOS_HEADER __ImageBase;        // 서비스 최소화 수정 (사용하기 위해 추가)
 
TCHAR szCurrentPath[MAX_PATH] = {NULL,};
::GetModuleFileName((HINSTANCE)&__ImageBase, szCurrentPath, _countof(szCurrentPath));
 
cs

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/03   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함