开发与部署期间的应用程序数据路径

app data path during development versus deployment

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

现在我计划使用 InstallShield 或 Advanced Installer 部署到较新的 windows OS,并将 dll 放在应用程序安装文件夹中,将内容文件放在 ProgramData and/or 用户的 AppData.

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

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

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

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

是否有一个简单的示例来说明如何完成此操作?

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

所以知道如何检测"I am deployed"是我需要的最起码的帮助。更好的是一个小示例或 link 教程,显示在开发期间在一个位置访问内容文件,在部署时在不同位置访问内容文件。


更新

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),但基本文件夹与它们相同。

更新

进一步思考,上面建议的Whosebug问答根本不是一回事。我不在乎是否附加了调试器(可以将调试器附加到 installed/deployed 版本,它仍然是部署版本,而不是开发版本)。

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

人们如何知道在哪里寻找他们的内容文件,因为他们在开发和安装过程中不会在同一个地方? (除非你采用 "old school" 方法将内容文件放入你的应用程序安装文件夹。这是我以前的方法,但现在需要做不同的事情。)


更新

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

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

我通过在两个可能的位置明确查找文件解决了这个问题。然后缓存目录路径以供将来访问内容。在我的例子中,"development" 位置是 "content" 文件夹,它位于 "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