访问 ClickOnce 应用程序中的本地和远程数据

大多数应用程序使用或生成数据。 ClickOnce 提供了各种用于在本地和远程读取和写入数据的选项。

本地数据

借助 ClickOnce,可以使用以下任一方法在本地加载和存储数据:

  • ClickOnce 数据目录

  • 独立存储

  • 其他本地文件

ClickOnce 数据目录

本地计算机上安装的每个 ClickOnce 应用程序都有一个数据目录,存储在用户的“文档”和“设置”文件夹中。 在安装应用程序时,ClickOnce 应用程序中凡是标记为“数据”文件的任何包含文件将被复制到这个目录。 数据文件可以是任何文件类型,最常用的是文本、XML 和数据库文件,例如 Microsoft Access .mdb 文件。

数据目录适用于应用程序托管的数据,即应用程序显式存储和维护的数据。 应用程序清单中未标记为“data”的所有静态非依赖文件将改为驻留在应用程序目录中。 此目录是应用程序的可执行文件(.exe)文件和程序集所在的位置。

注释

卸载 ClickOnce 应用程序时,也会删除其数据目录。 切勿使用数据目录来存储最终用户管理的数据,例如文档。

在 ClickOnce 分发中标记数据文件

若要将现有文件放入数据目录,必须将现有文件标记为 ClickOnce 应用程序的应用程序清单文件中的数据文件。 有关详细信息,请参阅 如何:在 ClickOnce 应用程序中包括数据文件

从数据目录中读取和写入数据

从数据目录读取需要 ClickOnce 应用程序请求读取权限;同样,写入目录需要写入权限。 如果应用程序配置为使用完全信任运行,应用程序将自动拥有此权限。 有关使用"权限提升"或"受信任的应用程序部署"来提升应用程序权限的详细信息,请参阅安全 ClickOnce 应用程序

注释

如果组织不使用受信任的应用程序部署,并且已关闭权限提升,则请求权限将失败。

应用程序拥有这些权限后,可以使用对内部 System.IO类的方法调用来访问数据目录。 可以通过使用定义在ApplicationDeployment属性CurrentDeployment上的DataDirectory属性来获取 Windows 窗体 ClickOnce 应用程序中的数据目录路径。 这是访问数据的最方便和建议的方法。 下面的代码示例为你演示如何在部署中对一个名为 CSV.txt 的文本文件执行操作,该文件已作为数据文件包含在其中。

注释

在 .NET Core 和 .NET 5 及更高版本中,不支持命名空间 System.Deployment.Application中的类 ApplicationDeployment 和 API。 在 .NET 7 中,支持访问应用程序部署属性的新方法。 有关详细信息,请参阅 .NET 中的 Access ClickOnce 部署属性。 .NET 7 不支持 ApplicationDeployment 方法的等效项。

if (ApplicationDeployment.IsNetworkDeployed)
{
    try
    {
        using (StreamReader sr = new StreamReader(ApplicationDeployment.CurrentDeployment.DataDirectory + @"\CSV.txt"))
        {
            MessageBox.Show(sr.ReadToEnd());
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Could not read file. Error message: " + ex.Message);
    }
}

有关将部署中的文件标记为数据文件的详细信息,请参阅 如何:在 ClickOnce 应用程序中包括数据文件

还可以使用类上的 Application 相关变量(例如 LocalUserAppDataPath)获取数据目录路径。

处理其他类型的文件可能需要额外权限。 例如,如果要使用 Access 数据库(.mdb)文件,应用程序必须断言完全信任才能使用相关的 <xref:System.Data> 类。

数据目录和应用程序版本

应用程序的每个版本都有自己的数据目录,与其他版本隔离。 ClickOnce 将创建此目录,而不考虑部署中是否包含任何数据文件,以便应用程序在运行时具有创建新数据文件的位置。 安装应用程序的新版本后,ClickOnce 会将以前版本的数据目录中的所有现有数据文件复制到新版本的数据目录中,无论这些文件是包含在原始部署中还是由应用程序创建。

如果数据文件在旧版本的应用程序中具有不同于新版本的哈希值,ClickOnce 将用服务器上的新版本替换旧版本的文件。 此外,如果应用程序的早期版本创建了与新版本部署中包含的文件同名的新文件,ClickOnce 将使用新文件覆盖旧版本的文件。 在这两种情况下,旧文件将包含在名为 .pre的数据目录中的子目录中,以便应用程序仍可访问旧数据以进行迁移。

如果需要对数据进行精细迁移,可以使用 ClickOnce 部署 API 执行从旧数据目录到新数据目录的自定义迁移。 你需要使用IsFirstRun测试是否有可用下载,然后使用UpdateUpdateAsync下载更新,并在更新完成后自行执行任何自定义数据迁移工作。

独立存储

独立存储提供一个 API,用于使用简单的 API 创建和访问文件。 存储文件的实际位置对开发人员和用户是隐藏的。

独立存储适用于所有版本的 .NET Framework。 独立存储也适用于部分受信任的应用程序,无需额外的权限授予。 如果应用程序必须以部分信任方式运行,但必须维护特定于应用程序的数据,则应使用独立存储。

注释

在 ClickOnce for .NET Core 和 .NET 5 或更高版本中,不支持需要代码访问安全性的部分信任。 在 .NET Framework 中,使用代码访问安全性不是最佳做法,不建议这样做。

有关详细信息,请参阅 独立存储

其他本地文件

如果应用程序必须处理或保存最终用户数据(例如报表、图像、音乐等),应用程序需要 FileIOPermission 读取和写入本地文件系统的数据。

远程数据

在某些时候,应用程序可能需要从远程网站检索信息,例如客户数据或市场信息。 本部分讨论用于检索远程数据的最常见技术。

使用 HTTP 访问文件

可以通过使用命名空间System.Net中的WebClient类或HttpWebRequest类来从 Web 服务器访问数据。 数据可以是静态文件,也可以是返回原始文本或 XML 数据的 ASP.NET 应用程序。 如果数据采用 XML 格式,则检索数据的最快方法是使用 XmlDocument 类(其 Load 方法采用 URL 作为参数)。 有关示例,请参阅 将 XML 文档读入 DOM

当应用程序通过 HTTP 访问远程数据时,必须考虑安全性。 默认情况下,ClickOnce 应用程序对网络资源的访问可能会受到限制,具体取决于应用程序的部署方式。 这些限制用于防止恶意程序访问特权远程数据或使用用户的计算机攻击网络上的其他计算机。

下表列出了你可能使用的部署策略及其默认 Web 权限。

部署类型 默认网络权限
网页安装 只能访问安装应用程序的 Web 服务器
文件共享安装 无法访问任何 Web 服务器
CD-ROM 安装 可以访问任何 Web 服务器

如果由于安全限制导致 ClickOnce 应用程序无法访问 Web 服务器,则必须为该网站进行 WebPermission 的设置或声明以克服此限制。 有关提高 ClickOnce 应用程序的安全权限的详细信息,请参阅 安全 ClickOnce 应用程序

通过 XML Web 服务访问数据

如果将数据公开为 XML Web 服务,则可以使用 XML Web 服务代理访问数据。 代理是使用任一 Visual Studio 创建的 .NET Framework 类。 XML Web 服务的操作,例如检索客户、下单等,作为方法在代理对象上公开。 这使得 Web 服务比原始文本或 XML 文件更容易使用。

如果 XML Web 服务通过 HTTP 运行,该服务将受到与WebClientHttpWebRequest类相同的安全限制。

直接访问数据库

可以使用命名空间中的 System.Data 类与网络上的数据库服务器(如 SQL Server)建立直接连接,但必须考虑到安全问题。 与 HTTP 请求不同,默认情况下,数据库连接请求在部分信任下始终被禁止;只有在从 CD-ROM 安装 ClickOnce 应用程序时,才默认拥有此类权限。 这给你的应用程序提供了完全的信任。 若要启用对特定 SQL Server 数据库的访问,应用程序必须请求 SqlClientPermission;若要启用对 SQL Server 以外的数据库进行访问,必须请求 OleDbPermission

大多数时候,你不必直接访问数据库,而是通过用 ASP.NET 或 XML Web 服务编写的 Web 服务器应用程序来访问它。 如果 ClickOnce 应用程序是从 Web 服务器部署的,则以这种方式访问数据库通常是最佳方法。 可以在部分信任的情况下访问服务器,而无需提升应用程序的权限。