derskythe / WpfSettings

MIT License
27 stars 5 forks source link

Silent Updating in Net 6 #4

Closed jonrmorgan99 closed 7 months ago

jonrmorgan99 commented 2 years ago

I recently ported my Net5 implementation of the ClickOnce updater to Net6.

It works fine but setup.exe still shows it's update window during an update. The problem is in this method:

private static Process OpenUrl(string url)
    {
        try
        {
                 var info = new ProcessStartInfo(url)
            {
                CreateNoWindow = true,
                WindowStyle = ProcessWindowStyle.Hidden,
                RedirectStandardInput = true,
                RedirectStandardOutput = false,
                UseShellExecute = false
            };
            var proc = Process.Start(info);

            IntPtr tHwnd=IntPtr.Zero;

            for(int j=0;j<10;j++)
            {
                tHwnd = proc.MainWindowHandle;
                if(tHwnd != IntPtr.Zero) { break; }
                Thread.Sleep(100);
            }
            if (tHwnd !=IntPtr.Zero)
            {
                ShowWindow(tHwnd, ShowWindowCommand.Minimize);
                ShowWindow(tHwnd, ShowWindowCommand.Hide);
            }
            else
            {
                LocalMdiMessageHandlers.ShowStatus("Unable to close process window  " + tHwnd, 3000);
            }

            return proc;
        }
        catch (Exception ex)
        {
            LocalMdiMessageHandlers.ShowStatus("Using Hack: " + ex.Message, 2000);

            // hack because of this: https://github.com/dotnet/corefx/issues/10361
            url = url.Replace("&", "^&");
            return Process.Start(new ProcessStartInfo("cmd", $"/c start {url}")
            {
                CreateNoWindow = true,
                WindowStyle = ProcessWindowStyle.Hidden,
                RedirectStandardInput = true,
                RedirectStandardOutput = false,
                UseShellExecute = false,
            }
            );
        }
    }

I've tried various combinations of ProcessStartInfo parameters to hide the window but none work. I also added code to hide the window using P/Invoke ShowWindow but, again no luck.

I suspect the reason neither of these approaches works is because the download progress window is a child of the setup.exe process, but I can't work out how to target the child windows.

It looks unlikely MS will restore ApplicationDeployment API at least until Net7 so it's worth persisting with this issue so we can have a fully silent ClickOnce updater again.

derskythe commented 1 year ago

Returning to this question. Right now I don't see new features of .NET 7 and 8, but there doesn't seem to be much progress. With P/Invoke ShowWindow, yes I am also thinking about it. Anyway in a couple of weeks I will start doing a project on this topic and maybe come back here with new results.

jonrmorgan99 commented 1 year ago

@derskythe Yes, it looks unlikely MS will fully re-implement the ApplicationDeployment methods for in-app silent updating in Net 8 although they are certainly aware of the need.

Thanks to your original code I published my apps in Net7 and, apart from the download window showing, it all works fine.

Fully silent updating would of course need replacement for the download progress notifications as in MS' original code example

Good luck with your project - look forward to hearing more.