mirror of
https://github.com/greenshot/greenshot
synced 2025-08-25 07:36:38 -07:00
Rewrote the update check.
This commit is contained in:
parent
dc16b1df74
commit
f57e49d781
20 changed files with 450 additions and 637 deletions
|
@ -103,6 +103,7 @@ namespace Greenshot.Addons.Core
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Supply values we can't put as defaults
|
/// Supply values we can't put as defaults
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="coreConfiguration">ICoreConfiguration</param>
|
||||||
/// <param name="property">The property to return a default for</param>
|
/// <param name="property">The property to return a default for</param>
|
||||||
/// <returns>object with the default value for the supplied property</returns>
|
/// <returns>object with the default value for the supplied property</returns>
|
||||||
public static object GetDefault(this ICoreConfiguration coreConfiguration, string property)
|
public static object GetDefault(this ICoreConfiguration coreConfiguration, string property)
|
||||||
|
|
|
@ -1,235 +0,0 @@
|
||||||
#region Greenshot GNU General Public License
|
|
||||||
|
|
||||||
// Greenshot - a free and open source screenshot tool
|
|
||||||
// Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
|
|
||||||
//
|
|
||||||
// For more information see: http://getgreenshot.org/
|
|
||||||
// The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 1 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Usings
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Xml;
|
|
||||||
using Dapplo.Log;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
namespace Greenshot.Addons.Core
|
|
||||||
{
|
|
||||||
public class RssFile
|
|
||||||
{
|
|
||||||
private readonly DateTime _pubdate;
|
|
||||||
|
|
||||||
public RssFile(string file, string pubdate, string link)
|
|
||||||
{
|
|
||||||
File = file;
|
|
||||||
if (!DateTime.TryParse(pubdate, out _pubdate))
|
|
||||||
{
|
|
||||||
DateTime.TryParseExact(pubdate.Replace(" UT", ""), "ddd, dd MMM yyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out _pubdate);
|
|
||||||
}
|
|
||||||
Link = link;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string File { get; }
|
|
||||||
public DateTime Pubdate => _pubdate;
|
|
||||||
|
|
||||||
public string Link { get; }
|
|
||||||
public Version Version { get; set; }
|
|
||||||
|
|
||||||
public string Language { get; set; }
|
|
||||||
|
|
||||||
public bool IsExe
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (File != null)
|
|
||||||
{
|
|
||||||
return File.ToLower().EndsWith(".exe");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsAlpha => File?.ToLowerInvariant().Contains("alpha") == true;
|
|
||||||
|
|
||||||
public bool IsBeta => File?.ToLowerInvariant().Contains("beta") == true;
|
|
||||||
|
|
||||||
public bool IsReleaseCandidate
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (File != null)
|
|
||||||
{
|
|
||||||
return Regex.IsMatch(File.ToLower(), "rc[0-9]+");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Description of RssHelper.
|
|
||||||
/// </summary>
|
|
||||||
public class RssHelper
|
|
||||||
{
|
|
||||||
private const string Rssfeed = "http://getgreenshot.org/project-feed/";
|
|
||||||
private static readonly LogSource Log = new LogSource();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This is using the HTTP HEAD Method to check if the RSS Feed is modified after the supplied date
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="updateTime">DateTime</param>
|
|
||||||
/// <returns>true if the feed is newer</returns>
|
|
||||||
public static bool IsRssModifiedAfter(DateTime updateTime)
|
|
||||||
{
|
|
||||||
var lastModified = NetworkHelper.GetLastModified(new Uri(Rssfeed));
|
|
||||||
if (lastModified == DateTime.MinValue)
|
|
||||||
{
|
|
||||||
// Time could not be read, just take now and add one hour to it.
|
|
||||||
// This assist BUG-1850
|
|
||||||
lastModified = DateTime.Now.AddHours(1);
|
|
||||||
}
|
|
||||||
return updateTime.CompareTo(lastModified) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Read the Greenshot RSS feed, so we can use this information to check for updates
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>List with RssFile(s)</returns>
|
|
||||||
public static IList<RssFile> ReadRss()
|
|
||||||
{
|
|
||||||
var rssDoc = new XmlDocument();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var webRequest = NetworkHelper.CreateWebRequest(Rssfeed);
|
|
||||||
var rssReader = new XmlTextReader(webRequest.GetResponse().GetResponseStream());
|
|
||||||
|
|
||||||
// Load the XML content into a XmlDocument
|
|
||||||
rssDoc.Load(rssReader);
|
|
||||||
}
|
|
||||||
catch (Exception wE)
|
|
||||||
{
|
|
||||||
Log.Warn().WriteLine("Problem reading RSS from {0}", Rssfeed);
|
|
||||||
Log.Warn().WriteLine(wE.Message);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop for the <rss> tag
|
|
||||||
XmlNode nodeRss = null;
|
|
||||||
for (var i = 0; i < rssDoc.ChildNodes.Count; i++)
|
|
||||||
{
|
|
||||||
// If it is the rss tag
|
|
||||||
if (rssDoc.ChildNodes[i].Name == "rss")
|
|
||||||
{
|
|
||||||
// <rss> tag found
|
|
||||||
nodeRss = rssDoc.ChildNodes[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nodeRss == null)
|
|
||||||
{
|
|
||||||
Log.Debug().WriteLine("No RSS Feed!");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop for the <channel> tag
|
|
||||||
XmlNode nodeChannel = null;
|
|
||||||
for (var i = 0; i < nodeRss.ChildNodes.Count; i++)
|
|
||||||
{
|
|
||||||
// If it is the channel tag
|
|
||||||
if (nodeRss.ChildNodes[i].Name == "channel")
|
|
||||||
{
|
|
||||||
// <channel> tag found
|
|
||||||
nodeChannel = nodeRss.ChildNodes[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nodeChannel == null)
|
|
||||||
{
|
|
||||||
Log.Debug().WriteLine("No channel in RSS feed!");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
IList<RssFile> rssFiles = new List<RssFile>();
|
|
||||||
|
|
||||||
// Loop for the <title>, <link>, <description> and all the other tags
|
|
||||||
for (var i = 0; i < nodeChannel.ChildNodes.Count; i++)
|
|
||||||
{
|
|
||||||
// If it is the item tag, then it has children tags which we will add as items to the ListView
|
|
||||||
|
|
||||||
if (nodeChannel.ChildNodes[i].Name != "item")
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var nodeItem = nodeChannel.ChildNodes[i];
|
|
||||||
var link = nodeItem["link"]?.InnerText;
|
|
||||||
var pubdate = nodeItem["pubDate"]?.InnerText;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (link == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var match = Regex.Match(Uri.UnescapeDataString(link), @"^.*\/(Greenshot.+)\/download$");
|
|
||||||
if (!match.Success)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var file = match.Groups[1].Value;
|
|
||||||
|
|
||||||
var rssFile = new RssFile(file, pubdate, link);
|
|
||||||
if (file.EndsWith(".exe") || file.EndsWith(".zip"))
|
|
||||||
{
|
|
||||||
var version = Regex.Replace(file, @".*[a-zA-Z_]\-", "");
|
|
||||||
version = version.Replace(@"\-[a-zA-Z]+.*", "");
|
|
||||||
version = Regex.Replace(version, @"\.exe$", "");
|
|
||||||
version = Regex.Replace(version, @"\.zip$", "");
|
|
||||||
version = Regex.Replace(version, @"RC[0-9]+", "");
|
|
||||||
if (version.Trim().Length > 0)
|
|
||||||
{
|
|
||||||
version = version.Replace('-', '.');
|
|
||||||
version = version.Replace(',', '.');
|
|
||||||
version = Regex.Replace(version, @"^[a-zA-Z_]*\.", "");
|
|
||||||
version = Regex.Replace(version, @"\.[a-zA-Z_]*$", "");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
rssFile.Version = new Version(version);
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
Log.Debug().WriteLine("Found invalid version {0} in file {1}", version, file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rssFiles.Add(rssFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Warn().WriteLine("Couldn't read RSS entry for: {0}", nodeChannel["title"]?.InnerText);
|
|
||||||
Log.Warn().WriteLine(ex, "Reason: ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rssFiles;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -363,7 +363,6 @@
|
||||||
<Compile Include="Core\NetworkHelper.cs" />
|
<Compile Include="Core\NetworkHelper.cs" />
|
||||||
<Compile Include="Core\ObjectExtensions.cs" />
|
<Compile Include="Core\ObjectExtensions.cs" />
|
||||||
<Compile Include="Core\PluginUtils.cs" />
|
<Compile Include="Core\PluginUtils.cs" />
|
||||||
<Compile Include="Core\RssHelper.cs" />
|
|
||||||
<Compile Include="Core\WindowCapture.cs" />
|
<Compile Include="Core\WindowCapture.cs" />
|
||||||
<Compile Include="Interfaces\ICaptureDetails.cs" />
|
<Compile Include="Interfaces\ICaptureDetails.cs" />
|
||||||
<Compile Include="Interfaces\Drawing\IDrawableContainer.cs" />
|
<Compile Include="Interfaces\Drawing\IDrawableContainer.cs" />
|
||||||
|
|
|
@ -83,6 +83,9 @@
|
||||||
<Reference Include="Dapplo.CaliburnMicro.Translations, Version=1.0.46.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Dapplo.CaliburnMicro.Translations, Version=1.0.46.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Dapplo.CaliburnMicro.Translations.1.0.46\lib\net46\Dapplo.CaliburnMicro.Translations.dll</HintPath>
|
<HintPath>..\packages\Dapplo.CaliburnMicro.Translations.1.0.46\lib\net46\Dapplo.CaliburnMicro.Translations.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Dapplo.HttpExtensions, Version=0.8.35.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Dapplo.HttpExtensions.0.8.35\lib\net46\Dapplo.HttpExtensions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Dapplo.Ini, Version=0.5.28.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Dapplo.Ini, Version=0.5.28.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Dapplo.Ini.0.5.28\lib\net45\Dapplo.Ini.dll</HintPath>
|
<HintPath>..\packages\Dapplo.Ini.0.5.28\lib\net45\Dapplo.Ini.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
@ -173,6 +176,7 @@
|
||||||
<HintPath>..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
|
<HintPath>..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System.Management" />
|
<Reference Include="System.Management" />
|
||||||
|
<Reference Include="System.Net.Http.WebRequest" />
|
||||||
<Reference Include="System.Numerics" />
|
<Reference Include="System.Numerics" />
|
||||||
<Reference Include="System.Reactive, Version=4.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
|
<Reference Include="System.Reactive, Version=4.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\System.Reactive.4.0.0\lib\net46\System.Reactive.dll</HintPath>
|
<HintPath>..\packages\System.Reactive.4.0.0\lib\net46\System.Reactive.dll</HintPath>
|
||||||
|
@ -200,6 +204,7 @@
|
||||||
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net46\System.Security.Cryptography.X509Certificates.dll</HintPath>
|
<HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net46\System.Security.Cryptography.X509Certificates.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="System.ServiceModel" />
|
||||||
<Reference Include="System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
<Reference Include="System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\System.Text.Encoding.CodePages.4.5.0\lib\net46\System.Text.Encoding.CodePages.dll</HintPath>
|
<HintPath>..\packages\System.Text.Encoding.CodePages.4.5.0\lib\net46\System.Text.Encoding.CodePages.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
@ -262,11 +267,13 @@
|
||||||
<Compile Include="Murmur3Tests.cs" />
|
<Compile Include="Murmur3Tests.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="StitchTests.cs" />
|
<Compile Include="StitchTests.cs" />
|
||||||
|
<Compile Include="UpdateTests.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="app.config" />
|
<ProjectReference Include="..\Greenshot.Addons\Greenshot.Addons.csproj">
|
||||||
</ItemGroup>
|
<Project>{5b924697-4dcd-4f98-85f1-105cb84b7341}</Project>
|
||||||
<ItemGroup>
|
<Name>Greenshot.Addons</Name>
|
||||||
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\Greenshot.Gfx.Experimental\Greenshot.Gfx.Experimental.csproj">
|
<ProjectReference Include="..\Greenshot.Gfx.Experimental\Greenshot.Gfx.Experimental.csproj">
|
||||||
<Project>{14894a45-aa2c-4bc3-85a3-e388d0bdc1ca}</Project>
|
<Project>{14894a45-aa2c-4bc3-85a3-e388d0bdc1ca}</Project>
|
||||||
<Name>Greenshot.Gfx.Experimental</Name>
|
<Name>Greenshot.Gfx.Experimental</Name>
|
||||||
|
@ -306,6 +313,12 @@
|
||||||
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.2.6.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" />
|
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.2.6.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" />
|
||||||
<Analyzer Include="..\packages\xunit.analyzers.0.9.0\analyzers\dotnet\cs\xunit.analyzers.dll" />
|
<Analyzer Include="..\packages\xunit.analyzers.0.9.0\analyzers\dotnet\cs\xunit.analyzers.dll" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="TestFiles\project-feed.xml">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|
75
src/Greenshot.Tests/TestFiles/project-feed.xml
Normal file
75
src/Greenshot.Tests/TestFiles/project-feed.xml
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<rss version="2.0">
|
||||||
|
<channel>
|
||||||
|
<title>Greenshot</title>
|
||||||
|
<link>https://getgreenshot.org</link>
|
||||||
|
<description>Greenshot update feed</description>
|
||||||
|
<item>
|
||||||
|
<title>Greenshot-INSTALLER-1.2.9.129-RELEASE.exe</title>
|
||||||
|
<link>http://sourceforge/projects/greenshot/files/release/Greenshot/Greenshot-INSTALLER-1.2.9.129-RELEASE.exe/download</link>
|
||||||
|
<pubDate>Sat, 28 Jan 2017 15:59:07 +0000</pubDate>
|
||||||
|
<description></description>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<title>Greenshot-INSTALLER-1.2.10.6-RELEASE.exe</title>
|
||||||
|
<link>http://sourceforge/projects/greenshot/files/release/Greenshot/Greenshot-INSTALLER-1.2.10.6-RELEASE.exe/download</link>
|
||||||
|
<pubDate>Wed, 09 Aug 2017 15:35:30 +0000</pubDate>
|
||||||
|
<description></description>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<title>Greenshot-INSTALLER-1.2.9.112-RELEASE.exe</title>
|
||||||
|
<link>http://sourceforge/projects/greenshot/files/release/Greenshot/Greenshot-INSTALLER-1.2.9.112-RELEASE.exe/download</link>
|
||||||
|
<pubDate>Fri, 30 Dec 2016 21:39:18 +0000</pubDate>
|
||||||
|
<description></description>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<title>Greenshot-INSTALLER-1.2.9.104-RELEASE.exe</title>
|
||||||
|
<link>http://sourceforge/projects/greenshot/files/release/Greenshot/Greenshot-INSTALLER-1.2.9.104-RELEASE.exe/download</link>
|
||||||
|
<pubDate>Thu, 15 Dec 2016 19:35:59 +0000</pubDate>
|
||||||
|
<description></description>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<title>Greenshot-INSTALLER-1.3.0.14-BETA.exe</title>
|
||||||
|
<link>http://sourceforge/projects/greenshot/files/release/Greenshot/Greenshot-INSTALLER-1.3.0.0-BETA.exe/download</link>
|
||||||
|
<pubDate>Thu, 03 Nov 2016 20:59:15 +0000</pubDate>
|
||||||
|
<description></description>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<title>Greenshot-INSTALLER-1.2.8.12-RELEASE.exe</title>
|
||||||
|
<link>http://sourceforge/projects/greenshot/files/release/Greenshot/Greenshot-INSTALLER-1.2.8.12-RELEASE.exe/download</link>
|
||||||
|
<pubDate>Tue, 10 Nov 2015 10:58:37 +0000</pubDate>
|
||||||
|
<description></description>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<title>Greenshot-INSTALLER-1.2.10.6-RELEASE.exe</title>
|
||||||
|
<link>https://github.com/greenshot/greenshot/releases/download/Greenshot-RELEASE-1.2.10.6/Greenshot-INSTALLER-1.2.10.6-RELEASE.exe</link>
|
||||||
|
<pubDate>Wed, 09 Aug 2017 15:35:30 +0000</pubDate>
|
||||||
|
<description></description>
|
||||||
|
</item><item>
|
||||||
|
<title>Greenshot-INSTALLER-1.2.9.129-RELEASE.exe</title>
|
||||||
|
<link>https://github.com/greenshot/greenshot/releases/download/Greenshot-RELEASE-1.2.9.129/Greenshot-INSTALLER-1.2.9.129-RELEASE.exe</link>
|
||||||
|
<pubDate>Sat, 28 Jan 2017 15:59:07 +0000</pubDate>
|
||||||
|
<description></description>
|
||||||
|
</item><item>
|
||||||
|
<title>Greenshot-INSTALLER-1.2.9.112-RELEASE.exe</title>
|
||||||
|
<link>https://github.com/greenshot/greenshot/releases/download/Greenshot-RELEASE-1.2.9.112/Greenshot-INSTALLER-1.2.9.112-RELEASE.exe</link>
|
||||||
|
<pubDate>Fri, 30 Dec 2016 21:39:18 +0000</pubDate>
|
||||||
|
<description></description>
|
||||||
|
</item><item>
|
||||||
|
<title>Greenshot-INSTALLER-1.2.9.104-RELEASE.exe</title>
|
||||||
|
<link>https://github.com/greenshot/greenshot/releases/download/Greenshot-RELEASE-1.2.9.104/Greenshot-INSTALLER-1.2.9.104-RELEASE.exe</link>
|
||||||
|
<pubDate>Thu, 15 Dec 2016 19:35:59 +0000</pubDate>
|
||||||
|
<description></description>
|
||||||
|
</item><item>
|
||||||
|
<title>Greenshot-INSTALLER-1.2.20.99-RC1.exe</title>
|
||||||
|
<link>https://github.com/greenshot/greenshot/releases/download/Greenshot-RC1-1.2.20.99/Greenshot-INSTALLER-1.2.20.99-RC1.exe</link>
|
||||||
|
<pubDate>Thu, 03 Nov 2016 20:59:15 +0000</pubDate>
|
||||||
|
<description></description>
|
||||||
|
</item><item>
|
||||||
|
<title>Greenshot-INSTALLER-1.2.8.12-RELEASE.exe</title>
|
||||||
|
<link>https://github.com/greenshot/greenshot/releases/download/Greenshot-RELEASE-1.2.8.12/Greenshot-INSTALLER-1.2.8.12-RELEASE.exe</link>
|
||||||
|
<pubDate>Tue, 10 Nov 2015 10:58:37 +0000</pubDate>
|
||||||
|
<description></description>
|
||||||
|
</item>
|
||||||
|
</channel>
|
||||||
|
</rss>
|
35
src/Greenshot.Tests/UpdateTests.cs
Normal file
35
src/Greenshot.Tests/UpdateTests.cs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
using System;
|
||||||
|
using System.ServiceModel.Syndication;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml;
|
||||||
|
using Dapplo.HttpExtensions;
|
||||||
|
using Dapplo.Log;
|
||||||
|
using Greenshot.Components;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Greenshot.Tests
|
||||||
|
{
|
||||||
|
public class UpdateTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task UpdateTest_GetFeed()
|
||||||
|
{
|
||||||
|
var updateFeed = await new Uri("http://getgreenshot.org/project-feed/").GetAsAsync<SyndicationFeed>();
|
||||||
|
Assert.True(updateFeed.Links.Count >0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void UpdateTest()
|
||||||
|
{
|
||||||
|
var updateService = new UpdateService(null, null);
|
||||||
|
using (var reader = XmlReader.Create(@"TestFiles\project-feed.xml"))
|
||||||
|
{
|
||||||
|
var feed = SyndicationFeed.Load(reader);
|
||||||
|
updateService.ProcessFeed(feed);
|
||||||
|
Assert.Equal(new Version("1.2.10.6"), updateService.LatestVersion);
|
||||||
|
Assert.Equal(new Version("1.3.0.0"), updateService.BetaVersion);
|
||||||
|
Assert.Equal(new Version("1.2.20.99"), updateService.ReleaseCandidateVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,91 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<configuration>
|
|
||||||
<runtime>
|
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-1.2.3.0" newVersion="1.2.3.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.IO.FileSystem" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.IO.FileSystem.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Xml.XPath.XDocument" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Diagnostics.FileVersionInfo" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="Microsoft.DotNet.PlatformAbstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="Microsoft.CodeAnalysis" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-2.8.0.0" newVersion="2.8.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="Microsoft.CodeAnalysis.CSharp" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-2.8.0.0" newVersion="2.8.0.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="xunit.core" publicKeyToken="8d05b1bb7a6fdb6c" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-2.3.1.3858" newVersion="2.3.1.3858" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="xunit.execution.desktop" publicKeyToken="8d05b1bb7a6fdb6c" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-2.3.1.3858" newVersion="2.3.1.3858" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Reflection.Metadata" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-1.4.3.0" newVersion="1.4.3.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="CommonServiceLocator" publicKeyToken="489b6accfaf20ef0" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-2.0.3.0" newVersion="2.0.3.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Reactive.Linq" publicKeyToken="94bc3704cddfc263" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-3.0.3000.0" newVersion="3.0.3000.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Reactive.Core" publicKeyToken="94bc3704cddfc263" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-3.0.3000.0" newVersion="3.0.3000.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.8.1.0" newVersion="4.8.1.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity name="System.Runtime.InteropServices.RuntimeInformation" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</assemblyBinding>
|
|
||||||
</runtime>
|
|
||||||
</configuration>
|
|
|
@ -14,6 +14,7 @@
|
||||||
<package id="Dapplo.Addons.Bootstrapper" version="1.0.47" targetFramework="net46" />
|
<package id="Dapplo.Addons.Bootstrapper" version="1.0.47" targetFramework="net46" />
|
||||||
<package id="Dapplo.CaliburnMicro" version="1.0.46" targetFramework="net46" />
|
<package id="Dapplo.CaliburnMicro" version="1.0.46" targetFramework="net46" />
|
||||||
<package id="Dapplo.CaliburnMicro.Translations" version="1.0.46" targetFramework="net46" />
|
<package id="Dapplo.CaliburnMicro.Translations" version="1.0.46" targetFramework="net46" />
|
||||||
|
<package id="Dapplo.HttpExtensions" version="0.8.35" targetFramework="net46" />
|
||||||
<package id="Dapplo.Ini" version="0.5.28" targetFramework="net46" />
|
<package id="Dapplo.Ini" version="0.5.28" targetFramework="net46" />
|
||||||
<package id="Dapplo.InterfaceImpl" version="0.2.12" targetFramework="net46" />
|
<package id="Dapplo.InterfaceImpl" version="0.2.12" targetFramework="net46" />
|
||||||
<package id="Dapplo.Language" version="0.5.28" targetFramework="net46" />
|
<package id="Dapplo.Language" version="0.5.28" targetFramework="net46" />
|
||||||
|
|
|
@ -36,7 +36,6 @@ namespace Greenshot.Components
|
||||||
|
|
||||||
public static void Capture(string parameters)
|
public static void Capture(string parameters)
|
||||||
{
|
{
|
||||||
|
|
||||||
using (var factory = ChannelFactory)
|
using (var factory = ChannelFactory)
|
||||||
{
|
{
|
||||||
var client = factory.CreateChannel();
|
var client = factory.CreateChannel();
|
||||||
|
|
|
@ -34,6 +34,7 @@ namespace Greenshot.Components
|
||||||
/// Start the forms initialization before the shell is initialized!
|
/// Start the forms initialization before the shell is initialized!
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Forms = CaliburnStartOrder.Shell-1,
|
Forms = CaliburnStartOrder.Shell-1,
|
||||||
|
User = CaliburnStartOrder.User,
|
||||||
Server = CaliburnStartOrder.User + 100,
|
Server = CaliburnStartOrder.User + 100,
|
||||||
Sound = CaliburnStartOrder.User + 200
|
Sound = CaliburnStartOrder.User + 200
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace Greenshot.Components
|
||||||
public enum GreenshotUiStartupOrder
|
public enum GreenshotUiStartupOrder
|
||||||
{
|
{
|
||||||
TrayIcon = 100,
|
TrayIcon = 100,
|
||||||
Plugins = 200,
|
Addons = 200,
|
||||||
Hotkeys = 300
|
Hotkeys = 300
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using Autofac.Features.OwnedInstances;
|
||||||
using Dapplo.Addons;
|
using Dapplo.Addons;
|
||||||
using Dapplo.CaliburnMicro;
|
using Dapplo.CaliburnMicro;
|
||||||
using Dapplo.Log;
|
using Dapplo.Log;
|
||||||
|
@ -45,12 +46,18 @@ namespace Greenshot.Components
|
||||||
private static readonly LogSource Log = new LogSource();
|
private static readonly LogSource Log = new LogSource();
|
||||||
private readonly ICoreConfiguration _coreConfiguration;
|
private readonly ICoreConfiguration _coreConfiguration;
|
||||||
private readonly MainForm _mainForm;
|
private readonly MainForm _mainForm;
|
||||||
|
private readonly Func<Owned<LanguageDialog>> _languageDialogFactory;
|
||||||
private readonly WindowHandle _windowHandle;
|
private readonly WindowHandle _windowHandle;
|
||||||
|
|
||||||
public MainFormStartup(ICoreConfiguration coreConfiguration, MainForm mainForm, WindowHandle windowHandle)
|
public MainFormStartup(
|
||||||
|
ICoreConfiguration coreConfiguration,
|
||||||
|
MainForm mainForm,
|
||||||
|
Func<Owned<LanguageDialog>> languageDialogFactory,
|
||||||
|
WindowHandle windowHandle)
|
||||||
{
|
{
|
||||||
_coreConfiguration = coreConfiguration;
|
_coreConfiguration = coreConfiguration;
|
||||||
_mainForm = mainForm;
|
_mainForm = mainForm;
|
||||||
|
_languageDialogFactory = languageDialogFactory;
|
||||||
_windowHandle = windowHandle;
|
_windowHandle = windowHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,9 +68,11 @@ namespace Greenshot.Components
|
||||||
// if language is not set, show language dialog
|
// if language is not set, show language dialog
|
||||||
if (string.IsNullOrEmpty(_coreConfiguration.Language))
|
if (string.IsNullOrEmpty(_coreConfiguration.Language))
|
||||||
{
|
{
|
||||||
var languageDialog = LanguageDialog.GetInstance();
|
using (var ownedLanguageDialog = _languageDialogFactory())
|
||||||
languageDialog.ShowDialog();
|
{
|
||||||
_coreConfiguration.Language = languageDialog.SelectedLanguage;
|
ownedLanguageDialog.Value.ShowDialog();
|
||||||
|
_coreConfiguration.Language = ownedLanguageDialog.Value.SelectedLanguage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This makes sure the MainForm can initialize, calling show first would create the "Handle" and causing e.g. the DPI Handler to be to late.
|
// This makes sure the MainForm can initialize, calling show first would create the "Handle" and causing e.g. the DPI Handler to be to late.
|
||||||
|
|
233
src/Greenshot/Components/UpdateService.cs
Normal file
233
src/Greenshot/Components/UpdateService.cs
Normal file
|
@ -0,0 +1,233 @@
|
||||||
|
#region Greenshot GNU General Public License
|
||||||
|
|
||||||
|
// Greenshot - a free and open source screenshot tool
|
||||||
|
// Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
|
||||||
|
//
|
||||||
|
// For more information see: http://getgreenshot.org/
|
||||||
|
// The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 1 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Usings
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.ServiceModel.Syndication;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Dapplo.Addons;
|
||||||
|
using Dapplo.CaliburnMicro;
|
||||||
|
using Dapplo.HttpExtensions;
|
||||||
|
using Dapplo.Log;
|
||||||
|
using Dapplo.Utils;
|
||||||
|
using Greenshot.Addons;
|
||||||
|
using Greenshot.Addons.Core;
|
||||||
|
using Greenshot.Forms;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
namespace Greenshot.Components
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This processes the information, if there are updates available.
|
||||||
|
/// </summary>
|
||||||
|
[ServiceOrder(GreenshotStartupOrder.User)]
|
||||||
|
public class UpdateService : IStartup, IShutdown, IVersionProvider
|
||||||
|
{
|
||||||
|
private static readonly LogSource Log = new LogSource();
|
||||||
|
private static readonly Regex VersionRegex = new Regex(@"^.*[^-]-(?<version>[0-9\.]+)\-(?<type>(release|beta|rc[0-9]+))\.exe.*", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
private const string StableDownloadLink = "https://getgreenshot.org/downloads/";
|
||||||
|
private static readonly Uri UpdateFeed = new Uri("http://getgreenshot.org/project-feed/");
|
||||||
|
private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
|
||||||
|
|
||||||
|
private readonly ICoreConfiguration _coreConfiguration;
|
||||||
|
private readonly IGreenshotLanguage _greenshotLanguage;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Version CurrentVersion { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Version LatestVersion { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The latest beta version
|
||||||
|
/// </summary>
|
||||||
|
public Version BetaVersion { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The latest RC version
|
||||||
|
/// </summary>
|
||||||
|
public Version ReleaseCandidateVersion { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool IsUpdateAvailable => LatestVersion > CurrentVersion;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor with dependencies
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="coreConfiguration">ICoreConfiguration</param>
|
||||||
|
/// <param name="greenshotLanguage">IGreenshotLanguage</param>
|
||||||
|
public UpdateService(
|
||||||
|
ICoreConfiguration coreConfiguration,
|
||||||
|
IGreenshotLanguage greenshotLanguage)
|
||||||
|
{
|
||||||
|
_coreConfiguration = coreConfiguration;
|
||||||
|
_greenshotLanguage = greenshotLanguage;
|
||||||
|
LatestVersion = CurrentVersion = GetType().Assembly.GetName().Version;
|
||||||
|
_coreConfiguration.LastSaveWithVersion = CurrentVersion.ToString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
var ignore = BackgroundTask(() => TimeSpan.FromDays(_coreConfiguration.UpdateCheckInterval), UpdateCheck, _cancellationTokenSource.Token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Shutdown()
|
||||||
|
{
|
||||||
|
_cancellationTokenSource.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This runs a periodic task in the background
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="intervalFactory">Func which returns a TimeSpan</param>
|
||||||
|
/// <param name="reoccurringTask">Func which returns a task</param>
|
||||||
|
/// <param name="cancellationToken">CancellationToken</param>
|
||||||
|
/// <returns>Task</returns>
|
||||||
|
private async Task BackgroundTask(Func<TimeSpan> intervalFactory, Func<CancellationToken, Task> reoccurringTask, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
Log.Info().WriteLine("Starting background task");
|
||||||
|
await Task.Run(async () =>
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
var interval = intervalFactory();
|
||||||
|
var task = reoccurringTask;
|
||||||
|
if (TimeSpan.Zero == interval)
|
||||||
|
{
|
||||||
|
interval = TimeSpan.FromMinutes(10);
|
||||||
|
task = c => Task.FromResult(true);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await Task.WhenAll(Task.Delay(interval, cancellationToken), task(cancellationToken));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error().WriteLine(ex, "Error occured when trying to check for updates.");
|
||||||
|
}
|
||||||
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, cancellationToken);
|
||||||
|
Log.Info().WriteLine("Finished background task");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateCheck(CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
Log.Info().WriteLine("Checking for updates");
|
||||||
|
var updateFeed = await UpdateFeed.GetAsAsync<SyndicationFeed>(cancellationToken);
|
||||||
|
if (updateFeed == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_coreConfiguration.LastUpdateCheck = DateTime.Now;
|
||||||
|
|
||||||
|
ProcessFeed(updateFeed);
|
||||||
|
|
||||||
|
if (IsUpdateAvailable)
|
||||||
|
{
|
||||||
|
await UiContext.RunOn(() =>
|
||||||
|
{
|
||||||
|
// TODO: Show update
|
||||||
|
MainForm.Instance.NotifyIcon.BalloonTipClicked += HandleBalloonTipClick;
|
||||||
|
MainForm.Instance.NotifyIcon.BalloonTipClosed += CleanupBalloonTipClick;
|
||||||
|
MainForm.Instance.NotifyIcon.ShowBalloonTip(10000, "Greenshot", string.Format(_greenshotLanguage.UpdateFound, LatestVersion), ToolTipIcon.Info);
|
||||||
|
}, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Process the update feed to get the latest version
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="updateFeed"></param>
|
||||||
|
public void ProcessFeed(SyndicationFeed updateFeed)
|
||||||
|
{
|
||||||
|
var versions =
|
||||||
|
from link in updateFeed.Items.SelectMany(i => i.Links)
|
||||||
|
select VersionRegex.Match(link.Uri.AbsoluteUri) into match
|
||||||
|
where match.Success
|
||||||
|
group match by Regex.Replace(match.Groups["type"].Value, @"[\d-]", string.Empty) into groupedVersions
|
||||||
|
select groupedVersions.OrderByDescending(m => new Version(m.Groups["version"].Value)).First();
|
||||||
|
|
||||||
|
foreach (var versionMatch in versions)
|
||||||
|
{
|
||||||
|
var version = new Version(versionMatch.Groups["version"].Value);
|
||||||
|
var type = versionMatch.Groups["type"].Value;
|
||||||
|
if (string.IsNullOrEmpty(type))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Log.Debug().WriteLine("Got {0} {1}", type, version);
|
||||||
|
if ("release".Equals(type, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
LatestVersion = version;
|
||||||
|
}
|
||||||
|
if ("beta".Equals(type, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
BetaVersion = version;
|
||||||
|
}
|
||||||
|
if ("rc".Equals(type, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
ReleaseCandidateVersion = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CleanupBalloonTipClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
MainForm.Instance.NotifyIcon.BalloonTipClicked -= HandleBalloonTipClick;
|
||||||
|
MainForm.Instance.NotifyIcon.BalloonTipClosed -= CleanupBalloonTipClick;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleBalloonTipClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// "Direct" download link
|
||||||
|
// Process.Start(latestGreenshot.Link);
|
||||||
|
// Go to getgreenshot.org
|
||||||
|
Process.Start(StableDownloadLink);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
MessageBox.Show(string.Format(_greenshotLanguage.ErrorOpenlink, StableDownloadLink), _greenshotLanguage.Error);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
CleanupBalloonTipClick(sender, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,11 +28,11 @@ using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Printing;
|
using System.Drawing.Printing;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using Autofac.Features.OwnedInstances;
|
||||||
using Greenshot.Addons;
|
using Greenshot.Addons;
|
||||||
using Greenshot.Addons.Components;
|
using Greenshot.Addons.Components;
|
||||||
using Greenshot.Addons.Core;
|
using Greenshot.Addons.Core;
|
||||||
using Greenshot.Addons.Interfaces;
|
using Greenshot.Addons.Interfaces;
|
||||||
using Greenshot.Configuration;
|
|
||||||
using Greenshot.Helpers;
|
using Greenshot.Helpers;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -46,19 +46,23 @@ namespace Greenshot.Destinations
|
||||||
public class PrinterDestination : AbstractDestination
|
public class PrinterDestination : AbstractDestination
|
||||||
{
|
{
|
||||||
private readonly IGreenshotLanguage _greenshotLanguage;
|
private readonly IGreenshotLanguage _greenshotLanguage;
|
||||||
|
private readonly Func<ISurface, ICaptureDetails, Owned<PrintHelper>> _printHelperFactory;
|
||||||
private readonly string _printerName;
|
private readonly string _printerName;
|
||||||
|
|
||||||
public PrinterDestination(ICoreConfiguration coreConfiguration,
|
public PrinterDestination(ICoreConfiguration coreConfiguration,
|
||||||
IGreenshotLanguage greenshotLanguage
|
IGreenshotLanguage greenshotLanguage,
|
||||||
): base(coreConfiguration, greenshotLanguage)
|
Func<ISurface, ICaptureDetails, Owned<PrintHelper>> printHelperFactory
|
||||||
|
) : base(coreConfiguration, greenshotLanguage)
|
||||||
{
|
{
|
||||||
_greenshotLanguage = greenshotLanguage;
|
_greenshotLanguage = greenshotLanguage;
|
||||||
|
_printHelperFactory = printHelperFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PrinterDestination(
|
protected PrinterDestination(
|
||||||
ICoreConfiguration coreConfiguration,
|
ICoreConfiguration coreConfiguration,
|
||||||
IGreenshotLanguage greenshotLanguage,
|
IGreenshotLanguage greenshotLanguage,
|
||||||
string printerName) : this(coreConfiguration, greenshotLanguage)
|
Func<ISurface, ICaptureDetails, Owned<PrintHelper>> printHelperFactory,
|
||||||
|
string printerName) : this(coreConfiguration, greenshotLanguage, printHelperFactory)
|
||||||
{
|
{
|
||||||
_printerName = printerName;
|
_printerName = printerName;
|
||||||
}
|
}
|
||||||
|
@ -110,7 +114,7 @@ namespace Greenshot.Destinations
|
||||||
});
|
});
|
||||||
foreach (var printer in printers)
|
foreach (var printer in printers)
|
||||||
{
|
{
|
||||||
yield return new PrinterDestination(CoreConfiguration, GreenshotLanguage, printer);
|
yield return new PrinterDestination(CoreConfiguration, GreenshotLanguage, _printHelperFactory, printer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,24 +131,25 @@ namespace Greenshot.Destinations
|
||||||
PrinterSettings printerSettings;
|
PrinterSettings printerSettings;
|
||||||
if (!string.IsNullOrEmpty(_printerName))
|
if (!string.IsNullOrEmpty(_printerName))
|
||||||
{
|
{
|
||||||
using (var printHelper = new PrintHelper(CoreConfiguration, GreenshotLanguage,surface, captureDetails))
|
using (var ownedPrintHelper = _printHelperFactory(surface, captureDetails))
|
||||||
{
|
{
|
||||||
printerSettings = printHelper.PrintTo(_printerName);
|
printerSettings = ownedPrintHelper.Value.PrintTo(_printerName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!manuallyInitiated)
|
else if (!manuallyInitiated)
|
||||||
{
|
{
|
||||||
var settings = new PrinterSettings();
|
var settings = new PrinterSettings();
|
||||||
using (var printHelper = new PrintHelper(CoreConfiguration, GreenshotLanguage, surface, captureDetails))
|
|
||||||
|
using (var ownedPrintHelper = _printHelperFactory(surface, captureDetails))
|
||||||
{
|
{
|
||||||
printerSettings = printHelper.PrintTo(settings.PrinterName);
|
printerSettings = ownedPrintHelper.Value.PrintTo(settings.PrinterName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
using (var printHelper = new PrintHelper(CoreConfiguration, GreenshotLanguage, surface, captureDetails))
|
using (var ownedPrintHelper = _printHelperFactory(surface, captureDetails))
|
||||||
{
|
{
|
||||||
printerSettings = printHelper.PrintWithDialog();
|
printerSettings = ownedPrintHelper.Value.PrintWithDialog();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (printerSettings != null)
|
if (printerSettings != null)
|
||||||
|
|
|
@ -41,7 +41,6 @@ namespace Greenshot.Forms
|
||||||
public partial class LanguageDialog : Form
|
public partial class LanguageDialog : Form
|
||||||
{
|
{
|
||||||
private static readonly LogSource Log = new LogSource();
|
private static readonly LogSource Log = new LogSource();
|
||||||
private static LanguageDialog _uniqueInstance;
|
|
||||||
private bool _properOkPressed;
|
private bool _properOkPressed;
|
||||||
|
|
||||||
private LanguageDialog()
|
private LanguageDialog()
|
||||||
|
@ -108,10 +107,5 @@ namespace Greenshot.Forms
|
||||||
Language.CurrentLanguage = SelectedLanguage;
|
Language.CurrentLanguage = SelectedLanguage;
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LanguageDialog GetInstance()
|
|
||||||
{
|
|
||||||
return _uniqueInstance ?? (_uniqueInstance = new LanguageDialog());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -74,11 +74,11 @@ namespace Greenshot.Forms
|
||||||
private static readonly LogSource Log = new LogSource();
|
private static readonly LogSource Log = new LogSource();
|
||||||
private readonly ICoreConfiguration _coreConfiguration;
|
private readonly ICoreConfiguration _coreConfiguration;
|
||||||
private readonly IWindowManager _windowManager;
|
private readonly IWindowManager _windowManager;
|
||||||
private readonly ConfigViewModel _configViewModel;
|
private readonly Func<Owned<ConfigViewModel>> _configViewModelFactory;
|
||||||
|
private readonly Func<Owned<AboutForm>> _aboutFormFactory;
|
||||||
|
|
||||||
// Timer for the double click test
|
// Timer for the double click test
|
||||||
private readonly Timer _doubleClickTimer = new Timer();
|
private readonly Timer _doubleClickTimer = new Timer();
|
||||||
private readonly Func<Owned<AboutForm>> _aboutFormFactory;
|
|
||||||
|
|
||||||
private readonly DestinationHolder _destinationHolder;
|
private readonly DestinationHolder _destinationHolder;
|
||||||
// Thumbnail preview
|
// Thumbnail preview
|
||||||
|
@ -89,13 +89,13 @@ namespace Greenshot.Forms
|
||||||
public MainForm(ICoreConfiguration coreConfiguration,
|
public MainForm(ICoreConfiguration coreConfiguration,
|
||||||
IWindowManager windowManager,
|
IWindowManager windowManager,
|
||||||
IGreenshotLanguage greenshotLanguage,
|
IGreenshotLanguage greenshotLanguage,
|
||||||
ConfigViewModel configViewModel,
|
Func<Owned<ConfigViewModel>> configViewModelFactory,
|
||||||
Func<Owned<AboutForm>> aboutFormFactory,
|
Func<Owned<AboutForm>> aboutFormFactory,
|
||||||
DestinationHolder destinationHolder) : base(greenshotLanguage)
|
DestinationHolder destinationHolder) : base(greenshotLanguage)
|
||||||
{
|
{
|
||||||
_coreConfiguration = coreConfiguration;
|
_coreConfiguration = coreConfiguration;
|
||||||
_windowManager = windowManager;
|
_windowManager = windowManager;
|
||||||
_configViewModel = configViewModel;
|
_configViewModelFactory = configViewModelFactory;
|
||||||
_aboutFormFactory = aboutFormFactory;
|
_aboutFormFactory = aboutFormFactory;
|
||||||
_destinationHolder = destinationHolder;
|
_destinationHolder = destinationHolder;
|
||||||
Instance = this;
|
Instance = this;
|
||||||
|
@ -365,17 +365,7 @@ namespace Greenshot.Forms
|
||||||
{
|
{
|
||||||
PsApi.EmptyWorkingSet();
|
PsApi.EmptyWorkingSet();
|
||||||
}
|
}
|
||||||
if (UpdateHelper.IsUpdateCheckNeeded())
|
|
||||||
{
|
|
||||||
Log.Debug().WriteLine("BackgroundWorkerTimerTick checking for update");
|
|
||||||
// Start update check in the background
|
|
||||||
var backgroundTask = new Thread(UpdateHelper.CheckAndAskForUpdate)
|
|
||||||
{
|
|
||||||
Name = "Update check",
|
|
||||||
IsBackground = true
|
|
||||||
};
|
|
||||||
backgroundTask.Start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -841,10 +831,9 @@ namespace Greenshot.Forms
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ShowSetting()
|
public void ShowSetting()
|
||||||
{
|
{
|
||||||
// The new MVVM Configuration
|
using(var ownedConfigViewModel = _configViewModelFactory())
|
||||||
if (!_configViewModel.IsActive)
|
|
||||||
{
|
{
|
||||||
_windowManager.ShowDialog(_configViewModel);
|
_windowManager.ShowDialog(ownedConfigViewModel.Value);
|
||||||
}
|
}
|
||||||
InitializeQuickSettingsMenu();
|
InitializeQuickSettingsMenu();
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,7 +289,7 @@
|
||||||
<Compile Include="Help\HelpFileLoader.cs" />
|
<Compile Include="Help\HelpFileLoader.cs" />
|
||||||
<Compile Include="Processors\TitleFixProcessor.cs" />
|
<Compile Include="Processors\TitleFixProcessor.cs" />
|
||||||
<Compile Include="Helpers\WindowWrapper.cs" />
|
<Compile Include="Helpers\WindowWrapper.cs" />
|
||||||
<Compile Include="Helpers\UpdateHelper.cs" />
|
<Compile Include="Components\UpdateService.cs" />
|
||||||
<Compile Include="Helpers\EnvironmentInfo.cs" />
|
<Compile Include="Helpers\EnvironmentInfo.cs" />
|
||||||
<Compile Include="Helpers\MailHelper.cs" />
|
<Compile Include="Helpers\MailHelper.cs" />
|
||||||
<Compile Include="Helpers\PrintHelper.cs" />
|
<Compile Include="Helpers\PrintHelper.cs" />
|
||||||
|
|
|
@ -29,6 +29,7 @@ using Dapplo.CaliburnMicro.Security;
|
||||||
using Greenshot.Addons.Components;
|
using Greenshot.Addons.Components;
|
||||||
using Greenshot.Components;
|
using Greenshot.Components;
|
||||||
using Greenshot.Forms;
|
using Greenshot.Forms;
|
||||||
|
using Greenshot.Helpers;
|
||||||
using Greenshot.Ui.Configuration.ViewModels;
|
using Greenshot.Ui.Configuration.ViewModels;
|
||||||
using Greenshot.Ui.Misc.ViewModels;
|
using Greenshot.Ui.Misc.ViewModels;
|
||||||
|
|
||||||
|
@ -41,8 +42,8 @@ namespace Greenshot
|
||||||
{
|
{
|
||||||
builder
|
builder
|
||||||
.RegisterType<ConfigViewModel>()
|
.RegisterType<ConfigViewModel>()
|
||||||
.AsSelf()
|
.AsSelf();
|
||||||
.SingleInstance();
|
|
||||||
builder
|
builder
|
||||||
.RegisterType<AuthenticationProvider>()
|
.RegisterType<AuthenticationProvider>()
|
||||||
.As<IAuthenticationProvider>()
|
.As<IAuthenticationProvider>()
|
||||||
|
@ -53,6 +54,18 @@ namespace Greenshot
|
||||||
.AsSelf()
|
.AsSelf()
|
||||||
.SingleInstance();
|
.SingleInstance();
|
||||||
|
|
||||||
|
builder
|
||||||
|
.RegisterType<PrintHelper>()
|
||||||
|
.AsSelf();
|
||||||
|
|
||||||
|
builder
|
||||||
|
.RegisterType<PrintOptionsDialog>()
|
||||||
|
.AsSelf();
|
||||||
|
|
||||||
|
builder
|
||||||
|
.RegisterType<LanguageDialog>()
|
||||||
|
.AsSelf();
|
||||||
|
|
||||||
builder
|
builder
|
||||||
.RegisterType<HotkeyHandler>()
|
.RegisterType<HotkeyHandler>()
|
||||||
.As<IUiStartup>()
|
.As<IUiStartup>()
|
||||||
|
|
|
@ -27,6 +27,7 @@ using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Printing;
|
using System.Drawing.Printing;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using Autofac.Features.OwnedInstances;
|
||||||
using Greenshot.Forms;
|
using Greenshot.Forms;
|
||||||
using Dapplo.Log;
|
using Dapplo.Log;
|
||||||
using Dapplo.Windows.Common.Extensions;
|
using Dapplo.Windows.Common.Extensions;
|
||||||
|
@ -52,6 +53,7 @@ namespace Greenshot.Helpers
|
||||||
private static readonly LogSource Log = new LogSource();
|
private static readonly LogSource Log = new LogSource();
|
||||||
private readonly ICoreConfiguration _coreConfig;
|
private readonly ICoreConfiguration _coreConfig;
|
||||||
private readonly IGreenshotLanguage _greenshotLanguage;
|
private readonly IGreenshotLanguage _greenshotLanguage;
|
||||||
|
private readonly Func<Owned<PrintOptionsDialog>> _printOptionsDialogFactory;
|
||||||
private readonly ICaptureDetails _captureDetails;
|
private readonly ICaptureDetails _captureDetails;
|
||||||
private PrintDialog _printDialog = new PrintDialog();
|
private PrintDialog _printDialog = new PrintDialog();
|
||||||
private PrintDocument _printDocument = new PrintDocument();
|
private PrintDocument _printDocument = new PrintDocument();
|
||||||
|
@ -61,11 +63,13 @@ namespace Greenshot.Helpers
|
||||||
public PrintHelper(
|
public PrintHelper(
|
||||||
ICoreConfiguration coreConfiguration,
|
ICoreConfiguration coreConfiguration,
|
||||||
IGreenshotLanguage greenshotLanguage,
|
IGreenshotLanguage greenshotLanguage,
|
||||||
|
Func<Owned<PrintOptionsDialog>> printOptionsDialogFactory,
|
||||||
ISurface surface,
|
ISurface surface,
|
||||||
ICaptureDetails captureDetails)
|
ICaptureDetails captureDetails)
|
||||||
{
|
{
|
||||||
_coreConfig = coreConfiguration;
|
_coreConfig = coreConfiguration;
|
||||||
_greenshotLanguage = greenshotLanguage;
|
_greenshotLanguage = greenshotLanguage;
|
||||||
|
_printOptionsDialogFactory = printOptionsDialogFactory;
|
||||||
|
|
||||||
_surface = surface;
|
_surface = surface;
|
||||||
_captureDetails = captureDetails;
|
_captureDetails = captureDetails;
|
||||||
|
@ -83,16 +87,6 @@ namespace Greenshot.Helpers
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor
|
|
||||||
*/
|
|
||||||
|
|
||||||
~PrintHelper()
|
|
||||||
{
|
|
||||||
Dispose(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -149,9 +143,11 @@ namespace Greenshot.Helpers
|
||||||
/// <returns>printer settings if actually printed, or null if print was cancelled or has failed</returns>
|
/// <returns>printer settings if actually printed, or null if print was cancelled or has failed</returns>
|
||||||
public PrinterSettings PrintWithDialog()
|
public PrinterSettings PrintWithDialog()
|
||||||
{
|
{
|
||||||
PrinterSettings returnPrinterSettings = null;
|
if (_printDialog.ShowDialog() != DialogResult.OK)
|
||||||
if (_printDialog.ShowDialog() == DialogResult.OK)
|
|
||||||
{
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
PrinterSettings returnPrinterSettings = null;
|
||||||
var printOptionsResult = ShowPrintOptionsDialog();
|
var printOptionsResult = ShowPrintOptionsDialog();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -170,7 +166,6 @@ namespace Greenshot.Helpers
|
||||||
Log.Error().WriteLine(e, "An error ocurred while trying to print");
|
Log.Error().WriteLine(e, "An error ocurred while trying to print");
|
||||||
MessageBox.Show(Language.GetString(LangKey.print_error), Language.GetString(LangKey.error));
|
MessageBox.Show(Language.GetString(LangKey.print_error), Language.GetString(LangKey.error));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return returnPrinterSettings;
|
return returnPrinterSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,9 +185,9 @@ namespace Greenshot.Helpers
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var printOptionsDialog = new PrintOptionsDialog(_coreConfig, _greenshotLanguage))
|
using (var ownedPrintOptionsDialog = _printOptionsDialogFactory())
|
||||||
{
|
{
|
||||||
return printOptionsDialog.ShowDialog();
|
return ownedPrintOptionsDialog.Value.ShowDialog();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,223 +0,0 @@
|
||||||
#region Greenshot GNU General Public License
|
|
||||||
|
|
||||||
// Greenshot - a free and open source screenshot tool
|
|
||||||
// Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
|
|
||||||
//
|
|
||||||
// For more information see: http://getgreenshot.org/
|
|
||||||
// The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 1 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Usings
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
using Dapplo.Ini;
|
|
||||||
using Dapplo.Log;
|
|
||||||
using Greenshot.Addons.Core;
|
|
||||||
using Greenshot.Addons.Core.Enums;
|
|
||||||
using Greenshot.Configuration;
|
|
||||||
using Greenshot.Forms;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
namespace Greenshot.Helpers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Description of RssFeedHelper.
|
|
||||||
/// </summary>
|
|
||||||
public static class UpdateHelper
|
|
||||||
{
|
|
||||||
private const string StableDownloadLink = "https://getgreenshot.org/downloads/";
|
|
||||||
private const string VersionHistoryLink = "https://getgreenshot.org/version-history/";
|
|
||||||
private static readonly LogSource Log = new LogSource();
|
|
||||||
private static readonly ICoreConfiguration CoreConfig = IniConfig.Current.Get<ICoreConfiguration>();
|
|
||||||
private static readonly object LockObject = new object();
|
|
||||||
private static RssFile _latestGreenshot;
|
|
||||||
private static string _downloadLink = StableDownloadLink;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Is an update check needed?
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>bool true if yes</returns>
|
|
||||||
public static bool IsUpdateCheckNeeded()
|
|
||||||
{
|
|
||||||
lock (LockObject)
|
|
||||||
{
|
|
||||||
if (CoreConfig.UpdateCheckInterval == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
var checkTime = CoreConfig.LastUpdateCheck;
|
|
||||||
checkTime = checkTime.AddDays(CoreConfig.UpdateCheckInterval);
|
|
||||||
if (DateTime.Now.CompareTo(checkTime) < 0)
|
|
||||||
{
|
|
||||||
Log.Debug().WriteLine("No need to check RSS feed for updates, feed check will be after {0}", checkTime);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Log.Debug().WriteLine("Update check is due, last check was {0} check needs to be made after {1} (which is one {2} later)", CoreConfig.LastUpdateCheck, checkTime,
|
|
||||||
CoreConfig.UpdateCheckInterval);
|
|
||||||
if (!RssHelper.IsRssModifiedAfter(CoreConfig.LastUpdateCheck))
|
|
||||||
{
|
|
||||||
Log.Debug().WriteLine("RSS feed has not been updated since after {0}", CoreConfig.LastUpdateCheck);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Read the RSS feed to see if there is a Greenshot update
|
|
||||||
/// </summary>
|
|
||||||
public static void CheckAndAskForUpdate()
|
|
||||||
{
|
|
||||||
lock (LockObject)
|
|
||||||
{
|
|
||||||
var currentVersion = Assembly.GetExecutingAssembly().GetName().Version;
|
|
||||||
// Test like this:
|
|
||||||
// currentVersion = new Version("0.8.1.1198");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_latestGreenshot = null;
|
|
||||||
ProcessRssInfo(currentVersion);
|
|
||||||
if (_latestGreenshot != null)
|
|
||||||
{
|
|
||||||
MainForm.Instance.NotifyIcon.BalloonTipClicked += HandleBalloonTipClick;
|
|
||||||
MainForm.Instance.NotifyIcon.BalloonTipClosed += CleanupBalloonTipClick;
|
|
||||||
MainForm.Instance.NotifyIcon.ShowBalloonTip(10000, "Greenshot", Language.GetFormattedString(LangKey.update_found, "'" + _latestGreenshot.File + "'"),
|
|
||||||
ToolTipIcon.Info);
|
|
||||||
}
|
|
||||||
CoreConfig.LastUpdateCheck = DateTime.Now;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Log.Error().WriteLine(e, "An error occured while checking for updates, the error will be ignored: ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void CleanupBalloonTipClick(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
MainForm.Instance.NotifyIcon.BalloonTipClicked -= HandleBalloonTipClick;
|
|
||||||
MainForm.Instance.NotifyIcon.BalloonTipClosed -= CleanupBalloonTipClick;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void HandleBalloonTipClick(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_latestGreenshot != null)
|
|
||||||
{
|
|
||||||
// "Direct" download link
|
|
||||||
// Process.Start(latestGreenshot.Link);
|
|
||||||
// Go to getgreenshot.org
|
|
||||||
Process.Start(_downloadLink);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
MessageBox.Show(Language.GetFormattedString(LangKey.error_openlink, _downloadLink), Language.GetString(LangKey.error));
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
CleanupBalloonTipClick(sender, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ProcessRssInfo(Version currentVersion)
|
|
||||||
{
|
|
||||||
// Reset latest Greenshot
|
|
||||||
var rssFiles = RssHelper.ReadRss();
|
|
||||||
|
|
||||||
if (rssFiles == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve the current and latest greenshot
|
|
||||||
foreach (var rssFile in rssFiles)
|
|
||||||
{
|
|
||||||
if (rssFile.File.StartsWith("Greenshot"))
|
|
||||||
{
|
|
||||||
// check for exe
|
|
||||||
if (!rssFile.IsExe)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// do we have a version?
|
|
||||||
if (rssFile.Version == null)
|
|
||||||
{
|
|
||||||
Log.Debug().WriteLine("Skipping unversioned exe {0} which is published at {1} : {2}", rssFile.File, rssFile.Pubdate.ToLocalTime(), rssFile.Link);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the file is unstable, we will skip it when:
|
|
||||||
// the current version is a release or release candidate AND check unstable is turned off.
|
|
||||||
if (rssFile.IsAlpha)
|
|
||||||
{
|
|
||||||
// Skip if we shouldn't check unstables
|
|
||||||
if (CoreConfigurationExtensions.BuildState == BuildStates.RELEASE && !CoreConfig.CheckForUnstable)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the file is a release candidate, we will skip it when:
|
|
||||||
// the current version is a release AND check unstable is turned off.
|
|
||||||
if (rssFile.IsReleaseCandidate)
|
|
||||||
{
|
|
||||||
if (CoreConfigurationExtensions.BuildState == BuildStates.RELEASE && !CoreConfig.CheckForUnstable)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare versions
|
|
||||||
var versionCompare = rssFile.Version.CompareTo(currentVersion);
|
|
||||||
if (versionCompare > 0)
|
|
||||||
{
|
|
||||||
Log.Debug().WriteLine("Found newer Greenshot '{0}' with version {1} published at {2} : {3}", rssFile.File, rssFile.Version, rssFile.Pubdate.ToLocalTime(), rssFile.Link);
|
|
||||||
if (_latestGreenshot == null || rssFile.Version.CompareTo(_latestGreenshot.Version) > 0)
|
|
||||||
{
|
|
||||||
_latestGreenshot = rssFile;
|
|
||||||
if (rssFile.IsReleaseCandidate || rssFile.IsAlpha)
|
|
||||||
{
|
|
||||||
_downloadLink = VersionHistoryLink;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_downloadLink = StableDownloadLink;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (versionCompare < 0)
|
|
||||||
{
|
|
||||||
Log.Debug().WriteLine("Skipping older greenshot with version {0}", rssFile.Version);
|
|
||||||
}
|
|
||||||
else if (versionCompare == 0)
|
|
||||||
{
|
|
||||||
Log.Debug().WriteLine("Found current version as exe {0} with version {1} published at {2} : {3}", rssFile.File, rssFile.Version, rssFile.Pubdate.ToLocalTime(),
|
|
||||||
rssFile.Link);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue