ClickOnce更新,控制版本跳转

时间:2012-02-23 11:56:44

标签: clickonce database-schema

我们有一个ClickOnce部署的应用程序。我们希望确保安装只更新1版本跳转时间。 (欢迎其他最佳实践解决方案)。

例如,假设用户安装了1.16版本,同时有2个新版本,因此服务器上的版本现在为1.18。我们希望确保下次应用程序更新时,它会首先从1.16更新到1.17。然后在下次更新时,它会从1.17更新到1.18等。它不会直接从1.16更新到1.18。

为什么,你可能会问。它与我们的应用程序具有本地(SQL EXPRESS)数据库这一事实有关。我们有一个自定义更新类,在应用程序启动时调用。它检测是否发生了CO更新,如果是,它会使用可能已进行的任何架构更改来更新本地数据库。即CO更新首先提供执行scehma更改所需的文件,然后自定义更新类执行实际的数据库修改。跳转多于1个版本时会出现问题,因为在此示例中,将永远不会应用从v.16到v.17的db更改脚本。

我们的第一种方法是菊花链CO更新文件夹。这是从1.18 1.17更新的v.16更新,但这似乎没有解决问题。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

我有一个强大的ClickOnce应用程序,它也可以在最终用户的PC上使用SQL Server Express。在我们的例子中,在我们的Web服务器上管理本地数据库模式的同步。

应用程序启动后,将从当前客户端数据库中提取版本信息(如果数据库不存在,则返回版本“0”)然后Web服务返回必要的脚本文件以构建本地数据库。然后,ClickOnce应用程序按顺序执行脚本,并且无论上次用户何时启动应用程序,都可以完美地构建数据库模式。

更新本地架构后,将从服务器重新同步用户需要访问的所有数据。这是因为每次更新数据表时,我都必须删除该表,然后从我的模式更新脚本中重新创建它们。

如果您不想管理这种类型的复杂服务器/客户端脚本/数据库管理系统,为什么不能将关联的SQL脚本与您的应用程序捆绑在一起?您可以通过在客户端数据库中定义维护当前数据库版本的表来实现此目的。当您的用户向应用程序下载新更新时,请检查数据库的版本,并根据客户端的当前数据库版本,执行您使用应用程序编译的可用脚本或命令。

仅向应用程序的每个后续发布添加脚本,并且永远不会删除旧脚本。新的SQL脚本应该DROP并重新创建任何正在更新的对象。如果您的应用程序在应用程序执行的脚本中发生崩溃,这可以为您节省很多麻烦。我很难学到这一点。

我建议创建一个同步机制,从服务器管理版本检查,而不是使用应用程序编译脚本或嵌入SQL命令。这样,无需发布应用程序即可对数据库进行微小更改。相信我,您的用户会感谢您,因为他们不必下载频繁的应用程序更新。相反,这些类型的更改将是无缝的,并将在幕后自动进行。

答案 1 :(得分:1)

我正在粘贴一个方法,用于查找从桌面启动的程序版本以及从ClickOnce启动时的更新版本。

    private string GetTheVersion()
    {
        string version = string.Empty;
        Version currentVersion;
        Version updateVersion;
        StringBuilder sb = new StringBuilder();
        if (ApplicationDeployment.IsNetworkDeployed)
        {
                currentVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion;
            updateVersion = ApplicationDeployment.CurrentDeployment.UpdatedVersion;

            sb.AppendLine(string.Format("Current Version: {0}.{1}.{2}.{3}", currentVersion.Major.ToString(), currentVersion.Minor.ToString(), currentVersion.MajorRevision.ToString(), currentVersion.MinorRevision.ToString()));
            sb.AppendLine(string.Format("Updated Version: {0}.{1}.{2}.{3}", updateVersion.Major.ToString(), updateVersion.Minor.ToString(), updateVersion.MajorRevision.ToString(), updateVersion.MinorRevision.ToString()));
            version = sb.ToString();
        }
        else
        {
            currentVersion = Assembly.GetCallingAssembly().GetName().Version;
            version = string.Format("Current Version: {0}.{1}.{2}.{3}", currentVersion.Major.ToString(), currentVersion.Minor.ToString(), currentVersion.MajorRevision.ToString(), currentVersion.MinorRevision.ToString());
        }

        return version;
    }

当然,您需要的不仅仅是您需要的,但您可以使用ApplicationDeployment.CurrentDeployment类的方法来确定是否执行更新。您可以将现有应用程序的最低版本传递给命令行参数或url querystring变量,具体取决于您的部署方式。

乔伊