【问题标题】:app data path during development versus deployment开发与部署期间的应用程序数据路径
【发布时间】:2015-05-28 00:01:26
【问题描述】:

我有一个旧的 Windows Forms .Net 应用程序,它通过将所有文件复制到应用程序文件夹来“部署”在 Windows XP 上。

现在我计划使用 InstallShield 或 Advanced Installer 部署到较新的 Windows 操作系统,并将 dll 放在应用安装文件夹中,并将内容文件放在 ProgramData 和/或用户的 AppData 中。

因此,在 Visual Studio 2010 下调试期间,内容文件将位于一个位置(可能只是将它们保留在当前位置,在应用程序的 bin/debug 文件夹中),而在部署时将位于另一个位置。

如何在 Visual Studio 调试期间和部署期间以相同的方式访问这些文件?

如果我有一个包含内容文件基本路径的全局字符串,那么我可以使用相对于该字符串的路径访问文件。但我不确定如何在调试期间创建一个具有正确路径的字符串,然后在部署期间创建一个不同的路径。

我知道我可以测试 Debug 与 Release 标志,但这并不完全相同。 (切换到发布版本只是将文件移动到 ../bin/Release 而不是 ../bin/Debug;可能仍未部署。)

有没有一个简单的例子来说明如何做到这一点?

明确地说,我不是在询问访问相对于基本目录的路径的详细信息。我在问如何区分运行部署和开发期间运行。

因此,知道如何检测“我已部署”是我需要的最低限度的帮助。更好的是一个小示例或教程链接,显示在开发过程中在一个位置访问内容文件,在部署时访问另一个位置。


更新

What is the best way in c# to determine whether the programmer is running the program via IDE or it's user? 涵盖了最重要的情况,所以如果没有其他解决方案,我会使用它。但是,如果开发人员直接双击开发项目的 bin/debug 文件夹中的 .exe,它就不能正常工作。因为它们不在 IDE 中运行(我们也没有使用 vshost.exe),但基本文件夹与它们相同。

更新

经过进一步思考,上面建议的 stackoverflow Q&A 根本不是一回事。我不在乎是否附加了调试器(可以将调试器附加到已安装/已部署的版本,它仍然是已部署的版本,而不是开发版本)。

我最初认为应用程序可以使用某些标准标志或配置设置来确定它是否已安装。

鉴于在开发和安装过程中他们不会在同一个地方,人们如何知道在哪里寻找他们的内容文件? (除非您采用“老派”方法将内容文件放入您的应用安装文件夹。这是我以前的做法,但现在需要采取不同的做法。)


更新

终于顿悟了,我不应该在开发过程中尝试将内容文件保留在 bin/debug 文件夹中 - 之所以这样做,是因为以前就是这样。尚未决定是将它们全部移动到部署后的位置,还是移动到开发机器上的其他位置。

我仍然很好奇其他人在开发过程中如何指定内容文件的位置,但也许这是一个不同的问题......

【问题讨论】:

  • @DrewJordan:谢谢 - 这是一种可能的方法,对于我的目的来说可能已经足够了,尽管它不包括一个案例。在开发文件夹中,有人可以双击 .exe。它们不会“在 Visual Studio 下运行”/“通过 IDE”,但文件的位置与它们运行时的位置相同。
  • 嗯。如果我还没有基本路径,我可能会通过在两个可能的位置显式查找文件来解决这个问题。然后缓存该基本路径以供将来访问内容。
  • 对...不过,您在这里问了两个不同的问题,不是吗?无论如何,这就是为什么我将其发布为评论而不是答案...我认为您需要将其与一些“规则”结合起来进行开发和测试。
  • @DrewJordan 人们如何知道在哪里寻找他们的内容文件,因为他们在开发和安装期间不会在同一个地方?

标签: .net winforms visual-studio-2010 deployment file-access


【解决方案1】:

我通过在两个可能的位置显式查找文件来解决此问题。然后缓存目录路径以供将来访问内容。就我而言,“开发”位置是“bin”文件夹旁边的“内容”文件夹。

' Language: Visual Basic (VB)
' ... this is inside a VB module ...
Public g_AppRelativePath As String = "CompanyName\AppName"
Private _contentPathRootWithSlash As String

Public Function ContentPath(relPath As String) As String
  If _contentPathRootWithSlash Is Nothing Then
    ' --- first try to find "development" content ---
    ' Folder containing .exe.
    Dim pathRoot As String = Application.StartupPath
    Dim binIndex As Integer = pathRoot.LastIndexOf("bin", StringComparison.Ordinal)
    If binIndex >= 0 Then
      ' "content" folder that has been prepared as a sibling of "bin".
      pathRoot = pathRoot.Remove(binIndex) & "content"
    End If
    Dim pathRootWithSlash As String = pathRoot & "\"

    If File.Exists(pathRootWithSlash & relPath) Then
      _contentPathRootWithSlash = pathRootWithSlash

    Else
      ' --- "development" content does not exist; look for "deployed" content. ---
      '' Use this, if want files to be in User's AppData\Roaming.
      'pathRootWithSlash = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\"
      ' Use this, if want files to be shared by all users, in ProgramData.
      pathRootWithSlash = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) & "\"
      ' g_AppRelativePath was previously set to "CompanyName\AppName", which matches logic in our installer.
      pathRootWithSlash = pathRootWithSlash & g_AppRelativePath & "\"
      If File.Exists(pathRootWithSlash & relPath) Then
        _contentPathRootWithSlash = pathRootWithSlash

      Else
        ' Failed to find.
        MsgBox(String.Format("Can't find content file ""{0}""", relPath))
        Return Nothing
      End If
    End If
  End If

  Return _contentPathRootWithSlash & relPath
End Function

【讨论】:

    猜你喜欢
    • 2022-10-17
    • 1970-01-01
    • 1970-01-01
    • 2019-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多