Force autostart folder creation.

Also show an error if autostart couldn't be enabled.

Fixes #25608.
This commit is contained in:
John Preston 2023-01-02 12:24:46 +04:00
parent db6bdf36af
commit 442d0da5c1
3 changed files with 95 additions and 45 deletions

View file

@ -66,5 +66,9 @@ inline QString EmailConfirmationExpired() {
return u"This email confirmation has expired. Please setup two-step verification once again."_q; return u"This email confirmation has expired. Please setup two-step verification once again."_q;
} }
inline QString AutostartEnableError() {
return u"Could not register for autostart."_q;
}
} // namespace Hard } // namespace Hard
} // namespace Lang } // namespace Lang

View file

@ -142,19 +142,49 @@ void DeleteMyModules() {
RemoveDirectory(modules.c_str()); RemoveDirectory(modules.c_str());
} }
void ManageAppLink(bool create, bool silent, int path_csidl, const wchar_t *args, const wchar_t *description) { bool ManageAppLink(
bool create,
bool silent,
const GUID &folderId,
const wchar_t *args,
const wchar_t *description) {
if (cExeName().isEmpty()) { if (cExeName().isEmpty()) {
return; return false;
}
PWSTR startupFolder;
HRESULT hr = SHGetKnownFolderPath(
folderId,
KF_FLAG_CREATE,
nullptr,
&startupFolder);
const auto guard = gsl::finally([&] {
CoTaskMemFree(startupFolder);
});
if (!SUCCEEDED(hr)) {
WCHAR buffer[64];
const auto size = base::array_size(buffer) - 1;
const auto length = StringFromGUID2(folderId, buffer, size);
if (length > 0 && length <= size) {
buffer[length] = 0;
if (!silent) LOG(("App Error: could not get %1 folder: %2").arg(buffer).arg(hr));
}
return false;
}
const auto lnk = QString::fromWCharArray(startupFolder)
+ '\\'
+ AppFile.utf16()
+ u".lnk"_q;
if (!create) {
QFile::remove(lnk);
return true;
} }
WCHAR startupFolder[MAX_PATH];
HRESULT hr = SHGetFolderPath(0, path_csidl, 0, SHGFP_TYPE_CURRENT, startupFolder);
if (SUCCEEDED(hr)) {
QString lnk = QString::fromWCharArray(startupFolder) + '\\' + AppFile.utf16() + u".lnk"_q;
if (create) {
const auto shellLink = base::WinRT::TryCreateInstance<IShellLink>( const auto shellLink = base::WinRT::TryCreateInstance<IShellLink>(
CLSID_ShellLink, CLSID_ShellLink,
CLSCTX_INPROC_SERVER); CLSCTX_INPROC_SERVER);
if (shellLink) { if (!shellLink) {
if (!silent) LOG(("App Error: could not create instance of IID_IShellLink %1").arg(hr));
return false;
}
QString exe = QDir::toNativeSeparators(cExeDir() + cExeName()), dir = QDir::toNativeSeparators(QDir(cWorkingDir()).absolutePath()); QString exe = QDir::toNativeSeparators(cExeDir() + cExeName()), dir = QDir::toNativeSeparators(QDir(cWorkingDir()).absolutePath());
shellLink->SetArguments(args); shellLink->SetArguments(args);
shellLink->SetPath(exe.toStdWString().c_str()); shellLink->SetPath(exe.toStdWString().c_str());
@ -173,20 +203,17 @@ void ManageAppLink(bool create, bool silent, int path_csidl, const wchar_t *args
} }
} }
if (const auto persistFile = shellLink.try_as<IPersistFile>()) { const auto persistFile = shellLink.try_as<IPersistFile>();
hr = persistFile->Save(lnk.toStdWString().c_str(), TRUE); if (!persistFile) {
} else {
if (!silent) LOG(("App Error: could not create interface IID_IPersistFile %1").arg(hr)); if (!silent) LOG(("App Error: could not create interface IID_IPersistFile %1").arg(hr));
return false;
} }
} else { hr = persistFile->Save(lnk.toStdWString().c_str(), TRUE);
if (!silent) LOG(("App Error: could not create instance of IID_IShellLink %1").arg(hr)); if (!SUCCEEDED(hr)) {
} if (!silent) LOG(("App Error: could not save IPersistFile to path %1").arg(lnk));
} else { return false;
QFile::remove(lnk);
}
} else {
if (!silent) LOG(("App Error: could not get CSIDL %1 folder %2").arg(path_csidl).arg(hr));
} }
return true;
} }
} // namespace } // namespace
@ -415,9 +442,15 @@ void AutostartToggle(bool enabled, Fn<void(bool)> done) {
done ? Fn<void(bool)>(callback) : nullptr); done ? Fn<void(bool)>(callback) : nullptr);
#else // OS_WIN_STORE #else // OS_WIN_STORE
const auto silent = !done; const auto silent = !done;
ManageAppLink(enabled, silent, CSIDL_STARTUP, L"-autostart", L"Telegram autorun link.\nYou can disable autorun in Telegram settings."); const auto success = ManageAppLink(
enabled,
silent,
FOLDERID_Startup,
L"-autostart",
L"Telegram autorun link.\n"
"You can disable autorun in Telegram settings.");
if (done) { if (done) {
done(enabled); done(enabled && success);
} }
#endif // OS_WIN_STORE #endif // OS_WIN_STORE
} }
@ -586,7 +619,13 @@ void NewVersionLaunched(int oldVersion) {
} // namespace Platform } // namespace Platform
void psSendToMenu(bool send, bool silent) { void psSendToMenu(bool send, bool silent) {
ManageAppLink(send, silent, CSIDL_SENDTO, L"-sendpath", L"Telegram send to link.\nYou can disable send to menu item in Telegram settings."); ManageAppLink(
send,
silent,
FOLDERID_SendTo,
L"-sendpath",
L"Telegram send to link.\n"
"You can disable send to menu item in Telegram settings.");
} }
bool psLaunchMaps(const Data::LocationPoint &point) { bool psLaunchMaps(const Data::LocationPoint &point) {

View file

@ -500,10 +500,17 @@ void SetupSystemIntegrationContent(
) | rpl::filter([](bool checked) { ) | rpl::filter([](bool checked) {
return (checked != cAutoStart()); return (checked != cAutoStart());
}) | rpl::start_with_next([=](bool checked) { }) | rpl::start_with_next([=](bool checked) {
const auto weak = base::make_weak(controller);
cSetAutoStart(checked); cSetAutoStart(checked);
Platform::AutostartToggle(checked, crl::guard(autostart, [=]( Platform::AutostartToggle(checked, crl::guard(autostart, [=](
bool enabled) { bool enabled) {
if (checked && !enabled && weak) {
weak->window().showToast(
Lang::Hard::AutostartEnableError());
}
Ui::PostponeCall(autostart, [=] {
autostart->setChecked(enabled); autostart->setChecked(enabled);
});
if (enabled || !minimized->entity()->checked()) { if (enabled || !minimized->entity()->checked()) {
Local::writeSettings(); Local::writeSettings();
} else { } else {