2017-11-27 1 views
3

COM을 사용하여 모든 응용 프로그램의 설치 위치를 얻으려고합니다. 각 응용 프로그램의 표시 이름을 가져올 수 있습니다. 하지만 각 응용 프로그램의 설치 경로를 가져올 수 없습니다.COM에서 executbale의 설치된 응용 프로그램 경로를 얻는 방법

MY 코드 : IEnumShellItems에서 경로를 설치하는 방법에

CComPtr<IShellItem> spPrinters; 
     CoInitialize(nullptr); 
     HRESULT hresult = ::SHCreateItemFromParsingName(L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\\8\\" 
      L"::{7B81BE6A-CE2B-4676-A29E-EB907A5126C5}", nullptr, IID_PPV_ARGS(&spPrinters)); 
     CComPtr<IEnumShellItems> spEnum; 
     spPrinters->BindToHandler(nullptr, BHID_EnumItems, IID_PPV_ARGS(&spEnum)); 
     for (CComPtr<IShellItem> spProgram; spEnum->Next(1, &spProgram, nullptr) == S_OK; spProgram.Release()) 
     { 
      CComHeapPtr<wchar_t> spszName; 
      spProgram->GetDisplayName(SIGDN_NORMALDISPLAY, &spszName); 
      CString cDisplayName = spszName; 
} 

어떤 생각.

감사합니다.

+0

설치된 경로로 (선택 사항) "위치"열을 의미합니까? –

+0

예; 나는 위치를 얻고 싶다. – CrazyCoder

답변

2

다음은이를 덤프 할 코드 조각입니다. 아이의 IPropertyStore는 이것을 반환하지 않습니다. 이유는 모르겠지만, IShellFolder2::GetDetailsEx method과 특수 열 ID (PROPERTYKEY와 동일)를 사용해야합니다.

CComPtr<IShellItem> cpl; 
CComPtr<IShellFolder2> folder; 
CComPtr<IEnumShellItems> enumerator; 
PROPERTYKEY pkLocation; 
SHCreateItemFromParsingName(L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\\8\\::{7B81BE6A-CE2B-4676-A29E-EB907A5126C5}", nullptr, IID_PPV_ARGS(&cpl)); 

// bind to IShellFolder 
cpl->BindToHandler(NULL, BHID_SFObject, IID_PPV_ARGS(&folder)); 

// bind to IEnumShellItems 
cpl->BindToHandler(NULL, BHID_EnumItems, IID_PPV_ARGS(&enumerator)); 

// get this property key's value 
PSGetPropertyKeyFromName(L"System.Software.InstallLocation", &pkLocation); 

for (CComPtr<IShellItem> child; enumerator->Next(1, &child, nullptr) == S_OK; child.Release()) 
{ 
    // get child's display name 
    CComHeapPtr<wchar_t> name; 
    child->GetDisplayName(SIGDN_NORMALDISPLAY, &name); 
    wprintf(L"%s\n", name); 

    // get child's PIDL 
    CComHeapPtr<ITEMIDLIST> pidl; 
    SHGetIDListFromObject(child, &pidl); 

    // the PIDL is absolute, we need the relative one (the last itemId in the list) 
    // get it's install location 
    CComVariant v; 
    if (SUCCEEDED(folder->GetDetailsEx(ILFindLastID(pidl), &pkLocation, &v))) 
    { 
     // it's a VT_BSTR 
     wprintf(L" %s\n", v.bstrVal); 
    } 
} 

참고로 문서화되지 않은 System.Software.InstallLocation PROPERTYKEY를 사용하고 있습니다. 그것을 찾으려면 방금 각 열마다 다음과 같은 코드를 사용하여 모든 열을 버렸습니다.

추신 : 많은 오류 검사를 추가하지 않았지만,

+0

감사합니다. @ 사이먼. :) 그냥 CoInitialize (NULL) 추가했습니다; 그렇지 않으면 SHCreateItemFromParsingName은 NULL을 반환합니다. 어떤 식 으로든 오류 검사를 추가하고 나에게 잘 작동합니다. 다시 한번 감사드립니다. :) – CrazyCoder

+0

예, 대부분의 셸 함수는 COM을 초기화해야합니다. –

+0

@CrazyCoder, 현상금이 만료되기 전에이 대답을 받아 들여야합니다. –

관련 문제