-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BrowserSubprocess - Update shutdown priority (SetProcessShutdownParameters) #3155
Comments
Generally speaking there has been some refactoring lately, nothing that I can think of that would influence this. The default https://github.com/cefsharp/CefSharp/blob/cefsharp/83/CefSharp.BrowserSubprocess.Core/BrowserSubprocessExecutable.h#L110 Is you application closing itself as expected???
What testing have you done to confirm this exactly? Have you tried packaging the |
Our testing was comparing CefSharp 73 with CefSharp 81. With Cef sharp 73 MSI installer shows a dialog with the processes it needs to close in order to complete the installation. v73 doesn't list BrowserSubprocess in this list. With v81 BrowserSubprocess is part of this list and it is first. I suspect MSI is sending shutdown signals or trying to kill BrowserSubprocess unsuccessfully. Probably MSI is trying to close the processes sequentially and since BrowserSubprocess is the first in the list and it can't close it it won't get to the actual app process that BrowserSubprocess is child to. I am looking for a change in the code where BrowserSubprocess was registered as child process to the main app process. |
I'd still suggest trying to package the cefclient sample application, you may need to go digging through the CEF/chromium source if the behaviour reproduces. You can compare the source history for the CefSharp.BrowserSubprocess.Core and CefSharp.BrowserSubprocess projects. There's nothing I can think of that would be influencing the behaviour from a CefSharp point of view. |
You can probably include the cefclient.exe from the matching CEF distribution and use that as the browsersubprocess for a simpler test, you'll only be able to do basic browsing, that should be sufficient for testing purposes. |
Will try that. |
This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further. |
We recently realized this happens with our application and installer as well. From what I can gather, the installer asks Windows to shut down the application so it can update the assembly files. Windows uses the Restart Manager to query and instruct applications to close. According to the documentation, it will
Since the shutdown request seems to be canceled (step 1.a), that would lead me to believe that someone is returning false when they receive the WM_QUERYENDSESSION message. (However, I can't find anywhere in Cef or CefSharp's code that it is doing that) If we don't create a ChromiumBrowser or initialize CefSharp, then our application will receive and respond appropriately to the messages. However, once Cef has been initialized, we no longer receive those particular messages, even though we continue receiving other standard window messages I've been trying to fix this for a day and a half, and have gotten no closer to fixing it, other than gaining better knowledge on how it is supposed to work. CEF4Delphi looks to have had a similar problem, but I wasn't able to get anything useful from their solution. I added a window message handler in ChromiumWebBrowser to receive the WM_QUERYENDSESSION and WM_ENDSESSION messages, but after testing and still not receiving the messages, I realized that I was just attaching to the event on the same window handle as my main application, so of course I wouldn't see anything different. (Also, I don't like their solution because it forces their application to close when receiving the WM_QUERYENDSESSION message, when it should really do it when it receives the WM_ENDSESSION message. I apologize for the dump of information, if you have any ideas or questions, feel free to voice them. |
Sorry for intruding in this project. The solution in CEF4Delphi was this : Chromium also calls SetProcessShutdownParameters : |
@salvadordf Thanks, greatly appreciated. If I understand correctly for the sub processes we should call SetProcessShutdownParameters with a low value.
Looking through the //For crashpad
if (!SetProcessShutdownParameters(0x100, SHUTDOWN_NORETRY))
PLOG(ERROR) << "SetProcessShutdownParameters";
//For all others
//The browser uses the default shutdown order, which is 0x280.
const int kNonBrowserShutdownPriority = 0x280;
::SetProcessShutdownParameters(kNonBrowserShutdownPriority - 1,
SHUTDOWN_NORETRY); @salvadordf Is using |
Based on the comment in the |
@amaitland The current 0x100 value works fine but any value lower than the default should also work. I guess Chromium developers wanted to be sure the crashpad is closed last, even after the subprocesses.... but you're right, Even if we don't use the crashpad I should use the same value as Chromium for the subprocesses. |
@salvadordf Thank you for sharing that info! @amaitland I'll pull that commit into my local CefSharp repo and give it a try. I'll check in later with the results. |
No luck. Also, the comments you left on your (@amaitland) commit say "Lower the shutdown priority so the browser process is shutdown first", but the documentation on the SetProcessShutdownParameters say:
So I think lowering the shutdown priority actually makes them shut down after the main process? With that in mind, I experimented by increasing the priority above 0x280 and still had the problem. |
@GSonofNun Correct, this is the desired behaviour, matches that used by Chromium. Ideally your application (browser process) will shutdown gracefully and terminate the sub processes. Shutting the sub process down first would likely cause chromium to attempt to relaunch them. |
Oh, I think I see my confusion. The "browser" referenced in your comments on the commit were referring to what would be the main application using CefSharp? |
@GSonofNun Correct. See https://github.com/cefsharp/CefSharp/wiki/General-Usage#processes
As per #3155 (comment) The order should hopefully be changed, so the This should hopefully resolve the original issue raised by @ekalchev
What exactly are you doing? What does your code look like? Not clear this is related to the original issue. Relevant events appear to be raised with a cursory test for me. Using https://github.com/cefsharp/CefSharp.MinimalExample and rmlogotest.exe I can see that the |
Are you using WPF? Please provide more detail. What is the reason for calling Environment.Exit? Doesn't WPF handle the messages gracefully?
How does it behave if you run directly from your bin folder? If you create an installer for the minimum example how does it behave? What installer are you using? Just saying installer is vaigue. https://github.com/cefsharp/CefSharp.MinimalExample |
Sorry, yes. A WPF application using .NET 6.
I don't think that matters. Removing that line makes no difference. It was just temporarily there to simulate our application saving state and shutting down.
I behaves like Test 2. I receive WM_QUERYENDSESSION, followed by WM_CLOSE, which closes the window but leaves the process "running" in the background.
We're using an installer generated by Wix I'll try packaging the CefSharp.MinimalExample and get back to you. |
…x200 - Change to 0x200 which is low end of 'Application reserved "in between" shutdown range.' - Remove logging as it wasn't working, must be too early to use the LOG(INFO) CEF macro Test with a GetProcessShutdownParameters in debugger shows working e.g. if (SetProcessShutdownParameters(0x200, SHUTDOWN_NORETRY)) { DWORD level = 0; DWORD flags = 0; GetProcessShutdownParameters(&level, &flags); } Issue #3155
…x200 - Change to 0x200 which is low end of 'Application reserved "in between" shutdown range.' - Remove logging as it wasn't working, must be too early to use the LOG(INFO) CEF macro Test with a GetProcessShutdownParameters in debugger shows working e.g. if (SetProcessShutdownParameters(0x200, SHUTDOWN_NORETRY)) { DWORD level = 0; DWORD flags = 0; GetProcessShutdownParameters(&level, &flags); } Issue #3155
Well, my day has been disappointing. I spent most of the day figuring out how to build the minimal example into an installer using Wix (I'm not super familiar with Wix, so I had to re-learn how it works). I finally got it to work, only to have results that disappoint me, but will probably please you. 🥲 While the installed version of the minimal example is running, if I use rmlogotest.exe, it closes perfectly, as it should. However, while it is running, if I re-run the installer to repair it, and give it permission to shut down the running application, it fails. Which leads me to wonder if it is a problem with Wix and a multi-process application. Maybe it isn't sending the shutdown message to the correct application. ¯\_(ツ)_/¯ |
Can you fork the minimum example and push your changes to GitHub so I can have a look. Preferably squashed into a single commit. Thanks. |
Here you go. Let me know if you have any questions. |
Update: Because of a change we're making to our solution, I remembered that we are building our application as a .NET 6 Self-Contained application. So I updated our application to self-host the browser subprocess, and now it responds to the installer's shutdown request as expected. |
@GSonofNun Thanks for the example.
I had a suspicion this might be the case, was on my list of cases to test. From what I can tell After much digging and experimentation calling I don't know enough about A quick example using https://github.com/oleg-shilo/wixsharp to package the using System;
using WixSharp;
using Microsoft.Deployment.WindowsInstaller;
using System.IO;
namespace CefSharp.MinimalExample.WinForms.WixSharp
{
public static class Program
{
public static void Main(string[] args)
{
var bitness = Environment.Is64BitProcess ? "x64" : "x86";
#if DEBUG
const string Build = "Debug";
#else
const string Build = "Release";
#endif
var buildPath = Path.GetFullPath(@"..\CefSharp.MinimalExample.WinForms\bin.net472\" + bitness + @"\" + Build + @"\net472");
var project = new Project("CefSharp.MinimalExample.WinForms",
new Dir(@"%ProgramFiles%\CefSharp.MinimalExample.WinForms",
new DirFiles($"{buildPath}\\*.*"),
new Dir("locales", new DirFiles($"{buildPath}\\locales\\*.*")),
new Dir("swiftshader", new DirFiles($"{buildPath}\\swiftshader\\*.*"))),
new CustomActionRef("WixCloseApplications", When.Before, Step.CostFinalize, new Condition("VersionNT > 400")),
new CloseApplication(new Id("CefSharp.MinimalExample.WinForms"), "CefSharp.MinimalExample.WinForms.net472.exe")
{
Timeout = 15,
EndSessionMessage = true,
RebootPrompt = false,
},
new Property("MsiLogging", "vocewarmup"));
project.GUID = new Guid("9007D203-B084-482F-BC23-5F4BF82EE679");
project.Platform = Platform.x64;
Compiler.BuildMsi(project);
}
}
} I'm going to close this issue now. If someone contacts the |
See #3407 (comment) for example of self hosting the browser sub process (using your own applications exe instead of |
Bug Report
Delete this line and everything above, and then fill in the details below.
What version of the product are you using?
81
What architecture x86 or x64?
x64
On what operating system?
Win10
Are you using
WinForms
,WPF
orOffScreen
?WinForms
What steps will reproduce the problem?
We have MSI installer that try to stop the app process when it is about to make an install/update. A standard dialog is shown with the list of processes that must be stopped before install/update to complete. After the update to CefSharp 81 (from 73) we started seeing Browser subprocess in the list of processes that MSI need to kill. With version 73 the subprocess was not listed. Now with version 81, MSI installer fails to install/update because it fails to stop the processes. We believe the problem is in browser subprocess, because if we kill it manually the MSI install can complete.
The text was updated successfully, but these errors were encountered: