VB.Net 数据 (.mdb) 内容文件在发布后不可用。我错过了什么?

VB.Net Data (.mdb) content files not available after publish. What am I missing?

我正在我的笔记本电脑上编写程序,发布后我需要 运行 在我的工作计算机上。该程序执行大量数据库工作,然后打开一个 word 文档并将邮件合并链接到数据。在调试中一切正常。在我的笔记本电脑和台式机上发布后它崩溃了。 我已经隔离了问题,但不知道如何解决。

似乎 .mdb 文件,即 .docx 文件想要读取的内容,在 运行 时没有被复制到 App_Data 目录。这很奇怪,因为我在项目中同时拥有 .docx 文件和 .mdb 文件作为 content 文件。 .docx 文件显示在该文件夹中,我的程序可以正常打开它。

.mdb 文件唯一不同的是,它也是项目中的数据源,并且是通过添加数据源引入的,而不是仅仅添加文档本身并进行构建操作content.显然这就是它的工作方式,但是……最后问题来了……如何将成品 .mdb 文件复制到 App_Data 文件夹,以便我的 .docx 文件可以从中读取?

以下是我现在使用的我认为应该有效的代码行:

Dim w As New Word.Application
Try
    Dim Folder As String = My.Application.Info.DirectoryPath.ToString
    'MsgBox(Folder)
    Dim Path As String = Folder & "\StandardLetter.docx"
    w.Documents.Open(Path, [ReadOnly]:=True)
    w.WindowState = Word.WdWindowState.wdWindowStateMaximize
    w.Visible = True
    w.Activate()
Catch ex As Exception
    MsgBox("Couldn't open the document.")
    Exit Sub
End Try
Try
    Dim AccessFolder As String = My.Application.Info.DirectoryPath.ToString
    w.ActiveDocument.MailMerge.OpenDataSource(AccessFolder & "\RenewalTemp.mdb")
    'This does not work after publishing because RenewalTemp.mdb doesn't appear in the AppData Folder
Catch ex As Exception
    MsgBox("Error accessing the RenewalLetterTemp Database.")
    MsgBox("Path = " & My.Application.Info.DirectoryPath.ToString & "\RenewalTemp.mdb")
    Exit Sub
End Try

编辑 - 我进一步缩小了问题范围,但仍未解决。原来问题出在这段代码引用的目录上:

Dim AccessFolder As String = My.Application.Info.DirectoryPath.ToString

这在调试期间工作得很好,因为它指的是 \bin\debug 文件夹,并且 .mdb 文件在调试期间去那里。

在 BUILD 中,它们会转到上述代码未引用的位置。我不知道如何引用位置,但必须有一个好方法。此外,目录名称包含一堆似乎是随机生成的字符,所以我也不知道如何对位置进行硬编码。这是两个目录:

Dim AccessFolder As String = My.Application.Info.DirectoryPath.ToString
C:\Users\lholk\AppData\Local\Apps.0\OGMYVLOB.LZH\TD1N8EZX.KAN\rene..tion_7dc5ad3db20d2410_0001.0000_fee3b96b6598cca2

Dim AccessFolder As String = '??? I Don't know what should go here
C:\Users\lholk\AppData\Local\Apps.0\OGMYVLOB.LZH\TD1N8EZX.KAN\rene...exe_7dc5ad3db20d2410_0001.0000_none_6758ee3059fd9f2f

我在 My.Application space 中四处看了看,但没有看到其他有用的东西。你能帮我吗? 编辑 2 - 如果我引用 .mdb 的 TableAdapter,我可以获得以下输出,这几乎是我需要的:

    Dim Tbl As New RenewalTempDataSetTableAdapters.RenewalLettersTableAdapter
    Dim RightFolder As String = Tbl.Connection.DataSource
'Returns "|Data Directory|\RenewalTemp.mdb"

我知道某处'under the hood' 一定有一个变量可以生成实际的|数据目录|因为它在这里被称为 | |符号。

这就是解决问题的方法。澄清一下,在您发布程序后,数据文件存储在与其他内容文件不同的位置。我在通常的 类 中找不到任何可以提供这条路径的东西,所以我倒退了。 这适用于调试模式、发布后和更新后。希望它对其他人也有用。

        Public Shared Function GetDataFilePath(FileName As String) As String
    'StartPath refers to the location of regular content files
    Dim StartPath As String = My.Application.Info.DirectoryPath.ToString
    If IO.Directory.Exists(StartPath) Then
        For Each file As String In IO.Directory.GetFiles(StartPath)
            StartPath = file
            Exit For
        Next
    End If
    'DataFolder is where root of where published apps data files go, but the actual directory is 3 levels below.
    'The name of the Folder I'm looking for has the SAME name as the Folder the Content files are in.
    Dim DataFolder As String = Environ("UserProfile") & "\AppData\Local\Apps.0\Data"
    Dim Control As String = DataFolder
    Dim DataParent As String = IO.Directory.GetParent(StartPath).ToString
    Dim BackSlash As Integer = DataParent.LastIndexOf("\")
    Dim FolderName As String = Strings.Right(DataParent, Len(DataParent) - BackSlash - 1)
    Dim DataPath As String = ""

    If IO.Directory.Exists(DataParent) Then
        For Each SubFolder1 As String In IO.Directory.GetDirectories(DataFolder)
            'MsgBox(SubFolder1)
            For Each SubFolder2 As String In IO.Directory.GetDirectories(SubFolder1)
                'MsgBox(SubFolder2)
                For Each SubFolder3 As String In IO.Directory.GetDirectories(SubFolder2)
                    'MsgBox(SubFolder3)

                    Dim MatchBackSlash As Integer = SubFolder3.LastIndexOf("\")
                    Dim Match As String = Strings.Right(SubFolder3, Len(SubFolder3) - MatchBackSlash - 1)
                    If Match = FolderName Then
                        DataFolder = SubFolder2 & "\" & Match & "\Data"
                        'MsgBox(DataFolder)
                    End If
                Next
            Next
        Next
    End If
    If DataFolder <> Control Then
        Return DataFolder & "\" & FileName
    End If
    'This makes it so it works in Debug Mode as well, where everything is stored in the bin\debug folder
    Return My.Application.Info.DirectoryPath & "\" & FileName

End Function