C/C++ IPropertyStore / 파일 속성 모두 얻어오기 .doc .docs .xlsx .pptx
IPropertyStore()
개발을 진행하다보면 별 특이한 경우를 많이 경험하게 됩니다.
개발을 하다가 발생된 이슈로 인한
기능정리를 위한 포스팅을 진행할까 합니다.
안녕하세요 IT훈이입니다 😁
이슈
word 파일의 버전을 취득해야하는 상황입니다. '속성-자세히-유형' 에 있는 값을 취득하여서 값을 분기처리 해줘야합니다. 해당 값을 얻기위해서 구글링을 진행하는데, 생각보다 원하는 결과를 얻기가 어려웠기에 포스팅으로 기록을 남겨봅니다.
SHGetPropertyStoreFromParsingName 함수사용
구글링을 열심히 하다보니, SHGetPropertyStoreFromParsingName 함수를 활용하여 해결할 수 있다는 내용을 확인하고 바로 테스트코드를 작성해보았습니다. MFC를 통하여 개발한점 참고바랍니다. ( 소스는 글 아래 있습니다 )
SHGetPropertyStoreFromParsingName 함수를 통해서 자세히 영역의 값을 취득하기 위해서는 사용자가 직접 GetValue를 통하여 'INIT_PKEY_ ' 로 시작하는 키 값을 하나씩 넣어서 찾아가는 방식입니다.
propkey.h 파일을 보시면, 'INIT_PKEY_ ' 로 시작하는 Define들이 있는것을 확인하실 수 있습니다. 해당방식으로 찾게되면 이 많은 정의값들중에서 내가 원하는 갚은 찾아야하는데, 워낙 노가다적인 측면이 있습니다.
propkey.h 파일의 라인이 8571줄... 어마어마한 길이거든요. 그래서 이렇게 하는 방식보다 좀더 좋은 방식을 아래에서 알려드리겠습니다.
소스코드
헤더부분
#include "pch.h"
#include "framework.h"
#include "MFCApplication2.h"
#include "MFCApplication2Dlg.h"
#include "afxdialogex.h"
#include <Windows.h>
#include <shobjidl.h>
#include <propsys.h>
#include <propvarutil.h>
#include <propkey.h>
#include <strsafe.h>
소스부분
Visual Studio 2022 환경에서 MFC로 개발하였습니다.
void CMFCApplication2Dlg::OnCheck01()
{
HRESULT hr = ::CoInitialize(nullptr);
IPropertyStore* pps;
TCHAR wszAppID[MAX_PATH] = { 0, };
bool success = false;
if (SUCCEEDED(SHGetPropertyStoreFromParsingName(_T("D:\\reseouch\\MFCApplication2\\test1.doc"), NULL, GPS_DEFAULT, IID_PPV_ARGS(&pps))) )
{
PROPVARIANT propvar;
HRESULT hres = (pps->GetValue(INIT_PKEY_ItemTypeText, &propvar));
if (SUCCEEDED(hres))
{
MessageBox(propvar.pwszVal);
PropVariantClear(&propvar);
success = true;
}
if (pps) {
pps->Release();
}
CoUninitialize();
}
}
GetPropertyStore 함수 사용
우선 결과값을 아래 사진을 통해서 확인해보시면, 파일속성의 모든 데이터를 긁어온것을 확인하실 수 있습니다. 위의 SHGetPropertyStoreFromParsingName 함수를 통한 방법은 하나씩 입력하여 찾는 방식인 반면에 GetPropertyStore함수를 통한 방식은 모든 속성을 찾아오는 방식이기에 좀더 편리합니다.
소스
헤더부분
#include "pch.h"
#include "framework.h"
#include "MFCApplication2.h"
#include "MFCApplication2Dlg.h"
#include "afxdialogex.h"
#include <Windows.h>
#include <shobjidl.h>
#include <propsys.h>
#include <propvarutil.h>
#include <propkey.h>
#include <strsafe.h>
소스부분
Visual Studio 2022 환경에서 MFC로 개발하였습니다.
HRESULT PrintProperty(IPropertyStore* pps, REFPROPERTYKEY key, PCWSTR pszCanonicalName)
{
PROPVARIANT propvarValue = { 0 };
HRESULT hr = pps->GetValue(key, &propvarValue);
if (SUCCEEDED(hr))
{
WCHAR wMsg[MAX_PATH] = { 0, };
PWSTR pszDisplayValue = NULL;
hr = PSFormatForDisplayAlloc(key, propvarValue, PDFF_DEFAULT, &pszDisplayValue);
if (SUCCEEDED(hr))
{
wsprintf(wMsg,L"%s = %s\n", pszCanonicalName, pszDisplayValue);
sMsg.Append(wMsg);
CoTaskMemFree(pszDisplayValue);
}
PropVariantClear(&propvarValue);
}
return hr;
}
HRESULT EnumerateProperties(PCWSTR pszFilename)
{
IPropertyStore* pps = NULL;
// Call the helper to get the property store for the initialized item
// Note that as long as you have the property store, you are keeping the file open
// So always release it once you are done.
HRESULT hr = GetPropertyStore(pszFilename, GPS_DEFAULT, &pps);
if (SUCCEEDED(hr))
{
// Retrieve the number of properties stored in the item.
DWORD cProperties = 0;
hr = pps->GetCount(&cProperties);
if (SUCCEEDED(hr))
{
for (DWORD i = 0; i < cProperties; i++)
{
// Get the property key at a given index.
PROPERTYKEY key;
hr = pps->GetAt(i, &key);
if (SUCCEEDED(hr))
{
// Get the canonical name of the property
PWSTR pszCanonicalName = NULL;
hr = PSGetNameFromPropertyKey(key, &pszCanonicalName);
if (SUCCEEDED(hr))
{
hr = PrintProperty(pps, key, pszCanonicalName);
CoTaskMemFree(pszCanonicalName);
}
}
}
}
pps->Release();
}
else
{
wprintf(L"Error %x: getting the propertystore for the item.\n", hr);
}
return hr;
}
void CMFCApplication2Dlg::OnCheck02()
{
EnumerateProperties(_T("D:\\reseouch\\MFCApplication2\\test1.doc"));
MessageBox(sMsg);
}
상세한 소스확인은 해당 깃허브를 참고해주세요
'훈, IT 공부 > C,C++,MFC' 카테고리의 다른 글
C++ 에서의 .h 헤더파일 확장자 사용하지 않는 이유 (0) | 2023.09.12 |
---|---|
warning C4996 10초만에 해결하는법 3가지 정리, Visual Studio 2022 (1) | 2023.06.22 |
[VS에러] 함수에서 참조되는 확인할 수 없는 외부기호 LNK1120, LNK2019 (6) | 2021.01.14 |
[C++] 멀티바이트 -> 유니코드 변환을 위한 4가지 방법 (6) | 2020.06.05 |
C++ PCRE 정규식 라이브러리 사용해서 정규표현식 사용하기 (2) | 2020.04.08 |
댓글