ฉันกำลังพยายามหาวิธีอ่าน / เขียนไปยังคุณสมบัติไฟล์เพิ่มเติมใน C # เช่น Comment, Bit Rate, Date Accessed, Category ฯลฯ ที่คุณเห็นใน Windows explorer มีความคิดอย่างไรในการทำสิ่งนี้? แก้ไข: ฉันจะอ่าน / เขียนไฟล์วิดีโอเป็นหลัก (AVI / DIVX / ... )
ฉันกำลังพยายามหาวิธีอ่าน / เขียนไปยังคุณสมบัติไฟล์เพิ่มเติมใน C # เช่น Comment, Bit Rate, Date Accessed, Category ฯลฯ ที่คุณเห็นใน Windows explorer มีความคิดอย่างไรในการทำสิ่งนี้? แก้ไข: ฉันจะอ่าน / เขียนไฟล์วิดีโอเป็นหลัก (AVI / DIVX / ... )
คำตอบ:
สำหรับผู้ที่ไม่คลั่งไคล้ VB นี่คือ c #:
หมายเหตุคุณต้องเพิ่มการอ้างอิงไปยังMicrosoft Shell Controls and Automationจากแท็บ COM ของกล่องโต้ตอบการอ้างอิง
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)}");
}
}
}
มีบทความ CodeProjectสำหรับผู้อ่าน ID3 และเธรดที่ kixtart.orgที่มีข้อมูลเพิ่มเติมสำหรับคุณสมบัติอื่น ๆ โดยทั่วไปคุณต้องเรียกใช้GetDetailsOf()
เมธอดบนโฟลเดอร์เชลล์วัตถุสำหรับshell32.dll
.
เพิ่มแพ็คเกจ NuGet ต่อไปนี้ในโครงการของคุณ:
Microsoft.WindowsAPICodePack-Shell
โดย MicrosoftMicrosoft.WindowsAPICodePack-Core
โดย Microsoftusing 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();
สำคัญ:
ไฟล์ต้องเป็นไฟล์ที่ถูกต้องซึ่งสร้างขึ้นโดยซอฟต์แวร์ที่กำหนดให้โดยเฉพาะ ไฟล์ทุกประเภทมีคุณสมบัติของไฟล์แบบขยายเฉพาะและไม่สามารถเขียนได้ทั้งหมด
หากคุณคลิกขวาที่ไฟล์บนเดสก์ท็อปและไม่สามารถแก้ไขคุณสมบัติคุณจะไม่สามารถแก้ไขในโค้ดได้เช่นกัน
ตัวอย่าง:
Author
หรือTitle
คุณสมบัติดังนั้นอย่าลืมใช้บางส่วน try
catch
หัวข้อเพิ่มเติม: MSDN: การใช้ตัวจัดการทรัพย์สิน
ตัวอย่างนี้ใน 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
คุณต้องเพิ่มการอ้างอิงไปยังMicrosoft Shell Controls and Automationจากแท็บCOMของกล่องโต้ตอบการอ้างอิง
ขอบคุณสำหรับกระทู้นี้! มันช่วยฉันเมื่อฉันต้องการหาเวอร์ชันไฟล์ของ exe อย่างไรก็ตามฉันต้องการหาบิตสุดท้ายของสิ่งที่เรียกว่า Extended Properties
หากคุณเปิดคุณสมบัติของไฟล์ exe (หรือ dll) ใน Windows Explorer คุณจะได้รับแท็บเวอร์ชันและมุมมองของ Extended Properties ของไฟล์นั้น ฉันต้องการเข้าถึงหนึ่งในค่าเหล่านั้น
วิธีแก้ปัญหานี้คือตัวทำดัชนีคุณสมบัติ FolderItem.ExtendedProperty และหากคุณวางช่องว่างทั้งหมดในชื่อคุณสมบัติคุณจะได้รับค่า เช่น File Version ไปที่ FileVersion และคุณก็มี
หวังว่านี่จะช่วยคนอื่นคิดว่าฉันจะเพิ่มข้อมูลนี้ในชุดข้อความนี้ ไชโย!
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);
}
Folder rFolder = shell.NameSpace(_rootPath);
ที่นี่ FYI ฉันใช้ Windows 8 OS
ใช้:
string propertyValue = GetExtendedFileProperty("c:\\temp\\FileNameYouWant.ext","PropertyYouWant");
จะทำงานบน Windows เวอร์ชันเช่น Windows Server 2008 ซึ่งคุณจะได้รับข้อผิดพลาด"Unable to cast COM object of type 'System .__ ComObject' to interface type 'Shell32.Shell'"หากเพียงแค่พยายามสร้าง Shell32 Object ตามปกติ
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;
}
shell
ไปยังIShellDispatch
อินเทอร์เฟซใดก็ได้(1-6) และโทรหาสมาชิกโดยตรง Shell32.IShellDispatch ishell = (Shell32.IShellDispatch)shell; Shell32.Folder shellFolder = ishell.NameSpace(baseFolder);
คำตอบของ Jerkerนั้นง่ายกว่าเล็กน้อย นี่คือโค้ดตัวอย่างที่ทำงานจาก MS :
var folder = new Shell().NameSpace(folderPath);
foreach (FolderItem2 item in folder.Items())
{
var company = item.ExtendedProperty("Company");
var author = item.ExtendedProperty("Author");
// Etc.
}
สำหรับผู้ที่ไม่สามารถอ้างอิง shell32 แบบคงที่คุณสามารถเรียกใช้แบบไดนามิกดังนี้:
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.
}
ฉันไม่แน่ใจว่าไฟล์ประเภทใดที่คุณพยายามเขียนคุณสมบัติ แต่taglib-sharpเป็นไลบรารีการติดแท็กโอเพ่นซอร์สที่ยอดเยี่ยมซึ่งรวมฟังก์ชันทั้งหมดนี้ไว้อย่างดี มีการสนับสนุนในตัวสำหรับประเภทไฟล์สื่อยอดนิยมส่วนใหญ่ แต่ยังช่วยให้คุณสามารถทำการแท็กขั้นสูงกับไฟล์ใดก็ได้
แก้ไข: ฉันได้อัปเดตลิงก์ไปยัง taglib sharp แล้ว ลิงก์เก่าใช้งานไม่ได้อีกต่อไป
แก้ไข:อัปเดตลิงก์อีกครั้งตามความคิดเห็นของ kzu
นี่คือวิธีแก้ปัญหาสำหรับการอ่าน - ไม่เขียน - คุณสมบัติเพิ่มเติมตามสิ่งที่ฉันพบในหน้านี้และด้วยความช่วยเหลือเกี่ยวกับวัตถุ shell32วัตถุ
เพื่อให้ชัดเจนว่านี่คือการแฮ็ก ดูเหมือนว่าโค้ดนี้จะยังคงทำงานบน Windows 10 แต่จะโดนคุณสมบัติบางอย่างที่ว่างเปล่า Windows เวอร์ชันก่อนหน้าควรใช้:
var i = 0;
while (true)
{
...
if (String.IsNullOrEmpty(header)) break;
...
i++;
ใน Windows 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;
}
ดังที่ได้กล่าวไว้คุณจำเป็นต้องอ้างอิง Com assembly Interop.Shell32
หากคุณได้รับข้อยกเว้นที่เกี่ยวข้องกับ STA คุณจะพบวิธีแก้ไขที่นี่:
ข้อยกเว้นเมื่อใช้ Shell32 เพื่อรับคุณสมบัติการขยายไฟล์
ฉันไม่รู้ว่าชื่อคุณสมบัติเหล่านั้นจะเป็นอย่างไรในระบบต่างประเทศและไม่พบข้อมูลเกี่ยวกับค่าคงที่ที่แปลได้ว่าจะใช้เพื่อเข้าถึงพจนานุกรม ฉันยังพบว่าคุณสมบัติบางอย่างจากกล่องโต้ตอบคุณสมบัติไม่ปรากฏในพจนานุกรมที่ส่งคืน
BTW สิ่งนี้ช้ามากและอย่างน้อยใน Windows 10 การแยกวิเคราะห์วันที่ในสตริงที่ดึงมาจะเป็นเรื่องที่ท้าทายดังนั้นการใช้สิ่งนี้ดูเหมือนจะเป็นความคิดที่ไม่ดีในการเริ่มต้น
ใน Windows 10 คุณควรใช้ไลบรารี Windows.Storage ซึ่งมี SystemPhotoProperties, SystemMusicProperties เป็นต้น https://docs.microsoft.com/en-us/windows/uwp/files/quickstart-getting-file-properties
และในที่สุดฉันก็โพสต์วิธีแก้ปัญหาที่ดีกว่ามากซึ่งใช้ WindowsAPICodePack ที่นั่น