none
Metadaten von Dateien bearbeiten RRS feed

  • Frage

  • Hallo,

    gibt es in .NET die Möglichkeit, Metadaten von Dateien zu bearbeiten? Ich verstehe darunter die Informationen, die ich im Explorer unter Eigenschaften -> Details aufrufen kann. Im speziellen interessieren mich PDF- und XLS(X)-Dateien. Kann ich dort eigene Eigenschaften und Werte hinzufügen oder bestehende anpassen?

    Beste Grüße,

    Sven

    Mittwoch, 22. Dezember 2010 07:28

Antworten

  • Hallo Sven,

    früher hat man das oft mit folgenden Techniken gemacht:

    [Erweiterte Dateiinfos in C#]
    http://www.eggheadcafe.com/software/aspnet/35615191/erweiterte-dateiinfos.aspx

    Jetzt würde ich das evtl. eher typsicher über das:

    [Windows® API Code Pack for Microsoft® .NET Framework - Home]
    http://code.msdn.microsoft.com/WindowsAPICodePack

    machen. Also zum Beispiel unter Verweise folgende DLL einbinden:  "Microsoft.WindowsAPICodePack.Shell.dll".
    Dann zum Beispiel Code wie folgenden benutzen:

    using System;
    using System.Text;
    using System.Windows.Forms;
    using Microsoft.WindowsAPICodePack.Shell;
    using Microsoft.WindowsAPICodePack.Shell.PropertySystem;
    
    namespace WindowsAPICodePackDemo
    {
     public partial class Form1 : Form
     {
     DataGridView dgv = new DataGridView();
    
     public Form1()
     {
     InitializeComponent();
     dgv.Columns.Add("Eigenschaft", "Eigenschaft");
     dgv.Columns.Add("Wert", "Wert");
     dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
     dgv.Dock = DockStyle.Fill; Controls.Add(dgv);
    
     AnzeigeAllerEigenschaften(ShellFile.FromFilePath("Mappe1.xlsx"));
     AnzeigeAllerEigenschaften(ShellFile.FromFilePath("PdfDemo.pdf"));
    
     this.Show();
     }
    
     private void AnzeigeAllerEigenschaften(ShellFile sf)
     {
     DateiAnfangsZeile(sf);
     AnzeigeAllerProperties(sf.Properties.System);
     AnzeigeAllerProperties(sf.Properties.DefaultPropertyCollection);
     AnzeigeAllerProperties(sf.Properties.System.Document);
     }
    
     private void DateiAnfangsZeile(ShellFile sf1)
     {
     dgv.Rows.Add("============", "=========================");
     dgv.Rows.Add("Datei", sf1.Name);
     dgv.Rows.Add("============", "=========================");
     }
    
     private void AnzeigeAllerProperties(object pd)
     {
     var propCol = pd as ShellPropertyCollection;
     if (propCol != null)
     foreach (IShellProperty prop in propCol)
     {
      if (prop == null) continue;
      if (prop.ValueAsObject == null) continue;
      Zufügen(prop.Description, prop.ValueAsObject);
     }
    
     var propDoc = pd as ShellProperties.PropertySystemDocument;
     if (propDoc != null)
     foreach (var p in propDoc.GetType().GetProperties())
     {
      var prop = p.GetValue(pd, null) as IShellProperty;
      if (prop == null) continue;
      if (prop.ValueAsObject == null) continue;
      Zufügen(prop.Description, prop.ValueAsObject);
     }
     
     if (propCol == null && propDoc == null)
     foreach (var p in pd.GetType().GetProperties())
     {
      var prop = p.GetValue(pd, null) as IShellProperty;
      if (prop == null) continue;
      if (prop.ValueAsObject == null) continue;
      Zufügen(prop.Description, prop.ValueAsObject);
     }
     }
    
     StringBuilder sb = new StringBuilder();
    
     private void Zufügen(ShellPropertyDescription beschreibung, object wert)
     {
     string name = beschreibung.DisplayName + "(" + beschreibung.CanonicalName + ")";
     if (wert is Array)
     foreach (var item in (Array)wert)
      dgv.Rows.Add(name, item);
     else dgv.Rows.Add(name, wert);
     } 
     }
    }
    
    

    Je nach Format gibt es natürlich auch oft spezialisierte Libs - für PDF etwa:

    [pdfsharp - Release: PDFsharp and MigraDoc Foundation 1.31]
    http://pdfsharp.codeplex.com/releases/view/37054
    http://stackoverflow.com/questions/1465434/edit-metadata-of-pdf-file-with-c


    ciao Frank
    Mittwoch, 22. Dezember 2010 12:53
  • Hallo Sven

    dies dürfte Format-spezifisch sein.
    Mindestens bei klassischen Office-Files war AFAIK folgender Ansatz möglich
    OLE File Property Reader DsoFile, IPropertyStrorage
    http://www.microsoft.com/downloads/en/details.aspx?FamilyId=9BA6FAC6-520B-4A0A-878A-53EC8300C4C2

    dort drin gibt es auch Bsp für neuen Format (non-OLE).
    Ob dies dann für PDF via "custom property handler" auch geht weiss ich nicht, MSDN (C++) wäre
    http://msdn.microsoft.com/en-us/library/cc144129(VS.85).aspx

    Mittwoch, 22. Dezember 2010 07:44

Alle Antworten

  • Hallo Sven

    dies dürfte Format-spezifisch sein.
    Mindestens bei klassischen Office-Files war AFAIK folgender Ansatz möglich
    OLE File Property Reader DsoFile, IPropertyStrorage
    http://www.microsoft.com/downloads/en/details.aspx?FamilyId=9BA6FAC6-520B-4A0A-878A-53EC8300C4C2

    dort drin gibt es auch Bsp für neuen Format (non-OLE).
    Ob dies dann für PDF via "custom property handler" auch geht weiss ich nicht, MSDN (C++) wäre
    http://msdn.microsoft.com/en-us/library/cc144129(VS.85).aspx

    Mittwoch, 22. Dezember 2010 07:44
  • Hallo Sven,

    früher hat man das oft mit folgenden Techniken gemacht:

    [Erweiterte Dateiinfos in C#]
    http://www.eggheadcafe.com/software/aspnet/35615191/erweiterte-dateiinfos.aspx

    Jetzt würde ich das evtl. eher typsicher über das:

    [Windows® API Code Pack for Microsoft® .NET Framework - Home]
    http://code.msdn.microsoft.com/WindowsAPICodePack

    machen. Also zum Beispiel unter Verweise folgende DLL einbinden:  "Microsoft.WindowsAPICodePack.Shell.dll".
    Dann zum Beispiel Code wie folgenden benutzen:

    using System;
    using System.Text;
    using System.Windows.Forms;
    using Microsoft.WindowsAPICodePack.Shell;
    using Microsoft.WindowsAPICodePack.Shell.PropertySystem;
    
    namespace WindowsAPICodePackDemo
    {
     public partial class Form1 : Form
     {
     DataGridView dgv = new DataGridView();
    
     public Form1()
     {
     InitializeComponent();
     dgv.Columns.Add("Eigenschaft", "Eigenschaft");
     dgv.Columns.Add("Wert", "Wert");
     dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
     dgv.Dock = DockStyle.Fill; Controls.Add(dgv);
    
     AnzeigeAllerEigenschaften(ShellFile.FromFilePath("Mappe1.xlsx"));
     AnzeigeAllerEigenschaften(ShellFile.FromFilePath("PdfDemo.pdf"));
    
     this.Show();
     }
    
     private void AnzeigeAllerEigenschaften(ShellFile sf)
     {
     DateiAnfangsZeile(sf);
     AnzeigeAllerProperties(sf.Properties.System);
     AnzeigeAllerProperties(sf.Properties.DefaultPropertyCollection);
     AnzeigeAllerProperties(sf.Properties.System.Document);
     }
    
     private void DateiAnfangsZeile(ShellFile sf1)
     {
     dgv.Rows.Add("============", "=========================");
     dgv.Rows.Add("Datei", sf1.Name);
     dgv.Rows.Add("============", "=========================");
     }
    
     private void AnzeigeAllerProperties(object pd)
     {
     var propCol = pd as ShellPropertyCollection;
     if (propCol != null)
     foreach (IShellProperty prop in propCol)
     {
      if (prop == null) continue;
      if (prop.ValueAsObject == null) continue;
      Zufügen(prop.Description, prop.ValueAsObject);
     }
    
     var propDoc = pd as ShellProperties.PropertySystemDocument;
     if (propDoc != null)
     foreach (var p in propDoc.GetType().GetProperties())
     {
      var prop = p.GetValue(pd, null) as IShellProperty;
      if (prop == null) continue;
      if (prop.ValueAsObject == null) continue;
      Zufügen(prop.Description, prop.ValueAsObject);
     }
     
     if (propCol == null && propDoc == null)
     foreach (var p in pd.GetType().GetProperties())
     {
      var prop = p.GetValue(pd, null) as IShellProperty;
      if (prop == null) continue;
      if (prop.ValueAsObject == null) continue;
      Zufügen(prop.Description, prop.ValueAsObject);
     }
     }
    
     StringBuilder sb = new StringBuilder();
    
     private void Zufügen(ShellPropertyDescription beschreibung, object wert)
     {
     string name = beschreibung.DisplayName + "(" + beschreibung.CanonicalName + ")";
     if (wert is Array)
     foreach (var item in (Array)wert)
      dgv.Rows.Add(name, item);
     else dgv.Rows.Add(name, wert);
     } 
     }
    }
    
    

    Je nach Format gibt es natürlich auch oft spezialisierte Libs - für PDF etwa:

    [pdfsharp - Release: PDFsharp and MigraDoc Foundation 1.31]
    http://pdfsharp.codeplex.com/releases/view/37054
    http://stackoverflow.com/questions/1465434/edit-metadata-of-pdf-file-with-c


    ciao Frank
    Mittwoch, 22. Dezember 2010 12:53
  • Hallo Frank

    Gerne frische ich nochmals diesen Thread auf, auch wenn es schon bald zwei Jahre her ist, aber mir stellt sich einfach folgende Frage:

    Wie kann auf die Custom Properties von Ole Dokumenten (Word, Excel, etc.) zugegriffen werden? Mit dem Windows® API Code Pack erhalte ich zwar eine Auflistung alles Properties, inklusive den Werten der Custom Properties. Leider fehlt aber ein CanonicalName oder dergleichen bei diesen. Zudem können auch keine weiteren CustomProperties zugefügt werden...

    Hat hier jemand eine Idee? Bei der codeplex Diskussion betreffend Windows® API Code Pack stehen ähnliche Fragen, aber leider finde ich im gesamten Web keine passende Antwort, respektive sehe ich keinen Ansatz ausser dem DsoFile...

    Besten Dank!

    CanOnade


    • Bearbeitet CanOnade Sonntag, 24. Juni 2012 18:17 Unvollständige Lösung
    Sonntag, 24. Juni 2012 15:29