2014-09-26 4 views
5

मैं Outlook के भीतर से नेटवर्क शेयर पर स्थित एक्सेल वर्कबुक में हेरफेर करने के लिए सी # फ्रेमवर्क 4.5, नेटऑफिस 1.6 और तेज विकास 4.4.1 का उपयोग कर रहा हूं।प्रोग्रामेटिक रूप से उपयोगकर्ता को एक्सेल वर्कबुक लॉक कर रहा है

कुछ बिंदु मैं बहुत तरह ReadWrite को कार्यपुस्तिका वस्तु (EWB) की फ़ाइल का उपयोग बदलने की जरूरत पर:

ewb.ChangeFileAccess(Excel.Enums.XlFileAccess.xlReadWrite, System.Reflection.Missing.Value, true); 

इससे पहले कि मैं फ़ाइल का उपयोग बदलने के लिए, मैं अगर फ़ाइल सर्वर पर लॉक किया गया है की जाँच । अगर फ़ाइल लॉक है, तो मैं उपयोगकर्ता को बाद के बिंदु पर कार्रवाई को पुनः प्रयास करने के लिए सूचित करूंगा।

अब, मैं उस उपयोगकर्ता नाम को शामिल करना चाहता हूं जो अधिसूचना में एक्सेल फ़ाइल लॉक कर रहा है। मैंने एमएसडीएन, नेटऑफिस फोरम, इत्यादि की खोज की है ... और मुझे कोई समाधान नहीं मिला है। मुझे पता है कि, यदि आप एक्सेल फ़ाइल रीडराइट खोलते हैं, तो यह उपयोगकर्ता का नाम xlsx फ़ाइल में संग्रहीत करेगा। मैं सी # के माध्यम से जानकारी के उस विशेष टुकड़े तक कैसे पहुंच सकता हूं?

संपादित करें: मैं यह कर समाप्त हो गया:

public string GetExcelFileOwner(string path, NetOffice.ExcelApi.Enums.XlFileFormat ffmt) { 
     string tempmark = "~$"; 
     if(ffmt==NetOffice.ExcelApi.Enums.XlFileFormat.xlExcel8) { 
      tempmark = ""; 
     } 
     string uspath = Path.Combine(Path.GetDirectoryName(path), tempmark + Path.GetFileName(path)); 
     if (!File.Exists(uspath)) return ""; 
     var sharing = FileShare.ReadWrite | FileShare.Delete; 
     using (var fs = new FileStream(uspath, FileMode.Open, FileAccess.Read, sharing)) 
     using (var br = new BinaryReader(fs, Encoding.Default)) { 
      if(ffmt==NetOffice.ExcelApi.Enums.XlFileFormat.xlExcel8) { 
       byte[] ByteBuffer = new byte[500]; 
       br.BaseStream.Seek(150, SeekOrigin.Begin); 
       br.Read(ByteBuffer, 0, 500); 
       return matchRegex(System.Text.Encoding.UTF8.GetString(ByteBuffer), @"(?=\w\w\w)([\w, ]+)").Trim(); 
      } 
      else { 
       return br.ReadString(); 
      } 
     } 
    } 

    private static string matchRegex(string txt, string rgx) { 
     Regex r; 
     Match m; 
     try { 
      r = new Regex(rgx, RegexOptions.IgnoreCase); 
      m = r.Match(txt); 
      if (m.Success) { 
       return m.Groups[1].Value.ToString(); 
      } 
      else { 
       return ""; 
      } 
     } 
     catch { 
      return ""; 
     } 
    } 

हम Excel 2003 का उपयोग कर रहे हैं और 2007+ फ़ाइल स्वरूप Excel (.xls और .xlsx)। .xls के लिए मुझे .xls फ़ाइल में ही देखना था। .xlsx के लिए, लॉकिंग उपयोगकर्ता ~ $ temp फ़ाइल में संग्रहीत है। मुझे पता है, .xls फ़ाइल के लिए, यह गंदा कोड है, लेकिन मुझे कोई संकेत नहीं है कि .xls फ़ाइल प्रारूप कैसे संरचित है। इसलिए, मैंने बस बाइट्स का एक गुच्छा पढ़ा है जिसमें एएससीआई उपयोगकर्ता नाम शामिल है और उस उपयोगकर्ता नाम को निकालने के लिए एक रेगेक्स करें।

+0

क्या आपने Win32_ConnectionShare और WMIC को देखने का प्रयास किया है? –

उत्तर

8

यह .xlsx फ़ाइल में नहीं, xlsx फ़ाइल

नहीं में उपयोगकर्ता का नाम संग्रहीत करेगा। एक्सेल उपयोगकर्ता नाम को स्टोर करने के लिए अन्य फ़ाइल बनाता है। इसमें छिपी हुई फ़ाइल विशेषता चालू है ताकि आप इसे सामान्य रूप से एक्सप्लोरर के साथ नहीं देख सकें।

यह सामान्य रूप से मूल फ़ाइल के समान नाम है, लेकिन ~$ के साथ उपसर्ग किया गया है। तो test.xlsx नाम की एक फ़ाइल के लिए आपको ~$test.xlsx नाम की एक फ़ाइल मिलेगी। यह एक बाइनरी फ़ाइल है और इसमें डिफ़ॉल्ट कोड पृष्ठ और यूटीएफ -16 में एन्कोड किए गए उपयोगकर्ता नाम शामिल हैं।

0000000000: 0C 48 61 6E 73 20 50 61 │ 73 73 61 6E 74 20 20 20 ♀Hans Passant 
0000000010: 20 20 20 20 20 20 20 20 │ 20 20 20 20 20 20 20 20 
0000000020: 20 20 20 20 20 20 20 20 │ 20 20 20 20 20 20 20 20 
0000000030: 20 20 20 20 20 20 20 0C │ 00 48 00 61 00 6E 00 73   ♀ H a n s 
0000000040: 00 20 00 50 00 61 00 73 │ 00 73 00 61 00 6E 00 74  P a s s a n t 
0000000050: 00 20 00 20 00 20 00 20 │ 00 20 00 20 00 20 00 20 
0000000060: 00 20 00 20 00 20 00 20 │ 00 20 00 20 00 20 00 20 
0000000070: 00 20 00 20 00 20 00 20 │ 00 20 00 20 00 20 00 20 
0000000080: 00 20 00 20 00 20 00 20 │ 00 20 00 20 00 20 00 20 
0000000090: 00 20 00 20 00 20 00 20 │ 00 20 00 20 00 20 00 20 
00000000A0: 00 20 00 20 00   │ 

फ़ाइल में अनोखा 0x0C शब्द वर्ण (नहीं बाइट्स) में स्ट्रिंग की लंबाई, उपयोगकर्ता नाम, रिक्तियों के साथ गद्देदार स्टोर करने के लिए 54 पात्रों द्वारा पीछा किया है: एक हेक्स डंप यह क्या लगता है कि दिखाने के लिए। यह BinaryReader.ReadString() के साथ है पढ़ने के लिए सबसे आसान तरीका है:

public static string GetExcelFileOwner(string path) { 
    string uspath = Path.Combine(Path.GetDirectoryName(path), "~$" + Path.GetFileName(path)); 
    if (!File.Exists(uspath)) return ""; 
    var sharing = FileShare.ReadWrite | FileShare.Delete; 
    using (var fs = new FileStream(uspath, FileMode.Open, FileAccess.Read, sharing)) 
    using (var br = new BinaryReader(fs, Encoding.Default)) { 
     return br.ReadString(); 
    } 
} 

लेकिन जरूरी नहीं कि सबसे सही तरीका है, तो आप कोड में सुधार और UTF-16 स्ट्रिंग (नहीं ReadString के साथ) यदि पता लगाने के लिए प्रयास करने के लिए चाहते हो सकता है 8-बिट एन्कोडिंग आपके लोकेल में अच्छी तरह से काम नहीं करते हैं। पहले 0x37 ऑफसेट करने के लिए() खोजें। विधि का सही ढंग से उपयोग करना सुनिश्चित करें, इसमें एक निहित दौड़ की स्थिति है, इसलिए सुनिश्चित करें कि आप इसे का उपयोग के बाद ऑपरेशन विफल हो गए हैं और वैसे भी एक खाली स्ट्रिंग वापसी की उम्मीद है।मैं गारंटी नहीं दे सकता कि यह विधि भविष्य में सभी एक्सेल संस्करणों पर सही ढंग से काम करेगी, मैंने केवल वर्कस्टेशन क्लास मशीन पर Office 2013 के लिए परीक्षण किया था।

+0

हाय हंस। यह केवल स्थानीय फाइलों के लिए काम करता है, नेटवर्क पर स्थित एक्सेल फाइलों के लिए नहीं। जब मैं अपनी हार्ड ड्राइव पर एक्सेल फ़ाइल खोलता हूं और संशोधित करता हूं तो मुझे ~ $ फ़ाइल दिखाई देती है। नेटवर्क से खुलते समय मुझे फ़ाइल नहीं दिखाई देती है। मैंने xlsx फ़ाइल की जांच की जब मैंने इसे नेटवर्क पर पढ़ा/लिख दिया। उपयोगकर्ता का नाम जो इसे खोला गया है xlsx में संग्रहीत है। तो मुझे अभी भी लगता है कि मुझे xlsx फ़ाइल से सेटिंग पढ़नी चाहिए। – nire

+0

हम्म, नहीं, बहुत संदिग्ध यह उपयोगकर्ता नाम लिखने के लिए एक .xlsx फ़ाइल को संशोधित करने जा रहा है। एकमात्र झुर्रियां मैं सोच सकता हूं कि उपयोगकर्ता के पास साझा फ़ोल्डर में लेखन पहुंच नहीं है। लेकिन चलिए इस पर अनुमान नहीं लगाते हैं, यह देखने के लिए SysInternals 'प्रक्रिया मॉनीटर का उपयोग करें, आप फ़ाइल के साथ Excel.exe tinkering देखेंगे। –

+0

हंस, आप सही हैं। Procmon दिखा रहा है Excel.exe परिणाम सफलता के साथ ~ $ ...... xlsx तक पहुंच रहा है। ओह मैन, और अब मैं सर्वर पर ~ $ .... xlsx फ़ाइल देखता हूं। मैंने एक xls फ़ाइल भी कोशिश की, जिसके लिए ~ $ फ़ाइल नहीं बनाई गई है। उपयोगकर्ता का नाम वास्तविक .xls में संग्रहीत है। मैं आपका कोड आज़माउंगा और रिपोर्ट करूंगा। – nire

0

आपको किस हिस्से में समस्या है?

xslx बारे में कुछ भी जानने के बिना, मैं केवल अनुमान लगा सकते हैं कि: आप फ़ाइल को खोलने और यहाँ के रूप में FileAccess.Read & FileShare.ReadWrite निर्दिष्ट करना चाहते हैं: How to read open excel file at C# उसके बाद, आप DataTable में XSLX चालू करने के लिए पुस्तकालय किसी तरह का उपयोग करें, और आपको जिस विशिष्ट पंक्ति की आवश्यकता है उसे निकालें।

+0

मैं कार्यालय फाइलों और अनुप्रयोगों में हेरफेर करने के लिए netoffice .NET Wrapper Assemblies का उपयोग कर रहा हूं। समस्या यह है कि मेरे पास उपयोगकर्ता के उपयोगकर्ता नाम निकालने का कोई तरीका नहीं है (बी) एक्सेल फ़ाइल लॉक करना। – nire

+0

ठीक है, ऐसा लगता है कि आपको यह जानने की ज़रूरत है कि किसने विशिष्ट फ़ाइल खोला है और उस फ़ाइल में फ्लैग है। PSFile उपयोगिता इसे कमांड लाइन के माध्यम से कर सकती है। "psfile \\ yourremoteshare सी: \ test.xlsx"। यदि आप रुचि रखते हैं कि इसे प्रोग्रामेटिक तरीके से कैसे करें, तो आप एपीमिनेटर डाउनलोड कर सकते हैं और देख सकते हैं कि psfile कैसे करता है। मुझे व्यक्तिगत रूप से संदेह है कि आप "xlsx फ़ाइल में उपयोगकर्ता नाम" तक पहुंच सकते हैं, जो मुझे आंतरिक चीज की तरह लगता है। –

+0

हालांकि मेरे सुझाए गए समाधान के लिए व्यवस्थापकीय अधिकारों की आवश्यकता है, जो संख्या-नहीं है। आप एपीआई मॉनीटर का उपयोग यह जांचने के लिए कर सकते हैं कि Excel को दूरस्थ फ़ाइल से उपयोगकर्ता नाम कैसे प्राप्त होता है। (जैसे कि एपीआई कॉल करता है, और यह आंतरिक है) –

संबंधित मुद्दे