كيف يمكنني معرفة أن الدليل هو سلة إعادة التدوير في C#؟

StackOverflow https://stackoverflow.com/questions/1585295

  •  22-09-2019
  •  | 
  •  

سؤال

بالنظر إلى مجلد ، كيف يمكنني معرفة أنه صندوق إعادة التدوير؟ لقد وجدت إجابه لـ C ++ ولكن ليس لـ C#.

كانت فكرتي الأولى هي التحقق من fileattributes.system (والتي ستكون تقريب مقبول في حالتي) ولكن في الواقع يتم مسح العلم في مجلد إعادة التدوير.

الحلول الخام التي تستخدم أسماء المجلدات المتشددين غير واردة (نحن في عام 2009 بعد كل شيء).

هل كانت مفيدة؟

المحلول

هناك مشكلة صغيرة هنا. صندوق إعادة تدوير Windows هو مجلد افتراضي ولا يوجد بالفعل. الملفات التي تراها ليست في الواقع في هذا المجلد ، فهي تمثل الملفات الموجودة على القرص التي تمت إعادة تسميتها باسم اسم خاص ، والتي "تزيل" من نظام الملفات المرئية ، ولكن ليس المادية.

يمكنك "إثبات" هذا بنفسك عن طريق طلب موقع المجلد باستخدام API Win32. سوف يعود E_FAIL للاطلاع على سلة إعادة التدوير ، ولكن ليس للمجلدات الأخرى (انظر shgetminayfolderpath على pinvoke.net (وعلى MSDN) لجميع الثوابت التي يمكنك استخدامها والإعلانات اللازمة لتشغيل هذا الرمز):

IntPtr ptrRecycleBinPath;
// try it with KnownFolder.QuickLaunch to see it working:
HRESULT hr = (HRESULT) SHGetKnownFolderPath(
     KnownFolder.RecycleBinFolder, 
     0, 
     IntPtr.Zero, 
     out ptrRecycleBinPath);

if (hr == HRESULT.E_FAIL)
{
    Console.WriteLine("No folder avaialable, virtual folder");
}
else if (hr == HRESULT.S_OK)
{
    string RecycleBinPath = Marshal.PtrToStringUni(ptrRecycleBinPath);
    Marshal.FreeCoTaskMem(ptrRecycleBinPath);
    Console.WriteLine("path: " + RecycleBinPath);
}

// for convenience, you can use the code above
// directly if you paste the follow declarations in your class:

// get a "known path"
[DllImport("shell32.dll")]
static extern long SHGetKnownFolderPath(
    [MarshalAs(UnmanagedType.LPStruct)] Guid rfid, 
    uint dwFlags, 
    IntPtr hToken, 
    out IntPtr pszPath);

// known folder GUID declarations
public static class KnownFolder
{
    // many more entries exist, left out for clarity here

    public static readonly Guid RecycleBinFolder = 
         new Guid("B7534046-3ECB-4C18-BE4E-64CD4CB7D6AC");

    public static readonly Guid QuickLaunch = 
         new Guid("52a4f021-7b75-48a9-9f6b-4b87a210bc8f");

    //....
}

// results of COM invocations:
enum HRESULT : uint
{
    S_FALSE = 0x0001,
    S_OK = 0x0000,
    E_FAIL = 0x80004005,
    E_INVALIDARG = 0x80070057,
    E_OUTOFMEMORY = 0x8007000E
}

المجلد المزيف "$ recycle.bin" يتكرر لكل محرك. لا يتم تخزين الاسم المخفي في السجل ولا يمكن الوصول إليه بواسطة API على هذا النحو. لن يسترجع معروفة معروفة في وقت سابق هذه المعلومات إما (نفس LIB لديه طريقة تسمي للحصول على سلة إعادة التدوير ، كما أن لديها ملف GetPath, ، سوف تظهر فارغة).

ولكن لم نفقد كل شيء. يحتوي "اسم الملف" غير الموجود غير الموجود أو "اسم المجلد" على ملف مخفي يشبه شيئًا "S-1-5-21-2703390745-3900912742-210389625-1000" (سيكون لك مختلفًا). إنها واحدة من طريقتتين "موثوقتين" لمعرفة ما إذا كان اسم ملف معين هو في الواقع دليل افتراضي لعلامة إعادة التدوير (الطريقة الأخرى هي: حذف ملف من خلال SHFileOperation, أوضح هنا, وتحقق مما إذا كان يظهر في المجلد لديك):

string [] entries = Directory.GetFileSystemEntries(@"c:\$Recycle.bin", "?-?-?-??*");
if(entries.Length > 0)
   // we have a winner
else 
   // no, not the recycle bin

ملاحظة: لا أعرف ما هي المجلدات المخفية على إصدارات Win32 الأخرى ، يجب عليك تجربة بعض الشيء. لديهم جميعا النظام ومجموعة العلم المخفي ويبدو وكأنه guid mangled.

مستندات API ليست واضحة جدًا حول هذا الموضوع ، ولكن إذا كنت بحاجة إلى تأكيد ، تشرح هذه الصفحة أنه لا يوجد بالفعل مسار يمكن استرداده ( صفحة CSIDL ذات الصلة الأقدم أقل وضوحا عليه).

تحديث: مقاربات بديلة مع SHGetSpecialFolderPath, SHGetSpecialFolderLocation, ShellAPI.SHGetFolderLocation و SHGetPathFromIDList كل شيء يفشل مع نفسه: إما نتيجة فارغة أو خطأ. لقد اختبرت جميع الوظائف على حد سواء من أجل إعادة التدوير و AppData (للتأكد من أنني استخدمت المعلمات الصحيحة).

فقط الوثائق على ShGetPathFromIDListEx قال ذلك بشكل صريح ، اقتبس: "باستثناء أسماء طابعة UNC ، إذا كان الموقع المحدد بواسطة معلمة PIDL ليس جزءًا من نظام الملفات ، فإن هذه الوظيفة تفشل.".

نصائح أخرى

Microsoft حزمة رمز Windows API يحتوي على هذه الوظيفة.

للحصول على مجلد سلة إعادة التدوير ، استخدم

Microsoft.WindowsAPICodePack.Shell.KnownFolderHelper.FromPath("::{645FF040-5081-101B-9F08-00AA002F954E}");

ليس لدي أي فكرة عما تعنيه هذه السلسلة ، ولكن تم تضمينه في المستندات كمرجع إلى سلة إعادة التدوير.

أتمنى أن يساعدك هذا :)

تمت كتابة معظم الأساليب المتعلقة ببابة إعادة التدوير في C ++ كما ذكرت. يمكنك إنشاء فئة غلاف في التطبيق الخاص بك باستخدام الإضافات المدارة إلى C ++, ، ثم يجب عليك استخدام dllimport مثل هذا:

using System;
using System.Runtime.InteropServices;

class MainApp
{
[DllImport("user32.dll", EntryPoint="MessageBox")]
public static extern int MessageBox(int hWnd, String strMessage, String
strCaption, uint uiType);

public static void Main()
{
MessageBox( 0, "Hello, this is PInvoke in operation!", ".NET", 0 );
}
}

هناك أيضًا مقالات تفعل ذلك بطريقة أخرى مع C#، معظمها يستخدم Pinvoke أو يعتمد على المجلد الذي يحمل إعادة تدوير $ باسمه. فيما يلي بعض الروابط التي وجدتها لهذا الموضوع

http://social.msdn.microsoft.com/forums/en/csharpgeneral/thread/05f1476f-a101-4766-847b-0bdf4f6ad397

http://www.codeproject.com/kb/shell/recyclebin.aspx

http://www.pinvoke.net/default.aspx/shell32.shfileOperation

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top