पढ़ें / लिखें 'विस्तारित' फ़ाइल गुण (C #)


104

मैं यह जानने की कोशिश कर रहा हूं कि C # उदा। टिप्पणी, बिट दर, तिथि अभिगमन, श्रेणी आदि में विस्तारित फ़ाइल गुणों को कैसे पढ़ा / लिखा जा सकता है जिसे आप विंडोज एक्सप्लोरर में देख सकते हैं। कोई जानकारी यह कैसे करनी है? संपादित करें: मैं मुख्य रूप से वीडियो फ़ाइलों को पढ़ / लिखूंगा (AVI / DIVX / ...)


3
इस प्रश्न का स्पष्ट रूप से उत्तर नहीं दिया गया है क्योंकि स्वीकृत उत्तर केवल यह दर्शाता है कि विस्तारित गुण कैसे प्राप्त करें और उन्हें कैसे सेट करें
दिमित्री नेस्टरुक

1
विस्तारित गुणों को सेट करने के लिए देखें stackoverflow.com/questions/5337683/…
VoteC450

जवाबों:


83

VB के बारे में पागल न होने वालों के लिए, यहाँ यह c # में है:

ध्यान दें, आपको संदर्भ संवाद के COM टैब से Microsoft शैल नियंत्रण और स्वचालन का संदर्भ जोड़ना होगा ।

public static void Main(string[] args)
{
    List<string> arrHeaders = new List<string>();

    Shell32.Shell shell = new Shell32.Shell();
    Shell32.Folder objFolder;

    objFolder = shell.NameSpace(@"C:\temp\testprop");

    for( int i = 0; i < short.MaxValue; i++ )
    {
        string header = objFolder.GetDetailsOf(null, i);
        if (String.IsNullOrEmpty(header))
            break;
        arrHeaders.Add(header);
    }

    foreach(Shell32.FolderItem2 item in objFolder.Items())
    {
        for (int i = 0; i < arrHeaders.Count; i++)
        {
            Console.WriteLine(
              $"{i}\t{arrHeaders[i]}: {objFolder.GetDetailsOf(item, i)}");
        }
    }
}

3
इनमें से कोई एक मान कैसे निर्धारित करेगा? उदाहरण के लिए .txt फ़ाइल के लिए लेखक या प्रकाशक। मैं 7 जीत पर हूं और इसका इस्तेमाल किया है और यह एक खाली लेखक और प्रकाशक और 282 अन्य गुण दिखाता है
वैभव गर्ग

1
@Vainbhav - आप इन्हें सेट नहीं कर सकते।
csharptest.net

26
आपको Microsoft शैल नियंत्रण और स्वचालन को संदर्भ संवाद के COM टैब से जोड़ना होगा।
csharptest.net

2
उन्हें इस प्रश्न में बेहतर ढंग से कैसे शामिल किया जाए: stackoverflow.com/questions/5337683/…
निकोलस राउल

1
विंडोज 10 में यह केवल 52 फ़ील्ड्स को शामिल करता है जिसमें फ़्रेम दर, फ़्रेम ऊँचाई, चौड़ाई, .... शामिल नहीं है?
मिन्ह गुयेन

27

नहीं है एक CodeProject लेख एक ID3 पाठक के लिए। और kixtart.org पर एक धागा जिसमें अन्य गुणों के लिए अधिक जानकारी है। मूल रूप से, आप कॉल करने की आवश्यकता GetDetailsOf()विधि पर फ़ोल्डर के लिए खोल वस्तु shell32.dll


धन्यवाद, मुझे एक साथ खींचने में सक्षम होना चाहिए कि मुझे इससे क्या चाहिए
डेविड हेयस

26

समाधान 2016

अपने प्रोजेक्ट में निम्नलिखित NuGet पैकेज जोड़ें:

  • Microsoft.WindowsAPICodePack-Shell Microsoft द्वारा
  • Microsoft.WindowsAPICodePack-Core Microsoft द्वारा

गुण पढ़ें और लिखें

using Microsoft.WindowsAPICodePack.Shell;
using Microsoft.WindowsAPICodePack.Shell.PropertySystem;

string filePath = @"C:\temp\example.docx";
var file = ShellFile.FromFilePath(filePath);

// Read and Write:

string[] oldAuthors = file.Properties.System.Author.Value;
string oldTitle = file.Properties.System.Title.Value;

file.Properties.System.Author.Value = new string[] { "Author #1", "Author #2" };
file.Properties.System.Title.Value = "Example Title";

// Alternate way to Write:

ShellPropertyWriter propertyWriter =  file.Properties.GetPropertyWriter();
propertyWriter.WriteProperty(SystemProperties.System.Author, new string[] { "Author" });
propertyWriter.Close();

जरूरी:

फ़ाइल एक मान्य होनी चाहिए, जो विशिष्ट निर्दिष्ट सॉफ़्टवेयर द्वारा बनाई गई है। प्रत्येक फ़ाइल प्रकार में विशिष्ट विस्तारित फ़ाइल गुण होते हैं और उनमें से सभी राइट नहीं होते हैं।

यदि आप डेस्कटॉप पर किसी फ़ाइल को राइट-क्लिक करते हैं और किसी प्रॉपर्टी को संपादित नहीं कर सकते हैं, तो आप उसे कोड में भी संपादित करने में सक्षम नहीं होंगे।

उदाहरण:

  • डेस्कटॉप पर txt फ़ाइल बनाएँ, docx के लिए इसके एक्सटेंशन का नाम बदलें। आप अपने संपादित नहीं कर सकते Authorया Titleसंपत्ति।
  • इसे वर्ड से खोलें, एडिट करें और सेव करें। अब आप कर सकते हैं।

तो बस कुछ का उपयोग सुनिश्चित करें try catch

इसके अलावा विषय: MSDN: संपत्ति संचालकों को लागू करना


मैं Microsoft से इन नामों के किसी भी पैकेज को नहीं देखता
याकूब

1
@JacobBrewer यह वास्तव में एक है जिसे "acdvorak" द्वारा अपलोड किया गया था: nuget.org/packages/Microsoft.WindowsAPICodePack-Shell । Visual Studio NuGet-Package-Manager में इसे "Microsoft द्वारा" दिखाया गया है। इसी तरह के नामों वाले अन्य पैकेज इसके कांटे हैं और यह ठीक से काम भी कर सकते हैं या सट्टेबाज भी। मुझे नहीं पता ...
मार्टिन श्नाइडर

25

VB.NET में यह नमूना सभी विस्तारित गुणों को पढ़ता है:

Sub Main()
        Dim arrHeaders(35)

        Dim shell As New Shell32.Shell
        Dim objFolder As Shell32.Folder

        objFolder = shell.NameSpace("C:\tmp")

        For i = 0 To 34
            arrHeaders(i) = objFolder.GetDetailsOf(objFolder.Items, i)
        Next
        For Each strFileName In objfolder.Items
            For i = 0 To 34
                Console.WriteLine(i & vbTab & arrHeaders(i) & ": " & objfolder.GetDetailsOf(strFileName, i))
            Next
        Next

    End Sub

आपको संदर्भ संवाद के COM टैब से Microsoft शैल नियंत्रण और स्वचालन का संदर्भ जोड़ना होगा ।


2
वर्थ नोटिंग कि विंडोज 7 (कम से कम) पर आप अरेस्टहेडर्स का आकार बढ़ाकर सिर्फ 280 से ज्यादा कर सकते हैं और अतिरिक्त मेटा-डेटा वापस पा सकते हैं। मुझे यह तब पता चला जब मैं डब्ल्यूटीवी फ़ाइल (विंडोज 7 मीडिया सेंटर रिकॉर्ड किए गए टेलीविज़न शो) से मेटा-डेटा प्राप्त करने का एक तरीका ढूंढ रहा था।
रिचर्ड

1
I = 0 से 34 लूप के लिए पहला i = 0 से Integer.MaxValue के लिए होना चाहिए। फिर objFolder.GetDetailsOf (objFolder.Items, i) के रिटर्न मान का परीक्षण करें। यदि यह अशक्त या व्हॉट्सएप स्पेस देता है तो आपके पास सभी हेडर हैं।
टिम मर्फी

@TimMurphy, दुर्भाग्य से, यह सही नहीं है (कम से कम विंडोज 10 या 7 पर)। कुछ हेडर खाली हैं, इसलिए आपको सभी अनुक्रमित के माध्यम से लूप करने की आवश्यकता है। (बेशक, चूंकि उनमें से लाखों नहीं हैं, आप लूप को 1,000 तक सीमित कर सकते हैं।)
स्केच

8

इस धागे के लिए धन्यवाद दोस्तों! जब मैंने एक्स के फ़ाइल संस्करण का पता लगाना चाहा तो इससे मुझे मदद मिली। हालाँकि, मुझे अंतिम बिट के बारे में जानने की आवश्यकता है जिसे विस्तारित गुण कहा जाता है।

यदि आप Windows Explorer में एक exe (या dll) फ़ाइल के गुण खोलते हैं, तो आपको एक संस्करण टैब, और उस फ़ाइल के विस्तारित गुणों का एक दृश्य मिलता है। मैं उन मूल्यों में से एक का उपयोग करना चाहता था।

इसका हल प्रॉपर्टी इंडेक्सर FolderItem.ExtendedProperty है और यदि आप प्रॉपर्टी के नाम पर सभी स्पेस को छोड़ देते हैं, तो आपको वैल्यू मिल जाएगी। Eg फ़ाइल संस्करण FileVersion जाता है, और वहाँ आपके पास है।

आशा है कि यह किसी और की मदद करता है, बस मैंने सोचा कि मैं इस जानकारी को इस धागे में जोड़ दूंगा। चीयर्स!


2
यह भी सुनिश्चित करता है कि आपका कोड (कम से कम अधिकतर) अभी भी गैर-अंग्रेजी भाषा मशीनों पर काम करेगा।
एड नॉरिस

1
यहां एक छोटा सुधार, FolderItem में ExtendedProperty () नहीं है। FolderItem2 हालांकि करता है।
मिक्सक्सीफाइड

यह उत्तर दूसरों की तुलना में सरल है। मैंने नमूना कोड दिया है जो यहाँ काम करता है: stackoverflow.com/a/46648086/661933
nawfal

8

GetDetailsOf()विधि - किसी फ़ोल्डर में किसी आइटम के बारे में विवरण प्राप्त करता है। उदाहरण के लिए, इसका आकार, प्रकार, या इसके अंतिम संशोधन का समय। फ़ाइल गुण Windows-OSसंस्करण के आधार पर भिन्न हो सकते हैं ।

List<string> arrHeaders = new List<string>();

 Shell shell = new ShellClass();
 Folder rFolder = shell.NameSpace(_rootPath);
 FolderItem rFiles = rFolder.ParseName(filename);

 for (int i = 0; i < short.MaxValue; i++)
 {
      string value = rFolder.GetDetailsOf(rFiles, i).Trim();
      arrHeaders.Add(value);
 }

मैंने ऊपर समान कोड की प्रतिलिपि बनाई और उपयोग की है। लेकिन, मुझे यहां रनटाइम पर COM अपवाद मिल रहा है Folder rFolder = shell.NameSpace(_rootPath);। FYI करें, मैं विंडोज 8 ओएस का उपयोग कर रहा हूं।
डॉनमैक्स

1
वह त्रुटि क्या है? सुनिश्चित करें कि आप Shell32.dll के सही संस्करण का उपयोग कर रहे हैं। यह जाँचें कि शायद यह उपयोगी है
राजेशदेव

1
उपरोक्त लिंक के लिए +1। आपके द्वारा सुझाया गया लिंक ठीक काम कर रहा है। मुझे आपसे एक और मदद चाहिए। यानी, मैं मेटाडेटा प्राप्त करने के लिए एकल फ़ाइल कैसे पास कर सकता हूं ?? चूंकि, यह केवल फ़ोल्डर पास करने को स्वीकार करता है।
डॉनमैक्स

6
  • इस धागे और अन्य जगहों पर कई समाधानों को देखने के बाद निम्नलिखित कोड को एक साथ रखा गया था। यह केवल एक संपत्ति को पढ़ने के लिए है।
  • मुझे कार्य करने के लिए Shell32.FolderItem2.ExtendedProperty फ़ंक्शन नहीं मिल सका, यह एक स्ट्रिंग मान लेने और उस संपत्ति के लिए सही मान और प्रकार लौटाने वाला है ... यह हमेशा मेरे लिए अशक्त था और डेवलपर संदर्भ संसाधन बहुत पतले थे।
  • WindowsApiCodePack जो हमें नीचे दिए गए कोड लाता है माइक्रोसॉफ्ट द्वारा छोड़ दिया गया है लगता है।

उपयोग:

string propertyValue = GetExtendedFileProperty("c:\\temp\\FileNameYouWant.ext","PropertyYouWant");
  1. आपको दी गई फ़ाइल और संपत्ति के नाम के लिए एक स्ट्रिंग के रूप में इच्छित विस्तारित संपत्ति का मूल्य लौटाएगा।
  2. केवल लूप तब तक जब तक कि यह निर्दिष्ट संपत्ति न मिले - तब तक नहीं जब तक कि सभी गुणों को कुछ नमूना कोड की तरह नहीं खोजा जाता
  3. विंडोज संस्करणों पर काम करेगा जैसे विंडोज सर्वर 2008 जहां आपको त्रुटि मिलेगी "टाइप के COM ऑब्जेक्ट को कास्ट करने में असमर्थ 'सिस्टम .__ ComObject' को इंटरफ़ेस टाइप 'Shell32.Shell'" यदि सिर्फ शेल 32 ऑब्जेक्ट को सामान्य रूप से बनाने की कोशिश कर रहा है।

    public static string GetExtendedFileProperty(string filePath, string propertyName)
    {
        string value = string.Empty;
        string baseFolder = Path.GetDirectoryName(filePath);
        string fileName = Path.GetFileName(filePath);
    
        //Method to load and execute the Shell object for Windows server 8 environment otherwise you get "Unable to cast COM object of type 'System.__ComObject' to interface type 'Shell32.Shell'"
        Type shellAppType = Type.GetTypeFromProgID("Shell.Application");
        Object shell = Activator.CreateInstance(shellAppType);
        Shell32.Folder shellFolder = (Shell32.Folder)shellAppType.InvokeMember("NameSpace", System.Reflection.BindingFlags.InvokeMethod, null, shell, new object[] { baseFolder });
    
        //Parsename will find the specific file I'm looking for in the Shell32.Folder object
        Shell32.FolderItem folderitem = shellFolder.ParseName(fileName);
        if (folderitem != null)
        {
            for (int i = 0; i < short.MaxValue; i++)
            {
                //Get the property name for property index i
                string property = shellFolder.GetDetailsOf(null, i);
    
                //Will be empty when all possible properties has been looped through, break out of loop
                if (String.IsNullOrEmpty(property)) break;
    
                //Skip to next property if this is not the specified property
                if (property != propertyName) continue;    
    
                //Read value of property
                value = shellFolder.GetDetailsOf(folderitem, i);
            }
        }
        //returns string.Empty if no value was found for the specified property
        return value;
    }

1
ध्यान दें कि InvokeMember () का उपयोग करने के बजाय , आप shellकिसी भी IShellDispatchइंटरफेस (1-6) को कास्ट कर सकते हैं और सदस्य को सीधे कॉल कर सकते हैं। Shell32.IShellDispatch ishell = (Shell32.IShellDispatch)shell; Shell32.Folder shellFolder = ishell.NameSpace(baseFolder);
21

5

जकर का उत्तर थोड़ा सरल है। यहाँ नमूना कोड है जो एमएस से काम करता है :

var folder = new Shell().NameSpace(folderPath);
foreach (FolderItem2 item in folder.Items())
{
    var company = item.ExtendedProperty("Company");
    var author = item.ExtendedProperty("Author");
    // Etc.
}

उन लोगों के लिए जो शेल 32 को वैधानिक रूप से संदर्भित नहीं कर सकते हैं, आप इसे गतिशील रूप से इस तरह से आमंत्रित कर सकते हैं:

var shellAppType = Type.GetTypeFromProgID("Shell.Application");
dynamic shellApp = Activator.CreateInstance(shellAppType);
var folder = shellApp.NameSpace(folderPath);
foreach (var item in folder.Items())
{
    var company = item.ExtendedProperty("Company");
    var author = item.ExtendedProperty("Author");
    // Etc.
}

1

मुझे यकीन नहीं है कि आप किस प्रकार की फ़ाइलों के लिए गुण लिखने की कोशिश कर रहे हैं, लेकिन टैगलिब-शार्प एक उत्कृष्ट खुला स्रोत टैगिंग लाइब्रेरी है जो इस सभी कार्यक्षमता को अच्छी तरह से लपेटता है। यह अधिकांश लोकप्रिय मीडिया फ़ाइल प्रकारों के समर्थन में बहुत कुछ बनाया गया है, लेकिन आपको बहुत अधिक फ़ाइल के साथ अधिक उन्नत टैगिंग करने की अनुमति देता है।

संपादित करें: मैंने टैगलिब तेज का लिंक अपडेट किया है। पुराना लिंक अब काम नहीं कर रहा है।

EDIT: kzu की टिप्पणी के अनुसार एक बार फिर लिंक को अपडेट करें


यह बहुत दिलचस्प लग रहा है, मैं मुख्य रूप से वीडियो फ़ाइलों (AVI, DIVX आदि) को देख रहा हूं। सूचक के लिए धन्यवाद
डेविड हेस

टैगलिब-शार्प लिंक मृत प्रतीत होता है :-( - जो विकी के रूप में अजीब है ... developer.novell.com/wiki/index.php/TagLib_Sharp:_Examples ... उस URL की ओर
इशारा करता है

धन्यवाद, स्टीव, जिस समय मैंने यह पोस्ट किया था, दोनों लिंक मान्य थे और मुझे यकीन नहीं था कि जो आधिकारिक जगह थी, जाने के लिए ऐसा लगता है कि नॉवेल इस काम के लिए जाने के लिए सही जगह है।
मॉकबॉजेक्ट जूल

हेड अप kzu के लिए धन्यवाद, मैंने अपने मूल उत्तर में लिंक को गितुब स्थान पर भी इंगित किया है।
मॉकबजेक्ट

1

यहां पढ़ने के लिए एक समाधान है - लेखन नहीं - इस पृष्ठ पर मुझे जो कुछ मिला है, उसके आधार पर विस्तारित गुण और शेल 32 ऑब्जेक्ट्स की मदद से

स्पष्ट होने के लिए यह एक हैक है। ऐसा लगता है कि यह कोड अभी भी विंडोज 10 पर चलेगा, लेकिन कुछ खाली गुणों पर हिट करेगा। Windows के पिछले संस्करण का उपयोग करना चाहिए:

        var i = 0;
        while (true)
        {
            ...
            if (String.IsNullOrEmpty(header)) break;
            ...
            i++;

विंडोज 10 पर हम मानते हैं कि लगभग 320 संपत्तियां पढ़ने के लिए हैं और बस खाली प्रविष्टियों को छोड़ दें:

    private Dictionary<string, string> GetExtendedProperties(string filePath)
    {
        var directory = Path.GetDirectoryName(filePath);
        var shell = new Shell32.Shell();
        var shellFolder = shell.NameSpace(directory);
        var fileName = Path.GetFileName(filePath);
        var folderitem = shellFolder.ParseName(fileName);
        var dictionary = new Dictionary<string, string>();
        var i = -1;
        while (++i < 320)
        {
            var header = shellFolder.GetDetailsOf(null, i);
            if (String.IsNullOrEmpty(header)) continue;
            var value = shellFolder.GetDetailsOf(folderitem, i);
            if (!dictionary.ContainsKey(header)) dictionary.Add(header, value);
            Console.WriteLine(header +": " + value);
        }
        Marshal.ReleaseComObject(shell);
        Marshal.ReleaseComObject(shellFolder);
        return dictionary;
    }

जैसा कि उल्लेख किया गया है कि आपको कॉम असेंबली Interop.Shell32 का संदर्भ देना होगा।

यदि आपको एसटीए से संबंधित अपवाद मिलता है, तो आपको इसका समाधान मिलेगा:

फ़ाइल विस्तारित गुण प्राप्त करने के लिए Shell32 का उपयोग करते समय अपवाद

मुझे पता नहीं है कि उन संपत्तियों के नाम एक विदेशी प्रणाली पर क्या होंगे और इस बारे में जानकारी नहीं मिल सकती है कि शब्द का उपयोग करने के लिए किस स्थानीय स्थिरांक का उपयोग करना है। मैंने यह भी पाया कि गुण संवाद से सभी गुण वापस आए शब्दकोश में मौजूद नहीं थे।

BTW यह बहुत धीमा है और - विंडोज 10 पर कम से कम - स्ट्रिंग में प्राप्त तारीखों को पार्स करना एक चुनौती होगी, इसलिए इसका उपयोग करना शुरू करने के लिए एक बुरा विचार प्रतीत होता है।

विंडोज 10 पर आपको Windows.Storage लाइब्रेरी का उपयोग जरूर करना चाहिए जिसमें SystemPhotoProperties, SystemMusicProperties आदि https://docs.microsoft.com/en-us/windows/uwp/files/quickstart-getting-file-properties शामिल हैं।

और अंत में, मैंने एक बहुत बेहतर समाधान पोस्ट किया है जो वहां विंडोजएपिकोडपैक का उपयोग करता है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.