Dokumententitel auslesen
-
Eine PDF Datei ist keine COM-Structured storage!
-
mr schrieb:
Eine PDF Datei ist keine COM-Structured storage!
hm, wie komm da dann an die Information die ich brauche. hatte es mal mit GetDetailsOf probiert, aber keine der information die ich damit bekommen hab, war die, die ich gesucht hab.....
-
Ich hab mal nach GetDetailsOf bei Codeproject gesucht und darauf gestossen:
http://www.codeproject.com/KB/files/detailedfileinfo.aspx
Bei mir kanns die PDF Informationen auslesen, wenn Adobe Acrobat Reader installiert ist.
-
hatte dazu schonmal eine "eigene" routine gebastelt, (ok, sind zusammenkopierte code-schnipsel).
damit kann ich informationen lesen wie dateiname, änderungsdatum, erstellungsdatum usw. aber halt nicht die titelinformation
würde mich interessieren was ich falsch gemacht hab, aber aufjedenfall schonmal danke für den link. (würd am liebsten aber keine fremden klassen benutzen, dann weis ich wenigsten das ich schuld bin, wenns nicht funktioniert
).kannst du mir evtl sagen was ich da falsch machen, ich komm an alles ran, nur nicht an den doofen titel.
// GetDetailsOf.cpp : Defines the entry point for the console application. // #include "stdafx.h" // ListDirCon.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung. // #include "stdafx.h" #include "windows.h" #include "shlobj.h" #include <iostream> using namespace std; int _tmain(int argc, TCHAR* argv[]) { char path[MAX_PATH] = "C:\\temp\\"; HRESULT hr; IShellFolder * isfDesktop = NULL; IShellFolder2 * isfCur = NULL; hr = CoInitialize(NULL); // initialize COM LPMALLOC pMalloc = NULL; // memory manager, for freeing up PIDLs hr = SHGetMalloc(&pMalloc); hr = SHGetDesktopFolder(&isfDesktop); isfDesktop->QueryInterface(IID_IShellFolder2, (LPVOID*)&isfCur); // IShellFolder::ParseDisplayName requires the path name in Unicode. OLECHAR olePath[MAX_PATH]; // wide-char version of path name MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, path, -1, olePath, MAX_PATH); // parse path for absolute PIDL, and connect to target folder LPITEMIDLIST pidl = NULL; // general purpose hr = isfDesktop->ParseDisplayName(NULL, NULL, olePath, NULL, &pidl, NULL); LPSHELLFOLDER psfFolder = NULL; hr = isfDesktop->BindToObject(pidl, NULL, IID_IShellFolder, (void**)&psfFolder); isfDesktop->Release(); // no longer required pMalloc->Free(pidl); LPENUMIDLIST penumIDL = NULL; // IEnumIDList interface for reading contents hr = psfFolder->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &penumIDL); while(1) { // retrieve a copy of next local item ID list hr = penumIDL->Next(1, &pidl, NULL); if(hr == NOERROR) { WIN32_FIND_DATA ffd; hr = SHGetDataFromIDList(psfFolder, pidl, SHGDFIL_FINDDATA, &ffd, sizeof(WIN32_FIND_DATA)); SHELLDETAILS sd; hr = isfCur->GetDetailsOf(pidl, 0, &sd); wcout<<sd.str.pOleStr<<endl; hr = isfCur->GetDetailsOf(pidl, 1, &sd); wcout<<sd.str.pOleStr<<endl; hr = isfCur->GetDetailsOf(pidl, 2, &sd); wcout<<sd.str.pOleStr<<endl; hr = isfCur->GetDetailsOf(pidl, 3, &sd); wcout<<sd.str.pOleStr<<endl; hr = isfCur->GetDetailsOf(pidl, 4, &sd); wcout<<sd.str.pOleStr<<endl; hr = isfCur->GetDetailsOf(pidl, 5, &sd); wcout<<sd.str.pOleStr<<endl; hr = isfCur->GetDetailsOf(pidl, 6, &sd); wcout<<sd.str.pOleStr<<endl; hr = isfCur->GetDetailsOf(pidl, 7, &sd); wcout<<sd.str.pOleStr<<endl; hr = isfCur->GetDetailsOf(pidl, -1, &sd); wcout<<sd.str.pOleStr<<endl; wcout << L"Name = " << ffd.cFileName << endl; wcout << L"Type = " << ( (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? "dir\n" : "file\n" ); wcout << L"Size = " << ffd.nFileSizeLow << endl; pMalloc->Free(pidl); } else break; } // release all remaining interface pointers penumIDL->Release(); psfFolder->Release(); pMalloc->Release(); CoUninitialize(); // shut down COM return 0; }
-
Ich werd demnächst mal gucken ob ich den Fehler finde, aber ich kann da nichts versprechen, ich kenn mich damit nämlich auch nicht aus. Aber ich hatte gar nicht gesehen das Martin Richter dir schon einen Link gegeben hat. Da kannst du doch einfach ein paar Debug-Ausgaben reinbauen um z.B. zu sehen welche ID der Titel hat.
-
Ich wüsste auch nicht wie man das mit GetDetailsOf zuverlässig hinbekommen soll wenn die ID immer unterschiedlich sein kann.
Deshalb habe ich nach einem Beispiel für GetDetailsEx gegoogled und bin auf das gestossen: http://www.experts-exchange.com/Programming/Languages/CPP/Q_21038514.htmlKanns im Moment nicht ausprobieren, aber es sieht gut aus.

-
Schade, klappt doch nicht, wenn man GetDetailsEx mit FMTID_SummaryInformation benutzt funktioniert es nur bei Dateien mit Structured Storage.
-
Ah es geht doch, hatte nur ein CoInitializeEx oder OleInitialize vergessen.

#include <windows.h> #include <shlobj.h> #include <iostream> #include <string> std::wstring getTitle(const std::wstring& path, const std::wstring& filename) { IMalloc* pMalloc; SHGetMalloc(&pMalloc); IShellFolder* pDesktopFolder; SHGetDesktopFolder(&pDesktopFolder); ITEMIDLIST* pidlShellItem; pDesktopFolder->ParseDisplayName(NULL, NULL, const_cast<wchar_t*>(path.c_str()), NULL, &pidlShellItem, NULL); IShellFolder2* pFolder; pDesktopFolder->BindToObject(pidlShellItem, NULL, IID_IShellFolder2, reinterpret_cast<void**>(&pFolder)); pMalloc->Free(pidlShellItem); pFolder->ParseDisplayName(NULL, NULL, const_cast<wchar_t*>(filename.c_str()), NULL, &pidlShellItem, NULL); SHCOLUMNID columnId; columnId.fmtid = FMTID_SummaryInformation; columnId.pid = PIDSI_TITLE; VARIANT variant; pFolder->GetDetailsEx(pidlShellItem, &columnId, &variant); pMalloc->Free(pidlShellItem); pMalloc->Release(); pFolder->Release(); pDesktopFolder->Release(); return variant.bstrVal; } int main() { OleInitialize(NULL); std::wcout << getTitle(L"C:\\", L"test.pdf") << '\n'; }Der Code braucht natürlich noch eine Überarbeitung, speziell in Sachen Fehlerbehandlung.
-
hey, vielen Dank !!!
-
Freut mich das es dir geholfen hat.

Habe noch 3 Sachen gefunden die man verbessern kann:
- VariantClear benutzen, sonst gibts ein Memory-Leak, die Funktion gibt unter anderem bstrVal frei.
- CoTaskMemFree benutzen statt dem IMalloc-Objekt
- SHBindToParent, dank dieser Funktion braucht man Pfad zum Ordner und Dateiname nicht mehr getrennt angeben#include <windows.h> #include <shlobj.h> #include <iostream> #include <string> std::wstring getTitle(const std::wstring& filePath) { IShellFolder* pDesktopFolder; SHGetDesktopFolder(&pDesktopFolder); ITEMIDLIST* pFileIdentifierList; pDesktopFolder->ParseDisplayName(NULL, NULL, const_cast<wchar_t*>(filePath.c_str()), NULL, &pFileIdentifierList, NULL); IShellFolder2* pShellFolder; const ITEMIDLIST* pFileIdentifier; SHBindToParent(pFileIdentifierList, IID_IShellFolder2, reinterpret_cast<void**>(&pShellFolder), &pFileIdentifier); PROPERTYKEY propertyKey; propertyKey.fmtid = FMTID_SummaryInformation; propertyKey.pid = PIDSI_TITLE; VARIANT variant; pShellFolder->GetDetailsEx(pFileIdentifier, &propertyKey, &variant); std::wstring result(variant.vt == VT_BSTR ? variant.bstrVal : L""); VariantClear(&variant); CoTaskMemFree(pFileIdentifierList); pShellFolder->Release(); pDesktopFolder->Release(); return result; } int main() { CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); std::wcout << getTitle(L"C:\\test.pdf") << '\n'; CoUninitialize(); }
-
hier:
http://www.scribd.com/doc/2347097/Windows-Shell-Programming-in-Visual-C-bin uach neu in der thematik..
habe dieses buch gefunden..
ist zwar sehr alt (win 95, 98 usw^^) wird aber am anfang grundwissen erklärt..unter anderem pidls und so weiter..