2012-07-25 33 views
5

में संशोधित फ़ाइल का पता लगाएं मैं फ़ोल्डर की निगरानी करने के लिए एक FileSystemWatcher का उपयोग कर रहा हूं। लेकिन जब निर्देशिका में कुछ घटना हो रही है, तो मुझे नहीं पता कि इस फ़ाइल पर किसने प्रभाव डाला है। मैंने EventLog का उपयोग करने की कोशिश की। यह सिर्फ काम नहीं कर सका। क्या ऐसा करने का कोई और तरीका है?उपयोगकर्ता नाम (जिसे) C#

+0

के संभावित डुप्लिकेट (http://stackoverflow.com/questions/8649661/use-the-filesystemwatcher [जो परिवर्तन कर रही है उपयोगकर्ता दस्तावेज़ के लिए FileSystemWatcher वर्ग का उपयोग] -class-to-document-the-user-who-making-making-change) –

उत्तर

7

मुझे याद नहीं कर सकते, जहां मैं इस कोड लेकिन PInvoke जो मुझे लगता है कि इस कार्य के लिए एक सा overkill है का उपयोग कर के लिए अपनी एक विकल्प मिल गया। FileSystemWatcher का प्रयोग करें फ़ोल्डर देखने के लिए और आप काम कर सकते हैं एक गतिविधि सक्रिय जब जो उपयोगकर्ता इस कोड का उपयोग फ़ाइल परिवर्तन किया:

private string GetSpecificFileProperties(string file, params int[] indexes) 
{ 
    string fileName = Path.GetFileName(file); 
    string folderName = Path.GetDirectoryName(file); 
    Shell32.Shell shell = new Shell32.Shell(); 
    Shell32.Folder objFolder; 
    objFolder = shell.NameSpace(folderName); 
    StringBuilder sb = new StringBuilder(); 

    foreach (Shell32.FolderItem2 item in objFolder.Items()) 
    { 
     if (fileName == item.Name) 
     { 
      for (int i = 0; i < indexes.Length; i++) 
      { 
       sb.Append(objFolder.GetDetailsOf(item, indexes[i]) + ","); 
      } 

      break; 
     } 
    } 

    string result = sb.ToString().Trim(); 
    //Protection for no results causing an exception on the `SubString` method 
    if (result.Length == 0) 
    { 
     return string.Empty; 
    } 
    return result.Substring(0, result.Length - 1); 
} 

Shell32 DLL लिए एक संदर्भ है: माइक्रोसॉफ्ट शैल नियंत्रण और स्वचालन - इसकी एक COM संदर्भ

यहां कुछ उदाहरण के कैसे आप विधि कॉल की है:

string Type = GetSpecificFileProperties(filePath, 2); 
string ObjectKind = GetSpecificFileProperties(filePath, 11); 
DateTime CreatedDate = Convert.ToDateTime(GetSpecificFileProperties(filePath, 4)); 
DateTime LastModifiedDate = Convert.ToDateTime(GetSpecificFileProperties(filePath, 3)); 
DateTime LastAccessDate = Convert.ToDateTime(GetSpecificFileProperties(filePath, 5)); 
string LastUser = GetSpecificFileProperties(filePath, 10); 
string ComputerName = GetSpecificFileProperties(filePath, 53); 
string FileSize = GetSpecificFileProperties(filePath, 1); 
+0

जहां तक ​​मुझे पता है कि 'GetDetailsOf' के इंडेक्स 10 को दस्तावेज़ का शीर्षक मिलता है, न कि "अंतिम उपयोगकर्ता"। –

+0

@ जेरेमी थॉम्पसन मैं Shell32.shell का उपयोग कैसे कर सकता हूं? ऐसा लगता है कि यह एक संदर्भ समस्या नहीं है। आयात की बात –

+0

'Shell32.shell' ** माइक्रोसॉफ्ट शैल कंट्रोल और ऑटोमेशन ** के माध्यम से उपलब्ध नहीं है - यह एक COM संदर्भ है। –

4

आपको फ़ाइल सिस्टम पर ऑडिटिंग सक्षम करने की आवश्यकता है (और ऑडिटिंग केवल एनटीएफएस पर उपलब्ध है)। आप समूह नीति या स्थानीय सुरक्षा नीति लागू करके ऐसा करते हैं। आपको उस फ़ाइल पर ऑडिटिंग को भी सक्षम करना होगा जिसे आप मॉनीटर करना चाहते हैं। आप इसे उसी तरह करते हैं जैसे आप फ़ाइल पर अनुमतियों को संशोधित करते हैं।

ऑडिटिंग ईवेंट तब सुरक्षा ईवेंट लॉग में लिखे जाते हैं। आपको अपनी रुचि रखने वाली ऑडिटिंग घटनाओं के लिए इस ईवेंट लॉग की निगरानी करनी होगी। ऐसा करने का एक तरीका एक निर्धारित कार्य बनाना है जो आपके द्वारा रुचि रखने वाली घटनाओं के दौरान एप्लिकेशन प्रारंभ होता है। प्रत्येक घटना के लिए एक नई प्रक्रिया शुरू करना केवल व्यवहार्य है यदि घटनाएं बहुत अधिक दर पर लॉग नहीं होती हैं। अन्यथा आप प्रदर्शन समस्याओं का अनुभव करेंगे।

असल में, आप फ़ाइल की सामग्री या विशेषताओं को देखना नहीं चाहते हैं (जो खोल कार्य GetFileDetails करता है)। साथ ही, आप उस नेटवर्क उपयोगकर्ता को प्राप्त करने के लिए फ़ाइल साझाकरण API का उपयोग नहीं करना चाहते हैं जिसमें फ़ाइल खुलती है (जो NetGetFileInfo करता है)। आप उस प्रक्रिया के उपयोगकर्ता को जानना चाहते हैं जिसने अंतिम बार फ़ाइल को संशोधित किया था। यह जानकारी सामान्य रूप से विंडोज द्वारा दर्ज नहीं की जाती है क्योंकि इसे सभी फाइल गतिविधियों के लिए ऐसा करने के लिए बहुत सारे संसाधनों की आवश्यकता होती है। इसके बजाए आप विशिष्ट फ़ाइलों (और फ़ोल्डरों) पर विशिष्ट कार्यों को करने वाले विशिष्ट उपयोगकर्ताओं के लिए ऑडिटिंग को चुनिंदा रूप से सक्षम कर सकते हैं।

+0

क्या आप लिख रहे हैं ईवेंट लिखना सुरक्षा के लिए स्वयं भी लॉग इन करें? –

+0

@ केविन: जब आप एनटीएफएस पर ऑडिटिंग सक्षम करते हैं तो ऑपरेटिंग सिस्टम सुरक्षा ईवेंट लॉग में ऑडिटिंग ईवेंट लिखेंगे। आपको ऑडिटिंग को सही तरीके से कॉन्फ़िगर करना होगा और फिर उन ऑडिटिंग ईवेंट के लिए सुरक्षा ईवेंट लॉग की निगरानी करनी होगी। –

+0

मैंने सुरक्षा लॉग ब्राउज़ किया था। यहां तक ​​कि फ़ाइल का एक भी निर्माण 10 से अधिक लॉग का कारण बनता है। और सी # में EventLog क्लास उस –

2

ऐसा लगता है कि आपको विंडोज एपीआई फ़ंक्शंस को जो भी आप चाहते हैं उसे प्राप्त करने की आवश्यकता होगी, जिसमें PInvoke शामिल है। किसी अन्य मंच पर कुछ लोग इसे देख रहे हैं और कुछ बाहर निकाले हैं, तो आप उनके solution here देख सकते हैं। हालांकि, ऐसा लगता है कि केवल नेटवर्क शेयरों पर फाइलों के साथ काम करता है (आपकी स्थानीय मशीन पर नहीं)।

भविष्य में संदर्भ के लिए, यह code posted by dave4dl है:

[DllImport("Netapi32.dll", SetLastError = true)] 
static extern int NetApiBufferFree(IntPtr Buffer); 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)] 
struct FILE_INFO_3 
{ 
    public int fi3_id; 
    public int fi3_permission; 
    public int fi3_num_locks; 
    public string fi3_pathname; 
    public string fi3_username; 
} 

[DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
static extern int NetFileEnum(
    string servername, 
    string basepath, 
    string username, 
    int level, 
    ref IntPtr bufptr, 
    int prefmaxlen, 
    out int entriesread, 
    out int totalentries, 
    IntPtr resume_handle 
); 

[DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
static extern int NetFileGetInfo(
    string servername, 
    int fileid, 
    int level, 
    ref IntPtr bufptr 
); 

private int GetFileIdFromPath(string filePath) 
{ 
    const int MAX_PREFERRED_LENGTH = -1; 

    int dwReadEntries; 
    int dwTotalEntries; 
    IntPtr pBuffer = IntPtr.Zero; 
    FILE_INFO_3 pCurrent = new FILE_INFO_3(); 

    int dwStatus = NetFileEnum(null, filePath, null, 3, ref pBuffer, MAX_PREFERRED_LENGTH, out dwReadEntries, out dwTotalEntries, IntPtr.Zero); 

    if (dwStatus == 0) 
    { 
     for (int dwIndex = 0; dwIndex < dwReadEntries; dwIndex++) 
     { 

      IntPtr iPtr = new IntPtr(pBuffer.ToInt32() + (dwIndex * Marshal.SizeOf(pCurrent))); 
      pCurrent = (FILE_INFO_3)Marshal.PtrToStructure(iPtr, typeof(FILE_INFO_3)); 

      int fileId = pCurrent.fi3_id; 

      //because of the path filter in the NetFileEnum function call, the first (and hopefully only) entry should be the correct one 
      NetApiBufferFree(pBuffer); 
      return fileId; 
     } 
    } 

    NetApiBufferFree(pBuffer); 
    return -1; //should probably do something else here like throw an error 
} 


private string GetUsernameHandlingFile(int fileId) 
{ 
    string defaultValue = "[Unknown User]"; 

    if (fileId == -1) 
    { 
     return defaultValue; 
    } 

    IntPtr pBuffer_Info = IntPtr.Zero; 
    int dwStatus_Info = NetFileGetInfo(null, fileId, 3, ref pBuffer_Info); 

    if (dwStatus_Info == 0) 
    { 
     IntPtr iPtr_Info = new IntPtr(pBuffer_Info.ToInt32()); 
     FILE_INFO_3 pCurrent_Info = (FILE_INFO_3)Marshal.PtrToStructure(iPtr_Info, typeof(FILE_INFO_3)); 
     NetApiBufferFree(pBuffer_Info); 
     return pCurrent_Info.fi3_username; 
    } 

    NetApiBufferFree(pBuffer_Info); 
    return defaultValue; //default if not successfull above 
} 

private string GetUsernameHandlingFile(string filePath) 
{ 
    int fileId = GetFileIdFromPath(filePath); 
    return GetUsernameHandlingFile(fileId); 
} 
+0

क्या कोई तरीका है जो स्थानीय मशीन के लिए कर सकता है? –

+0

मुझे नहीं लगता कि यह संभव है। इंटरनेट पर बहुत से लोग पूछते हैं, लेकिन उनमें से कोई भी जवाब नहीं है। – Virtlink

2

यह कई बार चर्चा की गई। मेरा उत्तर एक ही प्रश्न से:

आप फ़ाइलसिस्टम वाटर के साथ यह असंकालिक रूप से ऐसा नहीं कर सकते हैं, हालांकि आप फ़ाइल सिस्टम फ़िल्टर ड्राइवर का उपयोग करके यह सिंक्रनाइज़ कर सकते हैं। चालक आपको ऑपरेशन करने वाले खाते का उपयोगकर्ता नाम प्राप्त करने देता है।

1

निम्नलिखित, आप बना सकते हैं और अद्यतन फ़ाइल कार्रवाई (यह FileSystemWatcher और OpenFiles का संयोजन करने के लिए की तरह है का उपयोगकर्ता नाम निगरानी कर सकते हैं के रूप में उपयोग कोड posted by dave4dl और अद्यतन घोषित struct FILE_INFO_3।फ़ाइल साझा सर्वर के exe के कार्यों)

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
public struct FILE_INFO_3 
{ 
    public int fi3_id; 
    public int fi3_permission; 
    public int fi3_num_locks; 
    [MarshalAs(UnmanagedType.LPWStr)] 
    public string fi3_pathname; 
    [MarshalAs(UnmanagedType.LPWStr)] 
    public string fi3_username; 
}