NetSparkleUpdater / NetSparkle

NetSparkle is a C#, cross-platform, highly-configurable software update framework with pre-built UI for .NET developers compatible with .NET 4.6.2/.NET 6+, WinForms, WPF, and Avalonia; uses Ed25519 signatures. View basic usage here in the README and try the samples for yourself.
https://netsparkleupdater.github.io/NetSparkle/
MIT License
606 stars 84 forks source link

Unable to render pages properly using NetSparkle.UI.WPF or custom UI #457

Closed huangkai1994 closed 1 year ago

huangkai1994 commented 1 year ago

I used the ui frameworkWPF UI,When I click the download/install button,An exception is thrown immediately System.Windows.Markup.XamlParseException:““初始化“Wpf.Ui.Controls.Button”时引发了异常。”,行号为“80”,行位置为“33”。” InvalidOperationException: 无法在各进程之间访问可冻结的“System.Windows.Media.SolidColorBrush”,因为无法冻结它。 I know this is a conflict with my UI framework, but I don't have the ability to solve this problem, who can help me? Otherwise I would have to use NetSparkle.UI.winform

Deadpikle commented 1 year ago

Hi @huangkai1994,

Actually, I think based on that exception, this should be fixable. Instead of using the WPF UI, link your application to the main NetSparkleUpdater repository. Then, copy in the WPF UI files (as a base) and adjust them as necessary to compile and work with your UI library that you're using. Then you can just reference that UI factory instead of the WPF one.

I do something similar in one of my own proprietary applications where I just needed to tweak the UI a bit for that app's use case, where I just copied in the files from this repository into my own project and then tweaked as needed:

Screen Shot 2023-05-31 at 2 07 17 PM

That being said, um, looks like some brush just needs to be frozen somewhere in the main framework OR you shouldn't run WPF on the backend thread. Try setting ShowsUIOnMainThread to true.

Another thing that would help in solving this is a reproducible test case.

Thanks!

huangkai1994 commented 1 year ago

Now I can solve my problem By set ShowsUIOnMainThread = true。 I found a new problem in ReleaseNotesGrabber class DownloadReleaseNotes method,Garbled characters are returned when the file content is in Chinese,Although I could copy the source code and add HttpClientHandler to HttpClient to solve the problem, this would not be the best solution

Deadpikle commented 1 year ago

The original problem is because of https://github.com/lepoco/wpfui/issues/594.

ReleaseNotesGrabber: Don't copy the whole source code. You can just create your own ReleaseNotesGrabber subclass to pull things as UTF-8. Something like:

public class MyReleaseNotesGrabber : ReleaseNotesGrabber
    {
        public MyReleaseNotesGrabber(string releaseNotesTemplate, string htmlHeadAddition, SparkleUpdater sparkle) : base(releaseNotesTemplate, htmlHeadAddition, sparkle)
        {
        }

        protected override async Task<string> DownloadReleaseNotes(string link, CancellationToken cancellationToken, SparkleUpdater sparkle)
        {
            try
            {

                var httpClient = CreateHttpClient();
                using (cancellationToken.Register(() => httpClient.CancelPendingRequests()))
                {
                    using (HttpResponseMessage response = await httpClient.GetAsync(link))
                    {
                        var byteArray = await response.Content.ReadAsByteArrayAsync();
                        var result = Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);
                        return result;
                    }
                }
            }
            catch (WebException ex)
            {
                sparkle.LogWriter.PrintMessage("Cannot download release notes from {0} because {1}", link, ex.Message);
                return "";
            }
        }
    }

// ...

var uiFactory = new NetSparkleUpdater.UI.WPF.UIFactory(...);
_sparkle = new SparkleUpdater("...", new DSAChecker(Enums.SecurityMode.Strict))
{
    ShowsUIOnMainThread = true,
};
uiFactory.ReleaseNotesGrabberOverride = new MyReleaseNotesGrabber(uiFactory.ReleaseNotesHTMLTemplate, uiFactory.AdditionalReleaseNotesHeaderHTML, _sparkle);
_sparkle.UIFactory = uiFactory;
// ...
_sparkle.StartLoop(true, true);
huangkai1994 commented 1 year ago

Thank you. That solves my problem

Deadpikle commented 1 year ago

Great! Glad to hear. :)