간단한 file 조작

C++ 2012. 5. 20. 15:47



#pragma once


#include <string>

#include <fstream>

using namespace std;


#include <Shobjidl.h>

#include <Shlwapi.h>

#pragma comment(lib, "Shlwapi.lib")


#include <atlconv.h>


// 폴더의 경우 끝에 \\이 있으면 안됨.

bool isExist(const string& filename)

{

return (PathFileExistsA(filename.c_str()) == TRUE);

}


bool isDirectory(const string& filename)

{

return (GetFileAttributesA(filename.c_str()) == FILE_ATTRIBUTE_DIRECTORY);

}



int getWindowsVersion(void)

{

/*

return value :

   -1 : 버전얻기 실패

1 : Windows 95,  

2 : Windows 98,  

3 : Windows ME,  

4 : Windows NT,

    5 : Windows 2000,  

6 : Windows XP,  

7 : Windows 2003,

8 : Windows Vista, 2008

9 : Windows 7, 2008 R2

*/


int ver= -1;

OSVERSIONINFOEX osvi = {0,};

BOOL version_ex_flag = 0;


osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);


if ( !(version_ex_flag = GetVersionEx((OSVERSIONINFO *)&osvi)) ) {

osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);

if( !GetVersionEx((OSVERSIONINFO *)&osvi) )

return -1;

}


switch(osvi.dwPlatformId) {

case VER_PLATFORM_WIN32_WINDOWS: // 윈도우즈 9x 기반의 운영체제인 경우

if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) {

ver = 1; // Windows 95

} else if(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10) {

ver = 2; // Windows 98

} else if(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) {

ver = 3; // Windows ME

}

break;

case VER_PLATFORM_WIN32_NT: // NT 기술 기반의 운영체제인 경우

if (osvi.dwMajorVersion <= 4) {

ver = 4; // Windows NT

} else if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) {

ver = 5; //Windows 2000

} else if(version_ex_flag) {

if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) {

ver = 6; // Windows XP

} else if( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) {

ver = 7; // Windows 2003

} else if( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0) {

ver = 8; // Windows Vista, 2008

} else if( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1) {

ver = 9; // WIndows7, 2008 R2

}

}

break;

}

return ver;

}


// Vista 이상인 OS의 경우

bool removeUseShellSinceVista(const string& filename, const bool useRecycleBin)

{

bool ret = false;


USES_CONVERSION;

wstring path = A2W(filename.c_str());


IFileOperation* pfo;


HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

if (SUCCEEDED(hr)) {

HRESULT hr = CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pfo));

if (SUCCEEDED(hr)) {

DWORD flags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI;

if (useRecycleBin) {

flags |= FOF_ALLOWUNDO; // 휴지통에 넣기

}


hr = pfo->SetOperationFlags(flags);

if (SUCCEEDED(hr)) {

IShellItem *psiFrom = NULL;

hr = SHCreateItemFromParsingName(path.c_str(), NULL, IID_PPV_ARGS(&psiFrom));

if (SUCCEEDED(hr))

{

if (SUCCEEDED(hr))

{

hr = pfo->DeleteItem(psiFrom, NULL);

if (SUCCEEDED(hr))

printf("success\n");

else

printf("fail\n");

}

psiFrom->Release();

}


if (SUCCEEDED(hr)) {

hr = pfo->PerformOperations();

if (SUCCEEDED(hr)) {

ret = true;

}

}

}

pfo->Release();

}

}

CoUninitialize();

return ret;

}


// Vista 이하인 OS의 경우

bool removeUseShellUnderVista(const string& filename, bool useRecycleBin)

{

// 파일명 끝에 \0\0 이 있어야 정상동작.

// 그렇지 않은 경우 SHFileOperation()는 1026을 돌려준다.

string from = filename;

from.resize(filename.size() + 2);

from += "\0\0";


SHFILEOPSTRUCTA shFileOpStruct = {0,};

shFileOpStruct.hwnd = NULL;

shFileOpStruct.wFunc = FO_DELETE;

shFileOpStruct.pFrom = from.c_str();

shFileOpStruct.pTo = NULL;

shFileOpStruct.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI;

shFileOpStruct.fAnyOperationsAborted = FALSE;

shFileOpStruct.hNameMappings = NULL;

shFileOpStruct.lpszProgressTitle = NULL;

if (useRecycleBin) { // 휴지통에 넣기

shFileOpStruct.fFlags |= FOF_ALLOWUNDO;

}


return (SHFileOperationA(&shFileOpStruct) == 0);

}


bool isUTF8BOM(string& filename)

{

ifstream stream(filename.c_str(), std::ios_base::in | std::ios_base::binary);

if (!stream.is_open()) {

return false;

}

char head[3] = {0};

stream.read(head, 3);

stream.close();


// 파일 맨 앞의 3문자로 UTF-8인지 확인

if (head[0] == 0xEF && head[1] == 0xBB && head[2] == 0xBF) {

return true;

}

return false;

}



// 삭제 대상 : recursive 폴더, 비어있지 않은 폴더, 읽기전용 파일/폴더

bool removeUseShell(const string& filename, const bool useRecycleBin)

{

if (getWindowsVersion() >= 8) { // Vista 이상인 경우

return removeUseShellSinceVista(filename, useRecycleBin);

} else {

return removeUseShellUnderVista(filename, useRecycleBin);

}

}



// 현재 exe 디렉토리 및 파일 명

string getBinaryPath()

{

char binary_path[MAX_PATH] = {0};

GetModuleFileNameA(NULL, binary_path, MAX_PATH);

return binary_path;

}

// 현재 exe 디렉토리 및 파일 명

wstring getBinaryPathW()

{

wchar_t binary_path[MAX_PATH] = {0};

GetModuleFileNameW(NULL, binary_path, MAX_PATH);

return binary_path;

}


// 현재 exe 디렉토리

string getBinaryDir()

{

string path = getBinaryPath();

string::size_type pos = path.find_last_of("\\");

if (pos != string::npos) {

return path.substr(0, pos);

}

return path;

}


'C++' 카테고리의 다른 글

암호화 : RSA, AES, BASE64  (0) 2012.05.20
간단한 sync 소켓 사용  (0) 2012.05.20
WinINet, WinHTTP, post 전송  (0) 2012.05.20
간단한 유틸(util) 함수들  (0) 2012.05.20
윈도우 uuid(guid) 생성  (0) 2012.05.20
std::string 문자열 조작  (0) 2012.05.20
url encode  (0) 2012.05.04
컴파일시 해야할 일 표시하기 #pragma message 사용  (0) 2012.04.15