mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-09 12:46:47 +02:00
Ensure the lifetime of CPowerRenameProcessUI on the worker thread (#11106)
* Ensure the lifetime of CPowerRenameProcessUI on the worker thread to prevent AV during shutdown * Ensure worker thread progress dialog pointer is valid. Also add a call to StopProgressDialog from the worker thread as the progress dialog can be particular about thread affinity for that method call. Co-authored-by: Chris Davis (EDGE) <chrdavis@microsoft.com>
This commit is contained in:
@@ -1523,7 +1523,12 @@ HRESULT CPowerRenameProgressUI::Start()
|
|||||||
{
|
{
|
||||||
_Cleanup();
|
_Cleanup();
|
||||||
m_canceled = false;
|
m_canceled = false;
|
||||||
|
AddRef();
|
||||||
m_workerThreadHandle = CreateThread(nullptr, 0, s_workerThread, this, 0, nullptr);
|
m_workerThreadHandle = CreateThread(nullptr, 0, s_workerThread, this, 0, nullptr);
|
||||||
|
if (!m_workerThreadHandle)
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
}
|
||||||
return (m_workerThreadHandle) ? S_OK : E_FAIL;
|
return (m_workerThreadHandle) ? S_OK : E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1538,20 +1543,22 @@ DWORD WINAPI CPowerRenameProgressUI::s_workerThread(_In_ void* pv)
|
|||||||
|
|
||||||
SetTimer(hwndMessage, TIMERID_CHECKCANCELED, CANCEL_CHECK_INTERVAL, nullptr);
|
SetTimer(hwndMessage, TIMERID_CHECKCANCELED, CANCEL_CHECK_INTERVAL, nullptr);
|
||||||
|
|
||||||
if (SUCCEEDED(CoCreateInstance(CLSID_ProgressDialog, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&pThis->m_sppd))))
|
CComPtr<IProgressDialog> sppd;
|
||||||
|
if (SUCCEEDED(CoCreateInstance(CLSID_ProgressDialog, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&sppd))))
|
||||||
{
|
{
|
||||||
|
pThis->m_sppd = sppd;
|
||||||
wchar_t buff[100] = { 0 };
|
wchar_t buff[100] = { 0 };
|
||||||
LoadString(g_hInst, IDS_LOADING, buff, ARRAYSIZE(buff));
|
LoadString(g_hInst, IDS_LOADING, buff, ARRAYSIZE(buff));
|
||||||
pThis->m_sppd->SetLine(1, buff, FALSE, NULL);
|
sppd->SetLine(1, buff, FALSE, NULL);
|
||||||
LoadString(g_hInst, IDS_LOADING_MSG, buff, ARRAYSIZE(buff));
|
LoadString(g_hInst, IDS_LOADING_MSG, buff, ARRAYSIZE(buff));
|
||||||
pThis->m_sppd->SetLine(2, buff, FALSE, NULL);
|
sppd->SetLine(2, buff, FALSE, NULL);
|
||||||
LoadString(g_hInst, IDS_APP_TITLE, buff, ARRAYSIZE(buff));
|
LoadString(g_hInst, IDS_APP_TITLE, buff, ARRAYSIZE(buff));
|
||||||
pThis->m_sppd->SetTitle(buff);
|
sppd->SetTitle(buff);
|
||||||
SetTimer(hwndMessage, TIMERID_CHECKCANCELED, CANCEL_CHECK_INTERVAL, nullptr);
|
SetTimer(hwndMessage, TIMERID_CHECKCANCELED, CANCEL_CHECK_INTERVAL, nullptr);
|
||||||
pThis->m_sppd->StartProgressDialog(NULL, NULL, PROGDLG_MARQUEEPROGRESS, NULL);
|
sppd->StartProgressDialog(NULL, NULL, PROGDLG_MARQUEEPROGRESS, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (pThis->m_sppd && !pThis->m_canceled)
|
while (pThis->m_sppd && !sppd->HasUserCancelled())
|
||||||
{
|
{
|
||||||
MSG msg;
|
MSG msg;
|
||||||
while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
|
while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
|
||||||
@@ -1561,8 +1568,13 @@ DWORD WINAPI CPowerRenameProgressUI::s_workerThread(_In_ void* pv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure dialog is stopped
|
||||||
|
sppd->StopProgressDialog();
|
||||||
|
|
||||||
KillTimer(hwndMessage, TIMERID_CHECKCANCELED);
|
KillTimer(hwndMessage, TIMERID_CHECKCANCELED);
|
||||||
DestroyWindow(hwndMessage);
|
DestroyWindow(hwndMessage);
|
||||||
|
|
||||||
|
pThis->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
@@ -1587,9 +1599,12 @@ void CPowerRenameProgressUI::_Cleanup()
|
|||||||
|
|
||||||
if (m_workerThreadHandle)
|
if (m_workerThreadHandle)
|
||||||
{
|
{
|
||||||
|
// Wait for up to 5 seconds for worker thread to finish
|
||||||
|
WaitForSingleObject(m_workerThreadHandle, 5000);
|
||||||
CloseHandle(m_workerThreadHandle);
|
CloseHandle(m_workerThreadHandle);
|
||||||
m_workerThreadHandle = nullptr;
|
m_workerThreadHandle = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPowerRenameProgressUI::_UpdateCancelState()
|
void CPowerRenameProgressUI::_UpdateCancelState()
|
||||||
@@ -1634,6 +1649,7 @@ LRESULT CPowerRenameProgressUI::_WndProc(_In_ HWND hwnd, _In_ UINT msg, _In_ WPA
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
|
_UpdateCancelState();
|
||||||
KillTimer(hwnd, TIMERID_CHECKCANCELED);
|
KillTimer(hwnd, TIMERID_CHECKCANCELED);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user