mirror of
https://github.com/keymanapp/keyman.git
synced 2026-10-22 13:57:49 +00:00
Fixes #7690. When kmshell.dpr is being shut down by Windows via `WM_ENDSESSION`, the order of termination of units through `finalization` sections means that `IdStackWindows` was finalizing while components were still depending on it, causing a cascade of exceptions resulting eventually in the crash visible in #7690. We saw this when there were message loops before `Application.Run` had ever been called. For example, message box/dialog, ShellExecute (yep... this can do a `PeekMessage`), `THttpUploader` (which calls `Application.ProcessMessages`) and probably others. Ideally, it would be better to always call `Application.Run`, but it is not safe to call `Application.Run` more than once, because it ends up adding multiple `DoneApplication` exit procs, which would likely cause other crashes. I landed on the somewhat heavy-handed solution of adding `IdStackWindows` to the start of the project `uses` list, ensuring it is the last unit to be finalized -- importantly, before `Vcl.Forms`. A better solution would be to find a way of ensuring that `Application.Run` is called, just once, in all situations, but this is likely to be hard to achieve. The shutdown sequence for Delphi apps is so very, very fragile.
218 lines
15 KiB
ObjectPascal
218 lines
15 KiB
ObjectPascal
program kmshell;
|
|
|
|
uses
|
|
IdStackWindows,
|
|
Winapi.Windows,
|
|
comobj,
|
|
Forms,
|
|
SysUtils,
|
|
ActiveX,
|
|
Dialogs,
|
|
initprog in 'main\initprog.pas',
|
|
RegistryKeys in '..\..\..\..\common\windows\delphi\general\RegistryKeys.pas',
|
|
Registry,
|
|
UfrmMain in 'main\UfrmMain.pas' {frmMain},
|
|
kmint in 'util\kmint.pas',
|
|
GetOsVersion in '..\..\..\..\common\windows\delphi\general\GetOsVersion.pas',
|
|
DebugPaths in '..\..\..\..\common\windows\delphi\general\DebugPaths.pas',
|
|
VersionInfo in '..\..\..\..\common\windows\delphi\general\VersionInfo.pas',
|
|
UfrmHTML in 'main\UfrmHTML.pas' {frmHTML},
|
|
HotkeyUtils in '..\..\global\delphi\general\HotkeyUtils.pas',
|
|
Unicode in '..\..\..\..\common\windows\delphi\general\Unicode.pas',
|
|
utilkmshell in 'util\utilkmshell.pas',
|
|
custinterfaces in '..\..\global\delphi\cust\custinterfaces.pas',
|
|
UfrmInstallKeyboard in 'install\UfrmInstallKeyboard.pas' {frmInstallKeyboard},
|
|
MessageIdentifiers in '..\..\global\delphi\cust\MessageIdentifiers.pas',
|
|
KeyNames in '..\..\..\..\common\windows\delphi\general\KeyNames.pas',
|
|
klog in '..\..\..\..\common\windows\delphi\general\klog.pas',
|
|
keymanapi_TLB in '..\..\engine\kmcomapi\keymanapi_TLB.pas',
|
|
UfrmSplash in 'startup\UfrmSplash.pas' {frmSplash},
|
|
UfrmKeymanBase in 'main\UfrmKeymanBase.pas' {frmKeymanBase},
|
|
httpuploader in '..\..\..\..\common\windows\delphi\general\httpuploader.pas',
|
|
httpuploader_messageprocessor_forms in '..\..\..\..\common\windows\delphi\general\httpuploader_messageprocessor_forms.pas',
|
|
utildir in '..\..\..\..\common\windows\delphi\general\utildir.pas',
|
|
XMLRenderer in 'render\XMLRenderer.pas',
|
|
KeyboardListXMLRenderer in 'render\KeyboardListXMLRenderer.pas',
|
|
OptionsXMLRenderer in 'render\OptionsXMLRenderer.pas',
|
|
HotkeysXMLRenderer in 'render\HotkeysXMLRenderer.pas',
|
|
SupportXMLRenderer in 'render\SupportXMLRenderer.pas',
|
|
LanguagesXMLRenderer in 'render\LanguagesXMLRenderer.pas',
|
|
utilhttp in '..\..\..\..\common\windows\delphi\general\utilhttp.pas',
|
|
UfrmChangeHotkey in 'main\UfrmChangeHotkey.pas' {frmChangeHotkey},
|
|
utilhotkey in '..\..\global\delphi\general\utilhotkey.pas',
|
|
InterfaceHotkeys in '..\..\global\delphi\general\InterfaceHotkeys.pas',
|
|
utilsystem in '..\..\..\..\common\windows\delphi\general\utilsystem.pas',
|
|
Upload_Settings in '..\..\..\..\common\windows\delphi\general\Upload_Settings.pas',
|
|
UfrmOnlineUpdateNewVersion in 'main\UfrmOnlineUpdateNewVersion.pas' {frmOnlineUpdateNewVersion},
|
|
OnlineUpdateCheck in 'main\OnlineUpdateCheck.pas',
|
|
utilxml in '..\..\..\..\common\windows\delphi\general\utilxml.pas',
|
|
UfrmInstallKeyboardFromWeb in 'install\UfrmInstallKeyboardFromWeb.pas' {frmInstallKeyboardFromWeb},
|
|
UfrmWebContainer in 'main\UfrmWebContainer.pas' {frmWebContainer},
|
|
MessageIdentifierConsts in '..\..\global\delphi\cust\MessageIdentifierConsts.pas',
|
|
Keyman.UI.UfrmProgress in '..\..\global\delphi\general\Keyman.UI.UfrmProgress.pas' {frmProgress},
|
|
kmcomapi_errors in '..\..\global\delphi\general\kmcomapi_errors.pas',
|
|
GenericXMLRenderer in 'render\GenericXMLRenderer.pas',
|
|
help in 'main\help.pas',
|
|
UfrmProxyConfiguration in 'main\UfrmProxyConfiguration.pas' {frmProxyConfiguration: TTntForm},
|
|
OnlineUpdateCheckMessages in 'main\OnlineUpdateCheckMessages.pas',
|
|
WelcomeXMLRenderer in 'render\WelcomeXMLRenderer.pas',
|
|
ValidateKeymanInstalledSystemKeyboards in 'main\ValidateKeymanInstalledSystemKeyboards.pas',
|
|
uninstall in 'install\uninstall.pas',
|
|
KeymanControlMessages in '..\..\global\delphi\general\KeymanControlMessages.pas',
|
|
HintConsts in '..\..\global\delphi\hints\HintConsts.pas',
|
|
UfrmTextEditor in 'startup\help\UfrmTextEditor.pas' {frmTextEditor: TTntForm},
|
|
ttinfo in '..\..\..\..\common\windows\delphi\general\ttinfo.pas',
|
|
findfonts in '..\..\..\..\common\windows\delphi\general\findfonts.pas',
|
|
KMShellHints in 'util\KMShellHints.pas',
|
|
UfrmHint in '..\..\global\delphi\hints\UfrmHint.pas' {frmHint: TTntForm},
|
|
KeymanTextEditorRichEdit in '..\..\global\delphi\comp\KeymanTextEditorRichEdit.pas',
|
|
Hints in '..\..\global\delphi\hints\Hints.pas',
|
|
utilcheckfonts in '..\..\global\delphi\general\utilcheckfonts.pas',
|
|
wininet5 in '..\..\..\..\common\windows\delphi\general\wininet5.pas',
|
|
GlobalProxySettings in '..\..\..\..\common\windows\delphi\general\GlobalProxySettings.pas',
|
|
UFixupMissingFile in 'util\UFixupMissingFile.pas',
|
|
UImportOlderVersionKeyboards in 'main\UImportOlderVersionKeyboards.pas',
|
|
UImportOlderKeyboardUtils in 'main\UImportOlderKeyboardUtils.pas',
|
|
utiluac in '..\..\global\delphi\general\utiluac.pas',
|
|
UserMessages in '..\..\..\..\common\windows\delphi\general\UserMessages.pas',
|
|
UILanguages in 'util\UILanguages.pas',
|
|
UfrmKeyboardOptions in 'main\UfrmKeyboardOptions.pas' {frmKeyboardOptions},
|
|
UfrmOnlineUpdateIcon in 'main\UfrmOnlineUpdateIcon.pas' {frmOnlineUpdateIcon},
|
|
KeymanTrayIcon in '..\..\engine\keyman\KeymanTrayIcon.pas',
|
|
UImportOlderVersionKeyboards10 in 'main\UImportOlderVersionKeyboards10.pas',
|
|
VisualKeyboard in '..\..\..\..\common\windows\delphi\visualkeyboard\VisualKeyboard.pas',
|
|
VKeyChars in '..\..\..\..\common\windows\delphi\general\VKeyChars.pas',
|
|
UfrmPrintOSK in 'util\UfrmPrintOSK.pas' {frmPrintOSK},
|
|
VisualKeyboardExportHTML in '..\..\..\..\common\windows\delphi\visualkeyboard\VisualKeyboardExportHTML.pas',
|
|
VisualKeyboardExportXML in '..\..\..\..\common\windows\delphi\visualkeyboard\VisualKeyboardExportXML.pas',
|
|
VisualKeyboardParameters in '..\..\..\..\common\windows\delphi\visualkeyboard\VisualKeyboardParameters.pas',
|
|
MSXML2_TLB in '..\..\..\..\common\windows\delphi\tlb\MSXML2_TLB.pas',
|
|
VKeys in '..\..\..\..\common\windows\delphi\general\VKeys.pas',
|
|
ExtShiftState in '..\..\..\..\common\windows\delphi\visualkeyboard\ExtShiftState.pas',
|
|
UImportOlderVersionSettings in 'main\UImportOlderVersionSettings.pas',
|
|
KeymanMutex in '..\..\global\delphi\general\KeymanMutex.pas',
|
|
ErrorControlledRegistry in '..\..\..\..\common\windows\delphi\vcl\ErrorControlledRegistry.pas',
|
|
MSXMLDomCreate in '..\..\..\..\common\windows\delphi\general\MSXMLDomCreate.pas',
|
|
utilexecute in '..\..\..\..\common\windows\delphi\general\utilexecute.pas',
|
|
KeymanVersion in '..\..\..\..\common\windows\delphi\general\KeymanVersion.pas',
|
|
BaseKeyboards in '..\..\global\delphi\general\BaseKeyboards.pas',
|
|
LoadIndirectStringUnit in '..\..\engine\keyman\langswitch\LoadIndirectStringUnit.pas',
|
|
Glossary in '..\..\..\..\common\windows\delphi\general\Glossary.pas',
|
|
UfrmInstallKeyboardLanguage in 'install\UfrmInstallKeyboardLanguage.pas' {frmInstallKeyboardLanguage},
|
|
UfrmBaseKeyboard in 'main\UfrmBaseKeyboard.pas' {frmBaseKeyboard},
|
|
UnicodeBlocks in '..\..\global\delphi\general\UnicodeBlocks.pas',
|
|
TempFileManager in '..\..\..\..\common\windows\delphi\general\TempFileManager.pas',
|
|
keyman_msctf in '..\..\global\delphi\winapi\keyman_msctf.pas',
|
|
utiltsf in '..\..\global\delphi\general\utiltsf.pas',
|
|
utilolepicture in '..\..\engine\kmcomapi\util\utilolepicture.pas',
|
|
kmxfile in '..\..\..\..\common\windows\delphi\keyboards\kmxfile.pas',
|
|
utilfiletypes in '..\..\..\..\common\windows\delphi\general\utilfiletypes.pas',
|
|
CRC32 in '..\..\..\..\common\windows\delphi\general\CRC32.pas',
|
|
input_installlayoutortip in '..\..\global\delphi\winapi\input_installlayoutortip.pas',
|
|
KPInstallPackageStartMenu in '..\..\global\delphi\general\KPInstallPackageStartMenu.pas',
|
|
kmpinffile in '..\..\..\..\common\windows\delphi\packages\kmpinffile.pas',
|
|
PackageFileFormats in '..\..\..\..\common\windows\delphi\packages\PackageFileFormats.pas',
|
|
PackageInfo in '..\..\..\..\common\windows\delphi\packages\PackageInfo.pas',
|
|
utilstr in '..\..\..\..\common\windows\delphi\general\utilstr.pas',
|
|
utilwow64 in '..\..\global\delphi\general\utilwow64.pas',
|
|
KPUninstallPackageStartMenu in '..\..\global\delphi\general\KPUninstallPackageStartMenu.pas',
|
|
KPInstallFontKMShell in 'util\KPInstallFontKMShell.pas',
|
|
UpgradeMnemonicLayout in 'install\UpgradeMnemonicLayout.pas',
|
|
UfrmKeepInTouch in 'main\UfrmKeepInTouch.pas' {frmKeepInTouch},
|
|
UtilCheckOnline in 'util\UtilCheckOnline.pas',
|
|
KeyboardTIPCheck in 'main\KeyboardTIPCheck.pas',
|
|
utilfocusappwnd in 'util\utilfocusappwnd.pas',
|
|
UImportOlderVersionKeyboards8 in 'main\UImportOlderVersionKeyboards8.pas',
|
|
KeymanPaths in '..\..\..\..\common\windows\delphi\general\KeymanPaths.pas',
|
|
StockFileNames in '..\..\..\..\common\windows\delphi\general\StockFileNames.pas',
|
|
KeymanEngineControl in '..\..\global\delphi\general\KeymanEngineControl.pas',
|
|
KeymanOptionNames in '..\..\global\delphi\general\KeymanOptionNames.pas',
|
|
VisualKeyboardLoaderBinary in '..\..\..\..\common\windows\delphi\visualkeyboard\VisualKeyboardLoaderBinary.pas',
|
|
VisualKeyboardLoaderXML in '..\..\..\..\common\windows\delphi\visualkeyboard\VisualKeyboardLoaderXML.pas',
|
|
VisualKeyboardSaverBinary in '..\..\..\..\common\windows\delphi\visualkeyboard\VisualKeyboardSaverBinary.pas',
|
|
VisualKeyboardSaverXML in '..\..\..\..\common\windows\delphi\visualkeyboard\VisualKeyboardSaverXML.pas',
|
|
BCP47Tag in '..\..\..\..\common\windows\delphi\general\BCP47Tag.pas',
|
|
JsonUtil in '..\..\..\..\common\windows\delphi\general\JsonUtil.pas',
|
|
kmxfileconsts in '..\..\..\..\common\windows\delphi\keyboards\kmxfileconsts.pas',
|
|
Keyman.System.UpdateCheckResponse in '..\..\..\..\common\windows\delphi\general\Keyman.System.UpdateCheckResponse.pas',
|
|
UImportOlderVersionKeyboards9 in 'main\UImportOlderVersionKeyboards9.pas',
|
|
Keyman.System.UpgradeRegistryKeys in '..\..\global\delphi\general\Keyman.System.UpgradeRegistryKeys.pas',
|
|
UImportOlderVersionKeyboards9Plus in 'main\UImportOlderVersionKeyboards9Plus.pas',
|
|
Keyman.Configuration.UI.MitigationForWin10_1803 in 'install\Keyman.Configuration.UI.MitigationForWin10_1803.pas',
|
|
Keyman.System.CEFManager in '..\..\..\..\common\windows\delphi\chromium\Keyman.System.CEFManager.pas',
|
|
Keyman.UI.UframeCEFHost in '..\..\..\..\common\windows\delphi\chromium\Keyman.UI.UframeCEFHost.pas',
|
|
UfrmHelp in 'help\UfrmHelp.pas' {frmHelp},
|
|
Sentry.Client in '..\..\..\..\common\windows\delphi\ext\sentry\Sentry.Client.pas',
|
|
Sentry.Client.Vcl in '..\..\..\..\common\windows\delphi\ext\sentry\Sentry.Client.Vcl.pas',
|
|
sentry in '..\..\..\..\common\windows\delphi\ext\sentry\sentry.pas',
|
|
Keyman.System.LanguageCodeUtils in '..\..\..\..\common\windows\delphi\general\Keyman.System.LanguageCodeUtils.pas',
|
|
Keyman.System.Standards.ISO6393ToBCP47Registry in '..\..\..\..\common\windows\delphi\standards\Keyman.System.Standards.ISO6393ToBCP47Registry.pas',
|
|
Keyman.System.Standards.LCIDToBCP47Registry in '..\..\..\..\common\windows\delphi\standards\Keyman.System.Standards.LCIDToBCP47Registry.pas',
|
|
Keyman.System.Standards.BCP47SubtagRegistry in '..\..\..\..\common\windows\delphi\standards\Keyman.System.Standards.BCP47SubtagRegistry.pas',
|
|
Keyman.System.Standards.BCP47SuppressScriptRegistry in '..\..\..\..\common\windows\delphi\standards\Keyman.System.Standards.BCP47SuppressScriptRegistry.pas',
|
|
Keyman.System.KeymanSentryClient in '..\..\..\..\common\windows\delphi\general\Keyman.System.KeymanSentryClient.pas',
|
|
Keyman.Configuration.UI.UfrmDiagnosticTests in 'util\Keyman.Configuration.UI.UfrmDiagnosticTests.pas' {frmDiagnosticTests},
|
|
Keyman.Configuration.System.UmodWebHttpServer in 'web\Keyman.Configuration.System.UmodWebHttpServer.pas' {modWebHttpServer: TDataModule},
|
|
Keyman.Configuration.System.HttpServer.App in 'web\Keyman.Configuration.System.HttpServer.App.pas',
|
|
Keyman.System.HttpServer.Base in '..\..\..\..\common\windows\delphi\web\Keyman.System.HttpServer.Base.pas',
|
|
Keyman.Configuration.System.HttpServer.SharedData in 'web\Keyman.Configuration.System.HttpServer.SharedData.pas',
|
|
Keyman.Configuration.System.HttpServer.App.OnlineUpdate in 'web\Keyman.Configuration.System.HttpServer.App.OnlineUpdate.pas',
|
|
Keyman.System.LocaleStrings in '..\..\global\delphi\cust\Keyman.System.LocaleStrings.pas',
|
|
Keyman.Configuration.System.HttpServer.App.InstallKeyboard in 'web\Keyman.Configuration.System.HttpServer.App.InstallKeyboard.pas',
|
|
Keyman.Configuration.System.HttpServer.App.ProxyConfiguration in 'web\Keyman.Configuration.System.HttpServer.App.ProxyConfiguration.pas',
|
|
Keyman.Configuration.System.HttpServer.App.ConfigMain in 'web\Keyman.Configuration.System.HttpServer.App.ConfigMain.pas',
|
|
Keyman.Configuration.UI.InstallFile in 'install\Keyman.Configuration.UI.InstallFile.pas',
|
|
Keyman.Configuration.UI.KeymanProtocolHandler in 'install\Keyman.Configuration.UI.KeymanProtocolHandler.pas',
|
|
Keyman.Configuration.System.KeymanUILanguageManager in 'main\Keyman.Configuration.System.KeymanUILanguageManager.pas',
|
|
Keyman.System.UILanguageManager in '..\..\global\delphi\general\Keyman.System.UILanguageManager.pas',
|
|
Keyman.Configuration.System.TIPMaintenance in 'install\Keyman.Configuration.System.TIPMaintenance.pas',
|
|
UfrmDownloadProgress in 'util\UfrmDownloadProgress.pas' {frmDownloadProgress},
|
|
Keyman.Configuration.System.UImportOlderVersionKeyboards11To13 in 'main\Keyman.Configuration.System.UImportOlderVersionKeyboards11To13.pas',
|
|
Keyman.System.Settings in '..\..\global\delphi\general\Keyman.System.Settings.pas',
|
|
Keyman.System.SettingsManager in '..\..\global\delphi\general\Keyman.System.SettingsManager.pas',
|
|
Keyman.Configuration.UI.UfrmSettingsManager in 'settings\Keyman.Configuration.UI.UfrmSettingsManager.pas' {frmSettingsManager},
|
|
Keyman.Configuration.UI.UfrmSettingsAddTSFApp in 'settings\Keyman.Configuration.UI.UfrmSettingsAddTSFApp.pas' {frmSettingsAddTSFApp},
|
|
Keyman.System.SettingsManagerFile in '..\..\global\delphi\general\Keyman.System.SettingsManagerFile.pas',
|
|
Keyman.System.KeymanStartTask in 'util\Keyman.System.KeymanStartTask.pas',
|
|
TaskScheduler_TLB in '..\..\global\delphi\winapi\TaskScheduler_TLB.pas',
|
|
Keyman.Configuration.System.HttpServer.App.TextEditorFonts in 'startup\help\Keyman.Configuration.System.HttpServer.App.TextEditorFonts.pas',
|
|
Keyman.Configuration.System.HttpServer.App.Locale in 'web\Keyman.Configuration.System.HttpServer.App.Locale.pas',
|
|
Keyman.System.AndroidStringToKeymanLocaleString in '..\..\..\..\common\windows\delphi\general\Keyman.System.AndroidStringToKeymanLocaleString.pas';
|
|
|
|
{$R VERSION.RES}
|
|
{$R manifest.res}
|
|
|
|
// CEF3 needs to set the LARGEADDRESSAWARE flag which allows 32-bit processes to use up to 3GB of RAM.
|
|
// If you don't add this flag the rederer process will crash when you try to load large images.
|
|
{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}
|
|
|
|
const
|
|
LOGGER_DESKTOP_KMSHELL = TKeymanSentryClient.LOGGER_DESKTOP + '.kmshell';
|
|
begin
|
|
TKeymanSentryClient.Start(TSentryClientVcl, kscpDesktop, LOGGER_DESKTOP_KMSHELL);
|
|
try
|
|
CoInitFlags := COINIT_APARTMENTTHREADED;
|
|
FInitializeCEF := TCEFManager.Create;
|
|
try
|
|
if FInitializeCEF.Start then
|
|
try
|
|
Application.Initialize;
|
|
Application.Title := 'Keyman Configuration';
|
|
Application.CreateForm(TmodWebHttpServer, modWebHttpServer);
|
|
try
|
|
Run;
|
|
finally
|
|
FreeAndNil(modWebHttpServer);
|
|
end;
|
|
except
|
|
on E:Exception do
|
|
SentryHandleException(E);
|
|
end;
|
|
finally
|
|
FInitializeCEF.Free;
|
|
end;
|
|
finally
|
|
TKeymanSentryClient.Stop;
|
|
end;
|
|
end.
|
|
|