ClickOnce部署自动更新无效

时间:2014-04-23 08:58:36

标签: c# clickonce

我正在使用ClickOnce部署来检查更新:

  1. 我已完成设置,例如发布标签,发布网址和检查更新路径,并在应用程序启动前检查更新并离线和在线运行应用程序。
  2. 如果从本地系统安装应用程序,我会收到更新,但是,如果我从服务器安装应用程序,那么它不会检查更新。
  3. 以下是我用于检查更新的代码。我该如何纠正这个问题?

    private void InstallUpdateSyncWithInfo()
    {
        UpdateCheckInfo info = null;
        if (ApplicationDeployment.IsNetworkDeployed)
        {
            ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment;
    
            try
            {
                info = ad.CheckForDetailedUpdate();
            }
            catch (DeploymentDownloadException dde)
            {
                MessageBox.Show("The new version of the application cannot be downloaded at this time. \n\nPlease check your network connection, or try again later. Error: " + dde.Message);
                return;
            }
            catch (InvalidDeploymentException ide)
            {
                MessageBox.Show("Cannot check for a new version of the application. The ClickOnce deployment is corrupt. Please redeploy the application and try again. Error: " + ide.Message);
                return;
            }
            catch (InvalidOperationException ioe)
            {
                MessageBox.Show("This application cannot be updated. It is likely not a ClickOnce application. Error: " + ioe.Message);
                return;
            }
    
            if (info.UpdateAvailable)
            {
                Boolean doUpdate = true;
    
                if (!info.IsUpdateRequired)
                {
                    DialogResult dr = MessageBox.Show("An update is available. Would you like to update the application now?", "Update Available", MessageBoxButtons.OKCancel);
                    if (!(DialogResult.OK == dr))
                    {
                        doUpdate = false;
                    }
                }
                else
                {
                    // Display a message that the app MUST reboot. Display the minimum required version.
                    MessageBox.Show("This application has detected a mandatory update from your current " +
                        "version to version " + info.MinimumRequiredVersion.ToString() +
                        ". The application will now install the update and restart.",
                        "Update Available", MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                }
    
                if (doUpdate)
                {
                    try
                    {
                        ad.Update();
                        MessageBox.Show("The application has been upgraded, and will now restart.");
                        Application.Restart();
    
                    }
                    catch (DeploymentDownloadException dde)
                    {
                        MessageBox.Show("Cannot install the latest version of the application. \n\nPlease check your network connection, or try again later. Error: " + dde);
                        return;
                    }
                }
            }
        }
        else
        {
            MessageBox.Show("There are no updates available");
        }
    }
    

    C#项目文本文件:

    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="4.0" DefaultTargets="Build"
        xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
        <PropertyGroup>
            <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
            <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
            <ProductVersion>8.0.30703</ProductVersion>
            <SchemaVersion>2.0</SchemaVersion>
            <ProjectGuid>{1804771A-88C8-49AD-9763-44A296B7EC2B}</ProjectGuid>
            <OutputType>WinExe</OutputType>
            <AppDesignerFolder>Properties</AppDesignerFolder>
            <RootNamespace>TestUpdate</RootNamespace>
            <AssemblyName>TestUpdate</AssemblyName>
            <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
            <TargetFrameworkProfile>Client</TargetFrameworkProfile>
            <FileAlignment>512</FileAlignment>
            <IsWebBootstrapper>true</IsWebBootstrapper>
            <PublishUrl>C:\Program Files %28x86%29\Zend\Apache2\htdocs\TestUpdate\</PublishUrl>
            <Install>true</Install>
            <InstallFrom>Web</InstallFrom>
            <UpdateEnabled>true</UpdateEnabled>
            <UpdateMode>Foreground</UpdateMode>
            <UpdateInterval>7</UpdateInterval>
            <UpdateIntervalUnits>Days</UpdateIntervalUnits>
            <UpdatePeriodically>false</UpdatePeriodically>
            <UpdateRequired>true</UpdateRequired>
            <MapFileExtensions>true</MapFileExtensions>
            <InstallUrl>http://www.acharis.com/Clinic/TestUpdate/</InstallUrl>
            <UpdateUrl>http://www.acharis.com/Clinic/TestUpdate/</UpdateUrl>
            <ProductName>Test UPdate</ProductName>
            <PublisherName>Acharis</PublisherName>
            <SuiteName>www.acharis.com</SuiteName>
            <MinimumRequiredVersion>1.0.0.10</MinimumRequiredVersion>
            <CreateWebPageOnPublish>true</CreateWebPageOnPublish>
            <WebPage>test.html</WebPage>
            <ApplicationRevision>11</ApplicationRevision>
            <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
            <UseApplicationTrust>true</UseApplicationTrust>
            <CreateDesktopShortcut>true</CreateDesktopShortcut>
            <PublishWizardCompleted>true</PublishWizardCompleted>
            <BootstrapperEnabled>true</BootstrapperEnabled>
        </PropertyGroup>
    
        <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
            <PlatformTarget>x86</PlatformTarget>
            <DebugSymbols>true</DebugSymbols>
            <DebugType>full</DebugType>
            <Optimize>false</Optimize>
            <OutputPath>bin\Debug\</OutputPath>
            <DefineConstants>DEBUG;TRACE</DefineConstants>
            <ErrorReport>prompt</ErrorReport>
            <WarningLevel>4</WarningLevel>
        </PropertyGroup>
        <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
            <PlatformTarget>x86</PlatformTarget>
            <DebugType>pdbonly</DebugType>
            <Optimize>true</Optimize>
            <OutputPath>bin\Release\</OutputPath>
            <DefineConstants>TRACE</DefineConstants>
            <ErrorReport>prompt</ErrorReport>
            <WarningLevel>4</WarningLevel>
        </PropertyGroup>
        <PropertyGroup>
            <ManifestCertificateThumbprint>B3D4C4433FA2AC368ACF13B0917D1CFEADFDF92A
            </ManifestCertificateThumbprint>
        </PropertyGroup>
        <PropertyGroup>
            <ManifestKeyFile>TestUpdate_TemporaryKey.pfx</ManifestKeyFile>
        </PropertyGroup>
        <PropertyGroup>
            <GenerateManifests>true</GenerateManifests>
        </PropertyGroup>
        <PropertyGroup>
            <SignManifests>true</SignManifests>
        </PropertyGroup>
        <ItemGroup>
           <Reference Include="System" />
           <Reference Include="System.Core" />
           <Reference Include="System.Xml.Linq" />
           <Reference Include="System.Data.DataSetExtensions" />
           <Reference Include="Microsoft.CSharp" />
           <Reference Include="System.Data" />
           <Reference Include="System.Deployment" />
           <Reference Include="System.Drawing" />
           <Reference Include="System.Windows.Forms" />
           <Reference Include="System.Xml" />
        </ItemGroup>
        <ItemGroup>
            <Compile Include="Form1.cs">
                <SubType>Form</SubType>
            </Compile>
            <Compile Include="Form1.Designer.cs">
                <DependentUpon>Form1.cs</DependentUpon>
            </Compile>
            <Compile Include="Program.cs" />
            <Compile Include="Properties\AssemblyInfo.cs" />
            <EmbeddedResource Include="Form1.resx">
                <DependentUpon>Form1.cs</DependentUpon>
            </EmbeddedResource>
            <EmbeddedResource Include="Properties\Resources.resx">
                <Generator>ResXFileCodeGenerator</Generator>
                <LastGenOutput>Resources.Designer.cs</LastGenOutput>
                <SubType>Designer</SubType>
            </EmbeddedResource>
            <Compile Include="Properties\Resources.Designer.cs">
                <AutoGen>True</AutoGen>
                <DependentUpon>Resources.resx</DependentUpon>
                <DesignTime>True</DesignTime>
            </Compile>
            <None Include="app.config" />
            <None Include="Properties\Settings.settings">
                <Generator>SettingsSingleFileGenerator</Generator>
                <LastGenOutput>Settings.Designer.cs</LastGenOutput>
            </None>
            <Compile Include="Properties\Settings.Designer.cs">
                <AutoGen>True</AutoGen>
                <DependentUpon>Settings.settings</DependentUpon>
                <DesignTimeSharedInput>True</DesignTimeSharedInput>
            </Compile>
            <None Include="TestUpdate_TemporaryKey.pfx" />
        </ItemGroup>
        <ItemGroup>
            <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
                <Visible>False</Visible>
                <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
                <Install>true</Install>
            </BootstrapperPackage>
            <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
                <Visible>False</Visible>
                <ProductName>.NET Framework 3.5 SP1</ProductName>
                <Install>false</Install>
            </BootstrapperPackage>
            <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
                <Visible>False</Visible>
                <ProductName>Windows Installer 3.1</ProductName>
                <Install>true</Install>
            </BootstrapperPackage>
        </ItemGroup>
        <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
        <!-- To modify your build process, add your task inside one of the targets below and
           Other similar extension points exist, see Microsoft.Common.targets.
        <Target Name="BeforeBuild">
        </Target>
        <Target Name="AfterBuild">
        </Target>
        -->
    </Project>
    

1 个答案:

答案 0 :(得分:3)

安装/更新位置应该是一个文件夹,而不是igofed提到的test.html文件。

下一步没有回答你的问题,但希望对你有用。您在样本中调用的方法ad.CheckForDetailedUpdate()中的.NET框架中存在一个错误,如果它被调用了足够多次(在自主应用程序无限期运行的情况下) )它将开始抛出COMExceptionInvalidOperationException

类型的异常

现在不幸的是我无法回想起我发现这个bug的地方,所以我无法给出应有的信用,但我们通过检查清单文件中的版本号并将其与当前版本进行比较来解决问题装配版。

private bool CheckForUpdateAvailable()
{
    Uri updateLocation = ApplicationDeployment.CurrentDeployment.UpdateLocation;

    //Used to use the Clickonce API but we've uncovered a pretty serious bug which results in a COMException and the loss of ability
    //to check for updates. So until this is fixed, we're resorting to a very lo-fi way of checking for an update.

    WebClient webClient = new WebClient();
    webClient.Encoding = Encoding.UTF8;
    string manifestFile = webClient.DownloadString(updateLocation);

    //We have some garbage info from the file header, presumably because the file is a .application and not .xml
    //Just start from the start of the first tag
    int startOfXml = manifestFile.IndexOfAny(new[] { '<' });
    manifestFile = manifestFile.Substring(startOfXml);

    Version version;

    XmlDocument doc = new XmlDocument();

    //build the xml from the manifest
    doc.LoadXml(manifestFile);

    XmlNodeList nodesList = doc.GetElementsByTagName("assemblyIdentity");
    if (nodesList == null || nodesList.Count <= 0)
    {
        throw new XmlException("Could not read the xml manifest file, which is required to check if an update is available.");
    }

    XmlNode theNode = nodesList[0];
    version = new Version(theNode.Attributes["version"].Value);

    if (version > ApplicationDeployment.CurrentDeployment.CurrentVersion)
    {
        // update application
        return true;
    }
    return false;
}

您的更新检查呼叫代码...

if (ApplicationDeployment.IsNetworkDeployed)
{
    bool updateIsAvailable;

    try
    {
        updateIsAvailable = CheckForUpdateAvailable();
    }
    catch
    {
        //not network deployed etc...
    }

    if (updateIsAvailable)
    {
        ad = ApplicationDeployment.CurrentDeployment;

        if (ad == null)
        {
            return;
        }

        ad.Update();
        Application.Restart();
    }
}