На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
Дорогие девчонки! Поздравляем вас с праздником 8 Марта!
msm.ru
! user posted image
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Соблюдайте общие правила форума

Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как запустить программу/файл? (и дождаться ее завершения)
5. Как перехватить API-функции, поставить hook? (перехват сообщений от мыши, клавиатуры - внедрение в удаленное адресное прстранство)
... (продолжение следует) ...

Внимание:
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки - бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Rouse_, user posted image Krid

Модераторы: Rouse_, Krid
Страницы: (2) 1 [2]  все  ( Перейти к последнему сообщению )  
> Как извлечь информацию из файла , как на вкладке "Сводка" в Windows Explorer
    Господа программисты, помогите!
    Имею биологическое образование. Третью неделю лажу по интернету, одно понял - без вашей помощи мне не обойтись.
    Мне нужно получать свойства (автор, ключевые слова) из не compound файлов (в частности TIFF, JPEG). Как я понял, на этом форуме говорится именно об этом. Но разговор окончился на том, что Krid изменил код на подходящий, и... все.
    Выручайте! Опубликуйте исходник.
      Цитата к.б.н. @
      Мне нужно получать свойства (автор, ключевые слова) из не compound файлов (в частности TIFF, JPEG).


      Вот тебе пример. Снимает то, что тебе нужно и немного еще (из дополнительных свойств нет времени писать демку полного разбора)

      ExpandedWrap disabled
        uses
          GDIPOBJ,
          GDIPAPI,
          GDIPUTIL,
          ActiveX;
         
        {$R *.dfm}
         
        procedure TForm1.Button1Click(Sender: TObject);
         
          function GetAdvTagData(const ID: Integer): String;
          const
            TAG_Title     = 40091;
            TAG_Comments  = 40092;
            TAG_Author    = 40093;
            TAG_KeyWords  = 40094;
            TAG_Subject   = 40095;
          begin
            case ID of
              TAG_Title:    Result := 'Title';
              TAG_Comments: Result := 'Comments';
              TAG_Author:   Result := 'Author';
              TAG_KeyWords: Result := 'KeyWords';
              TAG_Subject:  Result := 'Subject';
            else
              Result := '';
            end;
          end;
         
        var
          GDIImage: TGPImage;
          I, ACount, PropSize: Integer;
          PropertyesList: array of TPropId;
          PropertyItem: PPropertyItem;
          PropName: String;
          PropValue: WideString;
          ByteValue: DWORD;
        begin
          if OpenDialog1.Execute then
          begin
            Memo1.Clear;
            GDIImage := TGPImage.Create(OpenDialog1.FileName);
            try
              ACount := GDIImage.GetPropertyCount;
              SetLength(PropertyesList, ACount);
              GDIImage.GetPropertyIdList(ACount, @PropertyesList[0]);
              for I := 0 to ACount - 1 do
              begin
                PropSize := GDIImage.GetPropertyItemSize(PropertyesList[I]);
                GetMem(PropertyItem, PropSize);
                try
                  GDIImage.GetPropertyItem(PropertyesList[I], PropSize, PropertyItem);
                  PropName := GetAdvTagData(PropertyesList[I]);
                  if PropName <> '' then
                  begin
                    SetLength(PropValue, PropertyItem^.length);
                    Move(PropertyItem^.value^, PropValue[1], PropertyItem^.length);
                  end
                  else
                  begin
                    PropName := GetMetaDataIDString(PropertyItem^.id);
                    ByteValue := 0;
                    if PropertyItem^.type_ in
                      [PropertyTagTypeByte, PropertyTagTypeShort,
                       PropertyTagTypeLong] then
                    begin
                      if PropertyItem^.length <= 4 then
                      begin
                        Move(PropertyItem^.value^, ByteValue, PropertyItem^.length);
                        PropValue := IntToStr(ByteValue);
                      end
                      else
                      begin
                        SetLength(PropValue, PropertyItem^.length);
                        Move(PropertyItem^.value^, PropValue[1], PropertyItem^.length);
                      end;
                    end;
                  end;
                  Memo1.Lines.Add(PropName + ' - ' + PropValue);
                finally
                  FreeMem(PropertyItem);
                end;
              end;
            finally
              GDIImage.Free;
            end;
          end;
        end;
        Цитата к.б.н. @
        Мне нужно получать свойства (автор, ключевые слова) из не compound файлов (в частности TIFF, JPEG). Как я понял, на этом форуме говорится именно об этом.

        Не правильно понял. Читай внимательно предыдущие посты и введение к коду из фака (как извлечь "Сводку" свойств файла). Там говорится о стандартных св-вах, хранящихся либо внутри compound файлов либо в файловых потоках, ассоциированных с файлом.
        А получение специфических св-в файлов определённого типа - это совсем из другой оперы. Тут используются свои наборы API (см. например, код Rouse_ - там юзаются ф-ции из gdiplus.dll)/свои интерфейсы/прямое чтение "тэгов" из файла/etc.
        Вобщем, твой вопрос (о св-вах TIFF, JPEG) скорее для форума Delphi: Multimedia
          Благодарю!
          Отличный код. Все работает. Правда, чтобы получить только необходимое (название, коммент., автор...), я его несколько укоротил.

          Для таких же тупых как я, прокомментирую:
          Здесь используется новый интерфейс GDI+. Работает на Windows XP и .NET Server, на более ранних ПО не работает (без определенной доработки).
          Чтобы с этим кодом заработал Delphi, в него надо установить соответствующие заголовочные файлы (подробности http://www.delphikingdom.com/asp/viewitem.asp?catalogid=772 )
            MSI файлы - это наборы таблиц и комманд для интерпретатора msiexec. Разумеется вы можете опросить таблицы внутри msi на предмет количесва названия файлов всего что вы пожелаете, есть даже SQL подобный язык. Для интересующихся - скачайте Microsoft MSI Orca. (http://www.technipages.com/downloadview-details-44-Orca_MSI_Editor.html).

            Примерно код для прочтения какого либо свойтсва из MSI:
            ExpandedWrap disabled
              const msilib = 'msi.dll';
               
              type
               
                MSIHANDLE = DWORD;    
                TMsiHandle = MSIHANDLE;
               
              function MsiCloseHandle(hAny: MSIHANDLE):UINT;stdcall;external msilib name 'MsiCloseHandle';
              function MsiOpenProduct(szProduct:LPCSTR;var hProduct:MSIHANDLE):UINT;stdcall;external msilib name 'MsiOpenProductA';
              function MsiGetProductProperty(hProduct:MSIHANDLE;szProperty:LPCSTR;lpValueBuf:LPSTR;pcchValueBuf:LPDWORD):UINT;stdcall; external msilib name 'MsiGetProductPropertyA';
              function MsiSetInternalUI(dwUILevel:INSTALLUILEVEL;phWnd:LPHWND):INSTALLUILEVEL;stdcall; external msilib name 'MsiSetInternalUI';
               
              function GetMSIProperty(aProductCode:string):string;
              var
               msi:TMSIHandle;
               t:string;
               
               function _getmsiproperty(_name:string):string;
               var
                txt:PChar;
                sz:DWORD;
               begin
                sz:=MAX_PATH;
                txt:=AllocMem(sz+1);
                if MsiGetProductProperty(msi,PChar(_name),txt,@sz)=ERROR_MORE_DATA then
                 begin
                  ReAllocMem(txt,sz+1);
                  MsiGetProductProperty(msi,PChar(_name),txt,@sz);
                 end;
                SetString(Result,txt,sz);
                FreeMem(txt,sz+1);
               end;
               
              begin
               MsiSetInternalUI(2,nil); // скрываем GUI
               if MsiOpenProduct(PChar(aProductCode),msi)=ERROR_SUCCESS then
                begin
                 t:=_getmsiproperty('ARPPRODUCTICON'); // главная иконка приложения
                     if t='' then t:=_getmsiproperty('ProductIcon');
                     if t='' then t:=_getmsiproperty('CompleteSetupIcon');
                     if t='' then t:=_getmsiproperty('CustomSetupIcon');
                     if t='' then t:=_getmsiproperty('InfoIcon');
                     if t='' then t:=_getmsiproperty('InstallerIcon');
                     if t='' then t:=_getmsiproperty('RemoveIcon');
                     if t='' then t:=_getmsiproperty('RepairIcon');
                     Result:=t;
                     MsiCloseHandle(msi);
                end;
              end;
            Сообщение отредактировано: Krid -
              работаю на builder c++,

              но к сожалению, у меня при вызове
              hr = pPropSetStg->Open(PropSetfmtid, STGM_READ, &pPropStg );
              получаю hr равную -2147286785, т.е. возникает ошибка, для doc файлов такая ошибка не возникает

              вот весь участок кода:
              ExpandedWrap disabled
                FMTID PropSetfmtid={0xf29f85e0,0x4ff9,0x1068,{0xab, 0x91, 0x08, 0x00, 0x2b, 0x27, 0xb3, 0xd9 }};
                HRESULT hr = S_OK;
                IPropertyStorage *pPropStg = NULL;
                IPropertySetStorage *pPropSetStg = NULL;
                IStorage *stgRoot = NULL;
                PROPSPEC propspec;
                PROPVARIANT propRead;
                 
                if (StgOpenStorageEx(StringToOleStr(FileName), STGM_READ | STGM_SHARE_DENY_WRITE,
                STGFMT_ANY, 0, NULL, NULL, IID_IPropertySetStorage, reinterpret_cast<void**>(&pPropSetStg))
                != S_OK) return;
                 
                //if (pPropSetStg->Open(PropSetfmtid, STGM_DIRECT | STGM_SHARE_EXCLUSIVE | STGM_READ, &pPropStg ) != S_OK)
                // return;
                hr = pPropSetStg->Open(PropSetfmtid, STGM_DIRECT | STGM_SHARE_EXCLUSIVE | STGM_READ, &pPropStg );
                 
                propspec.ulKind = PRSPEC_PROPID;
                propspec.propid = 0x00000002;
                 
                pPropStg->ReadMultiple(1, &propspec, &propRead);
                AnsiString Title = propRead.pszVal;

              подскажите пожалуйста как можно считать свойства из pdf и djvu файла? почему возникает ошибка?
                Доброго времени суток.
                Подскажите пожалуйста.
                Использую за основу код из сообщения #5 от Krid.
                Но я хочу получить пользовательское свойство из .DOC файла.
                Вот такой код получился.

                ExpandedWrap disabled
                  procedure TForm1.Button1Click(Sender: TObject);
                  var
                    stgRoot: IStorage;
                    stgPS: IPropertySetStorage;
                    stgP: IPropertyStorage;
                    ps: ^TPropSpec;
                    pv: ^TPropVariant;
                    ReturnCode: Integer;
                  begin
                  // выбираем файл
                    if (not OpenDialog1.Execute) then
                      exit;
                   
                    // Проверяем: если это не compound file и система - не NTFS, тогда выходим.
                    // (для compound файлов FS не важна)
                    if (StgIsStorageFile(StringToOleStr(OpenDialog1.FileName))<>S_OK) then
                      if (not IsNTFS(OpenDialog1.FileName)) then begin
                        MessageBox(Handle,'NTFS needed for non-compound files','Error',MB_ICONERROR);
                        exit;
                      end;
                   
                    if (StgOpenStorageEx(StringToOleStr(OpenDialog1.FileName), STGM_READ or STGM_SHARE_DENY_WRITE,
                                          STGFMT_ANY, 0, nil,  nil,
                                         @IID_IPropertySetStorage, stgRoot)<>S_OK) then  // открываем его
                    begin
                      MessageBox(Handle,'Can not open file','Error',MB_ICONERROR);
                      exit;
                    end;
                   
                    stgPS := stgRoot as IPropertySetStorage;  // ссылаемся на нужный интерфейс
                    if (stgPS.Open(FMTID_SummaryInformation, STGM_READ or STGM_SHARE_EXCLUSIVE, stgP) <> S_OK) then // открываем набор св-в
                    begin
                      MessageBox(Handle,'Can not open property set','Error',MB_ICONERROR);
                      exit;
                    end;
                    ps:=nil;
                    pv:=nil;
                    try
                      GetMem(ps,SizeOf(TPropSpec));
                      GetMem(pv,SizeOf(TPropVariant));
                   
                      // свойство по номеру
                  //    ps.ulKind := PRSPEC_PROPID;
                  //    ps.propid := PIDSI_TITLE;
                   
                      // свойство по имени
                      ps.ulKind := PRSPEC_LPWSTR;
                      ps.lpwstr := 'QWERTY';
                   
                      // читаем св-во
                      ReturnCode := stgP.ReadMultiple(1, ps, pv);
                      if ReturnCode = S_OK then
                        ShowMessage(pv.pszVal)
                      else
                        ShowMessage('Error!!!');
                    finally
                      if assigned(ps) then
                        FreeMem(ps);
                      if assigned(pv) then
                        FreeMem(pv);
                      stgP := nil;
                      stgPS := nil;
                      stgRoot := nil;
                    end;
                   
                  end;

                В тестируемом DOC файле создал свойство QWERTY при чтении свойство по имени всегда S_FALSE.
                Чтение стандартных свойств по номеру работает.
                Подскажите, пожалуйста что я не правильно делаю.
                  Пользовательские св-ва надо считывать из набора UserDefinedProperties, а ты открываешь SummaryInformation.

                  В stgPS.Open вместо FMTID_SummaryInformation юзай FMTID_UserDefinedProperties ({D5CDD505-2E9C-101B-9397-08002B2CF9AE})
                    Спасибо большое. Получилось.
                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                    0 пользователей:


                    Рейтинг@Mail.ru
                    [ Script execution time: 0,0339 ]   [ 16 queries used ]   [ Generated: 12.03.25, 03:44 GMT ]