SQL Server 2005 データベースを使用して、VB.net 4.0 で記述された従来の Windows デスクトップ アプリケーションを使用しています。アプリケーションは、データベースに保存されている Word テンプレートに基づいてレポートを生成します。レポートのテキストに変更があった場合に備えて、新しい Word レポート テンプレート (.docx) をデータベースにロードできる管理セクションがあります。管理フォームでは、新しいファイルを追加したり、既存のファイルを削除または更新したりできます。新しいファイルを追加するとき、それが格納されているデータベース ルックアップ テーブル内のファイルの主キーとして使用されるコード (テキスト) を要求します。また、データベースからファイルを選択して開くこともできるので、見た。
次の動作は一貫して再現できます。 新しいコード (主キー) を使用して新しい .docx ファイルを追加できます。そのファイルは正常に開くことができます。既存のファイルが新しい .docx で更新された場合、開こうとすると、Word で「ファイルを開くときにエラーが発生しました」というエラー メッセージが表示されて失敗します。そのファイルのレコードが削除され、同じファイルが新しいコード (PK) で追加された場合、正常に開くことができます。削除されたファイルと同じコード (PK) を使用して同じファイル (または任意の .docx ファイル) が追加された場合、DB への書き込みは問題ないように見えますが、ファイルを開こうとすると失敗し、上記と同じエラー メッセージが表示されます。 .
開くことができない .docx ファイルは、正常に開くことができる場合よりも 1 バイト長くなります。Word で開くことができない .docx ファイルは、アーカイブとして (たとえば 7zip で) 開くことができ、ファイルの内容は同じように見えます。
既存のファイルを上書きしたり、削除されたファイルのコード (PK) を他のファイル タイプ (.doc を含む) で再利用したりすることは正常に機能します。.docx ファイルのみが問題を引き起こしています。レポートの生成は、Word 文書の内容を OpenXML コードで操作することによって行われるため、.docx ファイルが必要となるため、これは残念です。
ファイルをデータベースに挿入するコードは次のとおりです。
Private Sub btnInsert_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnInsert.Click
Dim sName As String = InputBox("What is the name of this Resource")
If (sName.Length > 0) Then
Dim ofd As New OpenFileDialog
With ofd
.CheckFileExists = True
.ShowReadOnly = False
.Filter = "All Files|*.*"
If (.ShowDialog = DialogResult.OK) Then
Dim fs As FileStream = New FileStream(.FileName, FileMode.Open, FileAccess.Read)
Dim docByte As Byte() = New Byte(fs.Length - 1) {}
fs.Read(docByte, 0, Convert.ToInt32(fs.Length))
fs.Close()
Dim FileType As String = Path.GetExtension(.FileName).ToLower
Dim conn As New SqlConnection(strConnString)
Dim cmd As New SqlCommand(sqlInsert, conn)
cmd.Parameters.AddWithValue("@ID", sName)
cmd.Parameters.AddWithValue("@Bytes", docByte)
cmd.Parameters.AddWithValue("@Types", FileType)
conn.Open()
cmd.ExecuteNonQuery()
conn.Close()
MsgBox("Saved to DB")
Dim li As ListViewItem = lvwResource.Items.Add(sName)
li.SubItems.Add(FileType)
docByte = Nothing
fs.Dispose()
End If
End With
End If
End Sub
そして、取得するコード:
Private Sub btnOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpen.Click
Dim sName As String = lvwResource.SelectedItems(0).Text
Dim sType As String = lvwResource.SelectedItems(0).SubItems(1).Text
Dim fileName As String = String.Format("{0}{1}{2}", Path.GetTempPath, sName, sType)
Dim conn As New SqlConnection(strConnString)
Dim cmd As New SqlCommand(sqlSelect, conn)
cmd.Parameters.AddWithValue("@ID", sName)
Dim da As New SqlDataAdapter(cmd)
Dim dt As New DataTable
da.Fill(dt)
Dim docByte() As Byte = dt.Rows(0)(1)
Dim fs As New FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write)
fs.Write(docByte, 0, Convert.ToInt32(docByte.Length))
fs.Dispose()
Try
System.Diagnostics.Process.Start(fileName)
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Question, "Unknown Resource Type")
End Try
End Sub
詳細: ワークステーションは Windows XP SP3 with Microsoft Office 2003 SP3、サーバーは Server 2003 Standard edition SP2、db は SQL Server 2005 SP2 です。それは大規模な組織であり、私は彼らの時代遅れのソフトウェアに対して何の影響力も持っていません.