以编程方式获取lockingExcel工作簿的用户

我正在使用C#framework 4.5,netoffice 1.6和sharpdevelop 4.4.1来从Outlook中操作位于networking共享上的Excel工作簿。

在某些时候,我需要将工作簿对象(ewb)的文件访问权限更改为readwrite,如下所示:

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

在更改文件访问权限之前,我检查文件是否在服务器上被locking。 如果文件被locking,我会通知用户稍后重试该操作。

现在,我想包含在通知中lockingExcel文件的用户名。 我搜查了msdn,netoffice论坛,等等,并没有find解决scheme。 我知道,如果你打开excel文件readwrite,它会把用户名存储在xlsx文件中。 我如何通过c#访问特定的信息?

编辑:我结束了这样做:

 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和excel 2007+文件格式(.xls和.xlsx)。 对于.xls,我必须查看.xls文件本身。 对于.xlsx,locking用户存储在〜$ temp文件中。 我知道,.xls文件是脏代码,但我不知道如何构build.xls文件格式。 因此,我只读了一堆包含ascii用户名的字节,然后用正则expression式来提取用户名。

它会将用户名存储在xlsx文件中

不,不在.xlsx文件中。 Excel创build另一个文件来存储用户名称。 它有隐藏的文件属性打开,所以你不能正常使用资源pipe理器看到它。

它通常与原始文件具有相同的名称,但以~$前缀。 因此,对于名为test.xlsx的文件,您将得到一个名为~$test.xlsx的文件。 它是一个二进制文件,包含用缺省代码页和utf-16编码的用户名。 hex转储显示它看起来像:

 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 ans 0000000040: 00 20 00 50 00 61 00 73 │ 00 73 00 61 00 6E 00 74 P assant 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字是string长度(不是字节),接着是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(); } } 

但是不一定是最正确的方法,如果8位编码在您的语言环境中无法正常工作,您可能需要改进代码并尝试查找utf-16string(而不是ReadString)。 寻求()首先抵消0x37。 一定要正确使用该方法,它有一个隐式的竞争条件,所以确保你只在操作失败使用它并期望一个空string返回。 我无法保证此方法在所有Excel版本上都能正常工作,包括未来的版本,我只在工作站级机器上testingOffice 2013。

你有哪个部分有问题?

不知道什么关于xslx,我只能猜测:你想打开文件,并指定FileAccess.Read&FileShare.ReadWrite如下: 如何读取在C#打开excel文件之后,您使用某种库将XSLX转换为DataTable,并提取你需要的特定行。