Файлы содержимого данных VB.Net (.mdb) недоступны после публикации. Что мне не хватает?

Я пишу программу на своем ноутбуке, которую мне нужно запустить на рабочем компьютере после публикации. Программа выполняет кучу работы с базой данных, а затем открывает документ 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\2.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\2.0\OGMYVLOB.LZH\TD1N8EZX.KAN\rene...exe_7dc5ad3db20d2410_0001.0000_none_6758ee3059fd9f2f

Я просмотрел пространство My.Application, но не нашел там ничего полезного. Вы можете помочь? РЕДАКТИРОВАТЬ 2. Если я сошлюсь на TableAdapter для .mdb, я могу получить следующий вывод, который мне ПОЧТИ нужен:

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

Я знаю, что где-то «под капотом» должна быть переменная, которая может создать фактический |Каталог данных| как это упоминается здесь между | | символы.


person Rockin Raul    schedule 30.10.2015    source источник
comment
Установите CopyToOutputDirectory на CopyAlways.   -  person Fᴀʀʜᴀɴ Aɴᴀᴍ    schedule 30.10.2015
comment
Это уже так настроено.   -  person Rockin Raul    schedule 30.10.2015
comment
Тогда это странно.   -  person Fᴀʀʜᴀɴ Aɴᴀᴍ    schedule 30.10.2015
comment
Знаете ли вы, есть ли способ принудительно скопировать mdb в место, которое я бы выбрал?   -  person Rockin Raul    schedule 31.10.2015
comment
Возможно ли, что что-то сломано или отсутствует во «внутреннем» коде, который автоматически генерируется при связывании источника данных?   -  person Rockin Raul    schedule 01.11.2015
comment
вы можете сохранить свой файл как встроенный ресурс, а затем при первой загрузке скопировать его в исполняемый каталог.   -  person Fᴀʀʜᴀɴ Aɴᴀᴍ    schedule 01.11.2015
comment
@FarhanAnam Я отредактировал обновленную информацию, которую только что обнаружил. Не могли бы вы взглянуть еще раз? Спасибо!   -  person Rockin Raul    schedule 02.11.2015


Ответы (1)


Это то, что помогло решить проблему. Чтобы уточнить, после публикации программы файлы данных хранятся отдельно от других файлов содержимого. Я не смог найти ничего в обычных классах, которые предоставляли бы этот путь, поэтому я работал в обратном порядке. Это работает в режиме отладки, после публикации и после обновления. Надеюсь, это будет полезно и кому-то еще.

        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\2.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
person Rockin Raul    schedule 20.11.2015