3

I have searched a lot and have got some findings on how to get extended FA, but they are in C# using the language's own built-in APIs. I am trying to find the author name for a file in Windows, but my requirement is in Go/Python/C/Batch (order of priority).

In python, the third party packages (exifread and hachoir_metadata) are not working (not giving any result for a sample doc/xlsx file. Maybe the package I am installing via pip-install is erroneous).

Is there any other way or any user-level MSDN API available?

Please let me know if any experience on this. Thanks.

bitbyter
  • 801
  • 1
  • 8
  • 17
  • 1
    You are not talking about NTFS extended attributes. Maybe rename question to something with the property system? – Anders Jun 29 '19 at 22:34

1 Answers1

3

In C, C++ or other language, you get file properties with IPropertyStore interface

For example, for a .jpg file (test on Windows 10, VS 2015) =>

I get for Author : System.Author(Auteurs) = Test Auteur

PIDLIST_ABSOLUTE pidl = ILCreateFromPath(L"E:\\icon_rose.jpg");
if (pidl != NULL)
{
    IPropertyStore *pps;
    HRESULT hr = SHGetPropertyStoreFromIDList(pidl, GPS_DEFAULT, IID_PPV_ARGS(&pps));
    if (SUCCEEDED(hr))
    {
        DWORD dwCount;
        hr = pps->GetCount(&dwCount);
        PROPERTYKEY propKey;
        for (DWORD i = 0; i < dwCount; ++i)
        {
            hr = pps->GetAt(i, &propKey);
            if (SUCCEEDED(hr))
            {
                PWSTR pszCanonicalName = NULL;
                hr = PSGetNameFromPropertyKey(propKey, &pszCanonicalName);                      
                PWSTR pszDescriptionName = NULL;
                IPropertyDescription *ppd;
                hr = PSGetPropertyDescription(propKey, IID_PPV_ARGS(&ppd));
                if (SUCCEEDED(hr))
                {
                    hr = ppd->GetDisplayName(&pszDescriptionName);
                    ppd->Release();
                }
                PROPVARIANT propvarValue = { 0 };
                HRESULT hr = pps->GetValue(propKey, &propvarValue);
                if (SUCCEEDED(hr))
                {
                    PWSTR pszDisplayValue = NULL;
                    hr = PSFormatForDisplayAlloc(propKey, propvarValue, PDFF_DEFAULT, &pszDisplayValue);
                    if (SUCCEEDED(hr))
                    {
                        WCHAR wsBuffer[255];
                        wsprintf(wsBuffer, L"%s(%s) = %s\n", pszCanonicalName, (pszDescriptionName==NULL?L"Unknown":pszDescriptionName), pszDisplayValue);
                        OutputDebugString(wsBuffer);
                        CoTaskMemFree(pszDisplayValue);
                    }
                    PropVariantClear(&propvarValue);
                }
                if (pszCanonicalName != NULL)
                    CoTaskMemFree(pszCanonicalName);
                if (pszDescriptionName != NULL)
                    CoTaskMemFree(pszDescriptionName);;                         
            }
        }                   
        pps->Release();
    }
    ILFree(pidl);
}
Castorix
  • 1,465
  • 1
  • 9
  • 11
  • Hi. Thanks for the information, but unfortunately the call to SHGetPropertyStoreFromIDList() is always failing (hr = -2147221008). Any suggestion regarding that. – bitbyter Jun 30 '19 at 11:18
  • 1
    Thsi error is **CO_E_NOTINITIALIZED**, so you must initialize COM first, like : `HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); if (SUCCEEDED(hr)) { // Code... }`: – Castorix Jun 30 '19 at 11:54
  • Thanks again, mate. But unfortunately, I am not getting the Author name. Following are the attributes that I receive. `System.ItemFolderNameDisplay System.ItemTypeText System.ItemNameDisplay System.Size System.FileAttributes System.DateModified` I have checked. The doc file contains the author. – bitbyter Jun 30 '19 at 13:33
  • 1
    I cannot reproduce your problem... I just tested with a random .doc file with those [Doc Props](https://i.ibb.co/zs7hfpy/docprops.jpg) (french) I get 87 properties and one of them is **System.Author(Auteurs) = Truß, Johannes**, like in the properties dialog box – Castorix Jun 30 '19 at 14:08
  • My code is an almost full copy paste of yours. https://ideone.com/7bwTcf On Windows 10 I am testing. Could you also send your complete code? – bitbyter Jun 30 '19 at 14:13
  • 1
    I uploaded a Win32 console test program with the .doc file I tested (VS 2015 project) => [Test_IPropertyStore.zip](https://app.box.com/s/ofgltk26od3joqahgtm53eszrkpxguc6) – Castorix Jun 30 '19 at 14:55