【发布时间】:2013-10-17 08:34:09
【问题描述】:
我有 .NET 3.5 ClickOnce 应用程序。有一个简单的网格,其中包含存储在服务器上的 Word 文档列表。单击按钮时,应用程序从服务器(通过 WCF)下载选定的文档并将其放入定义的临时文件夹中。之后,使用以下函数计算文档的哈希:
Public Shared Function HashFile(ByVal file As String) As String
Using reader As New System.IO.FileStream(file, IO.FileMode.Open, IO.FileAccess.Read)
Using provider As New System.Security.Cryptography.MD5CryptoServiceProvider
Dim hash() As Byte = provider.ComputeHash(reader)
Dim sb As New System.Text.StringBuilder(hash.Length * 2)
For i As Integer = 0 To hash.Length - 1
sb.Append(hash(i).ToString("X2"))
Next
Return sb.ToString().ToLower
End Using
End Using
End Function
然后打开 Word 文档:
Private Shared Function OpenDocument(ByVal path As String) As Boolean
Try
Dim process As New Process
process.StartInfo.FileName = path
process.StartInfo.UseShellExecute = True
process.StartInfo.ErrorDialog = True
process.Start()
Return True
Catch ex As Exception
Return False
End Try
End Function
应用程序中有所有打开的文档的列表。打开文档后,有关它的信息将立即添加到此列表中。到目前为止,非常简单。应用程序中有一个计时器,每 1000 毫秒计时一次,并检查是否已经关闭了任何打开的文档。由于没有简单的方法可以从 Word 中获取此类信息,因此使用了以下技巧:
Public Shared Function IsLockedFile(ByVal path As String) As Boolean
Dim isLocked As Boolean = True
Try
Using fs As FileStream = File.Open(path, FileMode.Open, FileAccess.Write)
isLocked = False
End Using
Catch ex As Exception
End Try
Return isLocked
End Function
如果应用程序成功打开具有写访问权限的文件,则意味着该文档已关闭(不再被 Word 锁定)。之后,使用与上述相同的函数再次计算文件的 MD5 哈希值。如果旧哈希值等于新哈希值,则表示用户没有对文档进行任何更改。如果哈希值不同,则将文档上传到服务器。这是对整个过程的简化描述。
它工作得很好。但是,客户报告有时会丢失对文档的更改。久而久之,终于找到了原因。当应用程序计算(关闭的)文档的哈希值时,它有时会返回旧的哈希值。就像它仍在读取文件的旧版本一样。错误的发生是非常不确定的。大多数情况下它工作正常。例如 50 次我得到正确(不同的)哈希,但连续 3 次错误(旧)一个。
我无法在我的开发环境(VMware 中虚拟化的 Windows Server 2008)中模拟该错误,只能在主机中(Windows 7 64 位,防病毒关闭)。
我什至尝试在重新计算哈希之前延迟一些时间,以确保刷新所有磁盘操作。但即使在 2 秒后我仍然错了,老哈希。也许还不够,但我应该等多久?
根据我的谷歌搜索,只有刷新 .NET 应用程序执行的 IO 操作的可能性,而不是在它之外。读取哈希时的读/写独占打开也无济于事。任何想法如何解决这个问题或其他可能导致它的原因?
谢谢。
【问题讨论】:
-
对不起.. 我不认为你会得到很多答案。 SO 是精打细算的,因此提出这样的难题需要人们付出太多努力才能尝试和帮助。我尝试了一些,最后不得不自己回答。
-
正在尝试重新创建WebDAV?
-
Mithlon 非常适合点磨。通常有帮助的一件事是,如果您获得足够的声望,您可以设置赏金(牺牲自己的代表作为赏金),这会引起关注。
-
我根本不买“旧文件内容”的解释。用户用另一个名称保存文档太简单了。在 Word 中很容易做到,您永远不会看到它,并且用户不知道为什么该更改没有被采纳。