mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 03:07:56 +01:00
[AdvancedPaste]Use background thread for interactions between runner and Advanced Paste (#36858)
* [Advanced Paste] Use background thread for runner-Advanced Paste interaction * Fixed typo
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build"
|
||||
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<Target Name="GenerateResourceFiles" BeforeTargets="PrepareForBuild">
|
||||
<Exec Command="powershell -NonInteractive -executionpolicy Unrestricted $(SolutionDir)tools\build\convert-resx-to-rc.ps1 $(MSBuildThisFileDirectory) resource.base.h resource.h AdvancedPaste.base.rc AdvancedPaste.rc" />
|
||||
@@ -41,6 +40,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="AdvancedPasteConstants.h" />
|
||||
<ClInclude Include="AdvancedPasteProcessManager.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="resource.base.h" />
|
||||
@@ -48,6 +48,7 @@
|
||||
<ClInclude Include="Generated Files\resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AdvancedPasteProcessManager.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(UsePrecompiledHeaders)' != 'false'">Create</PrecompiledHeader>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0"
|
||||
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
@@ -31,6 +30,9 @@
|
||||
<ClInclude Include="trace.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="AdvancedPasteProcessManager.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
@@ -42,6 +44,9 @@
|
||||
<ClCompile Include="trace.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="AdvancedPasteProcessManager.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="resource.base.h">
|
||||
|
||||
@@ -0,0 +1,267 @@
|
||||
#include "pch.h"
|
||||
#include "AdvancedPasteProcessManager.h"
|
||||
|
||||
#include <common/logger/logger.h>
|
||||
#include <common/utils/winapi_error.h>
|
||||
#include <common/interop/shared_constants.h>
|
||||
#include <atlstr.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
std::optional<std::wstring> get_pipe_name(const std::wstring& prefix)
|
||||
{
|
||||
UUID temp_uuid;
|
||||
wchar_t* uuid_chars = nullptr;
|
||||
if (UuidCreate(&temp_uuid) == RPC_S_UUID_NO_ADDRESS)
|
||||
{
|
||||
const auto val = get_last_error_message(GetLastError());
|
||||
Logger::error(L"UuidCreate cannot create guid. {}", val.has_value() ? val.value() : L"");
|
||||
return std::nullopt;
|
||||
}
|
||||
else if (UuidToString(&temp_uuid, reinterpret_cast<RPC_WSTR*>(&uuid_chars)) != RPC_S_OK)
|
||||
{
|
||||
const auto val = get_last_error_message(GetLastError());
|
||||
Logger::error(L"UuidToString cannot convert to string. {}", val.has_value() ? val.value() : L"");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const auto pipe_name = std::format(L"{}{}", prefix, std::wstring(uuid_chars));
|
||||
RpcStringFree(reinterpret_cast<RPC_WSTR*>(&uuid_chars));
|
||||
|
||||
return pipe_name;
|
||||
}
|
||||
}
|
||||
|
||||
void AdvancedPasteProcessManager::start()
|
||||
{
|
||||
m_enabled = true;
|
||||
submit_task([this]() { refresh(); });
|
||||
}
|
||||
|
||||
void AdvancedPasteProcessManager::stop()
|
||||
{
|
||||
m_enabled = false;
|
||||
submit_task([this]() { refresh(); });
|
||||
}
|
||||
|
||||
void AdvancedPasteProcessManager::send_message(const std::wstring& message_type, const std::wstring& message_arg)
|
||||
{
|
||||
submit_task([this, message_type, message_arg] {
|
||||
send_named_pipe_message(message_type, message_arg);
|
||||
});
|
||||
}
|
||||
|
||||
void AdvancedPasteProcessManager::bring_to_front()
|
||||
{
|
||||
submit_task([this] {
|
||||
if (!is_process_running())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto enum_windows = [](HWND hwnd, LPARAM param) -> BOOL {
|
||||
const auto process_handle = reinterpret_cast<HANDLE>(param);
|
||||
DWORD window_process_id = 0;
|
||||
|
||||
GetWindowThreadProcessId(hwnd, &window_process_id);
|
||||
if (GetProcessId(process_handle) == window_process_id)
|
||||
{
|
||||
SetForegroundWindow(hwnd);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
};
|
||||
|
||||
EnumWindows(enum_windows, reinterpret_cast<LPARAM>(m_hProcess));
|
||||
});
|
||||
}
|
||||
|
||||
void AdvancedPasteProcessManager::submit_task(std::function<void()> task)
|
||||
{
|
||||
m_thread_executor.submit(OnThreadExecutor::task_t{ task });
|
||||
}
|
||||
|
||||
bool AdvancedPasteProcessManager::is_process_running() const
|
||||
{
|
||||
return m_hProcess != 0 && WaitForSingleObject(m_hProcess, 0) == WAIT_TIMEOUT;
|
||||
}
|
||||
|
||||
void AdvancedPasteProcessManager::terminate_process()
|
||||
{
|
||||
if (m_hProcess != 0)
|
||||
{
|
||||
TerminateProcess(m_hProcess, 1);
|
||||
CloseHandle(m_hProcess);
|
||||
m_hProcess = 0;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT AdvancedPasteProcessManager::start_process(const std::wstring& pipe_name)
|
||||
{
|
||||
const unsigned long powertoys_pid = GetCurrentProcessId();
|
||||
|
||||
const auto executable_args = std::format(L"{} {}", std::to_wstring(powertoys_pid), pipe_name);
|
||||
|
||||
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
||||
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
|
||||
sei.lpFile = L"WinUI3Apps\\PowerToys.AdvancedPaste.exe";
|
||||
sei.nShow = SW_SHOWNORMAL;
|
||||
sei.lpParameters = executable_args.data();
|
||||
if (ShellExecuteExW(&sei))
|
||||
{
|
||||
Logger::trace("Successfully started Advanced Paste process");
|
||||
terminate_process();
|
||||
m_hProcess = sei.hProcess;
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::error(L"Advanced Paste process failed to start. {}", get_last_error_or_default(GetLastError()));
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT AdvancedPasteProcessManager::start_named_pipe_server(const std::wstring& pipe_name)
|
||||
{
|
||||
m_write_pipe = nullptr;
|
||||
|
||||
const constexpr DWORD BUFSIZE = 4096 * 4;
|
||||
|
||||
const auto full_pipe_name = std::format(L"\\\\.\\pipe\\{}", pipe_name);
|
||||
|
||||
const auto hPipe = CreateNamedPipe(
|
||||
full_pipe_name.c_str(), // pipe name
|
||||
PIPE_ACCESS_OUTBOUND | // write access
|
||||
FILE_FLAG_OVERLAPPED, // overlapped mode
|
||||
PIPE_TYPE_MESSAGE | // message type pipe
|
||||
PIPE_READMODE_MESSAGE | // message-read mode
|
||||
PIPE_WAIT, // blocking mode
|
||||
1, // max. instances
|
||||
BUFSIZE, // output buffer size
|
||||
0, // input buffer size
|
||||
0, // client time-out
|
||||
NULL); // default security attribute
|
||||
|
||||
if (hPipe == NULL || hPipe == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
Logger::error(L"Error creating handle for named pipe");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Create overlapped event to wait for client to connect to pipe.
|
||||
OVERLAPPED overlapped = { 0 };
|
||||
overlapped.hEvent = CreateEvent(nullptr, true, false, nullptr);
|
||||
if (!overlapped.hEvent)
|
||||
{
|
||||
Logger::error(L"Error creating overlapped event for named pipe");
|
||||
CloseHandle(hPipe);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
const auto clean_up_and_fail = [&]() {
|
||||
CloseHandle(overlapped.hEvent);
|
||||
CloseHandle(hPipe);
|
||||
return E_FAIL;
|
||||
};
|
||||
|
||||
if (!ConnectNamedPipe(hPipe, &overlapped))
|
||||
{
|
||||
const auto lastError = GetLastError();
|
||||
|
||||
if (lastError != ERROR_IO_PENDING && lastError != ERROR_PIPE_CONNECTED)
|
||||
{
|
||||
Logger::error(L"Error connecting to named pipe");
|
||||
return clean_up_and_fail();
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for client.
|
||||
const constexpr DWORD client_timeout_millis = 5000;
|
||||
switch (WaitForSingleObject(overlapped.hEvent, client_timeout_millis))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
{
|
||||
DWORD bytes_transferred = 0;
|
||||
if (GetOverlappedResult(hPipe, &overlapped, &bytes_transferred, FALSE))
|
||||
{
|
||||
CloseHandle(overlapped.hEvent);
|
||||
m_write_pipe = std::make_unique<CAtlFile>(hPipe);
|
||||
|
||||
Logger::trace(L"Advanced Paste successfully connected to named pipe");
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::error(L"Error waiting for Advanced Paste to connect to named pipe");
|
||||
return clean_up_and_fail();
|
||||
}
|
||||
}
|
||||
|
||||
case WAIT_TIMEOUT:
|
||||
case WAIT_FAILED:
|
||||
default:
|
||||
Logger::error(L"Error waiting for Advanced Paste to connect to named pipe");
|
||||
return clean_up_and_fail();
|
||||
}
|
||||
}
|
||||
|
||||
void AdvancedPasteProcessManager::refresh()
|
||||
{
|
||||
if (m_enabled == is_process_running())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_enabled)
|
||||
{
|
||||
Logger::trace(L"Starting Advanced Paste process");
|
||||
|
||||
const auto pipe_name = get_pipe_name(L"powertoys_advanced_paste_");
|
||||
|
||||
if (!pipe_name)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (start_process(pipe_name.value()) != S_OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (start_named_pipe_server(pipe_name.value()) != S_OK)
|
||||
{
|
||||
Logger::error(L"Named pipe initialization failed; terminating Advanced Paste process");
|
||||
terminate_process();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::trace(L"Exiting Advanced Paste process");
|
||||
|
||||
send_named_pipe_message(CommonSharedConstants::ADVANCED_PASTE_TERMINATE_APP_MESSAGE);
|
||||
WaitForSingleObject(m_hProcess, 5000);
|
||||
|
||||
if (is_process_running())
|
||||
{
|
||||
Logger::error(L"Advanced Paste process failed to gracefully exit; terminating");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::trace(L"Advanced Paste process successfully exited");
|
||||
}
|
||||
|
||||
terminate_process();
|
||||
}
|
||||
}
|
||||
|
||||
void AdvancedPasteProcessManager::send_named_pipe_message(const std::wstring& message_type, const std::wstring& message_arg)
|
||||
{
|
||||
if (m_write_pipe)
|
||||
{
|
||||
const auto message = message_arg.empty() ? std::format(L"{}\r\n", message_type) : std::format(L"{} {}\r\n", message_type, message_arg);
|
||||
|
||||
const CString file_name(message.c_str());
|
||||
m_write_pipe->Write(file_name, file_name.GetLength() * sizeof(TCHAR));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
#include "pch.h"
|
||||
#include <common/utils/OnThreadExecutor.h>
|
||||
#include <atlfile.h>
|
||||
#include <string>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
|
||||
class AdvancedPasteProcessManager
|
||||
{
|
||||
public:
|
||||
AdvancedPasteProcessManager() = default;
|
||||
AdvancedPasteProcessManager(const AdvancedPasteProcessManager&) = delete;
|
||||
AdvancedPasteProcessManager& operator=(const AdvancedPasteProcessManager&) = delete;
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
void send_message(const std::wstring& message_type, const std::wstring& message_arg = L"");
|
||||
void bring_to_front();
|
||||
|
||||
private:
|
||||
void submit_task(std::function<void()> task);
|
||||
bool is_process_running() const;
|
||||
void terminate_process();
|
||||
HRESULT start_process(const std::wstring& pipe_name);
|
||||
HRESULT start_named_pipe_server(const std::wstring& pipe_name);
|
||||
void refresh();
|
||||
void send_named_pipe_message(const std::wstring& message_type, const std::wstring& message_arg = L"");
|
||||
|
||||
OnThreadExecutor m_thread_executor; // all internal operations are done on background thread with task queue
|
||||
std::atomic<bool> m_enabled = false; // written on main thread, read on background thread
|
||||
HANDLE m_hProcess = 0;
|
||||
std::unique_ptr<CAtlFile> m_write_pipe;
|
||||
};
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "AdvancedPasteConstants.h"
|
||||
#include "AdvancedPasteProcessManager.h"
|
||||
#include <interface/powertoy_module_interface.h>
|
||||
#include "trace.h"
|
||||
#include "Generated Files/resource.h"
|
||||
@@ -16,8 +17,6 @@
|
||||
#include <common/utils/gpo.h>
|
||||
|
||||
#include <winrt/Windows.Security.Credentials.h>
|
||||
#include <atlfile.h>
|
||||
#include <atlstr.h>
|
||||
#include <vector>
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*lpReserved*/)
|
||||
@@ -66,6 +65,8 @@ namespace
|
||||
class AdvancedPaste : public PowertoyModuleIface
|
||||
{
|
||||
private:
|
||||
|
||||
AdvancedPasteProcessManager m_process_manager;
|
||||
bool m_enabled = false;
|
||||
|
||||
std::wstring app_name;
|
||||
@@ -73,13 +74,6 @@ private:
|
||||
//contains the non localized key of the powertoy
|
||||
std::wstring app_key;
|
||||
|
||||
HANDLE m_hProcess;
|
||||
|
||||
std::unique_ptr<CAtlFile> m_write_pipe;
|
||||
|
||||
// Time to wait for process to close after sending WM_CLOSE signal
|
||||
static const constexpr int MAX_WAIT_MILLISEC = 10000;
|
||||
|
||||
static const constexpr int NUM_DEFAULT_HOTKEYS = 4;
|
||||
|
||||
Hotkey m_paste_as_plain_hotkey = { .win = true, .ctrl = true, .shift = false, .alt = true, .key = 'V' };
|
||||
@@ -371,84 +365,6 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
bool is_process_running() const
|
||||
{
|
||||
return WaitForSingleObject(m_hProcess, 0) == WAIT_TIMEOUT;
|
||||
}
|
||||
|
||||
void launch_process(const std::wstring& pipe_name)
|
||||
{
|
||||
Logger::trace(L"Starting AdvancedPaste process");
|
||||
const unsigned long powertoys_pid = GetCurrentProcessId();
|
||||
|
||||
const auto executable_args = std::format(L"{} {}", std::to_wstring(powertoys_pid), pipe_name);
|
||||
|
||||
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
||||
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
|
||||
sei.lpFile = L"WinUI3Apps\\PowerToys.AdvancedPaste.exe";
|
||||
sei.nShow = SW_SHOWNORMAL;
|
||||
sei.lpParameters = executable_args.data();
|
||||
if (ShellExecuteExW(&sei))
|
||||
{
|
||||
Logger::trace("Successfully started the Advanced Paste process");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::error(L"AdvancedPaste failed to start. {}", get_last_error_or_default(GetLastError()));
|
||||
}
|
||||
|
||||
TerminateProcess(m_hProcess, 1);
|
||||
m_hProcess = sei.hProcess;
|
||||
}
|
||||
|
||||
std::optional<std::wstring> get_pipe_name(const std::wstring& prefix) const
|
||||
{
|
||||
UUID temp_uuid;
|
||||
wchar_t* uuid_chars = nullptr;
|
||||
if (UuidCreate(&temp_uuid) == RPC_S_UUID_NO_ADDRESS)
|
||||
{
|
||||
const auto val = get_last_error_message(GetLastError());
|
||||
Logger::error(L"UuidCreate cannot create guid. {}", val.has_value() ? val.value() : L"");
|
||||
return std::nullopt;
|
||||
}
|
||||
else if (UuidToString(&temp_uuid, reinterpret_cast<RPC_WSTR*>(&uuid_chars)) != RPC_S_OK)
|
||||
{
|
||||
const auto val = get_last_error_message(GetLastError());
|
||||
Logger::error(L"UuidToString cannot convert to string. {}", val.has_value() ? val.value() : L"");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const auto pipe_name = std::format(L"{}{}", prefix, std::wstring(uuid_chars));
|
||||
RpcStringFree(reinterpret_cast<RPC_WSTR*>(&uuid_chars));
|
||||
|
||||
return pipe_name;
|
||||
}
|
||||
|
||||
void launch_process_and_named_pipe()
|
||||
{
|
||||
const auto pipe_name = get_pipe_name(L"powertoys_advanced_paste_");
|
||||
|
||||
if (!pipe_name)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::thread create_pipe_thread ([&]{ start_named_pipe_server(pipe_name.value()); });
|
||||
launch_process(pipe_name.value());
|
||||
create_pipe_thread.join();
|
||||
}
|
||||
|
||||
void send_named_pipe_message(const std::wstring& message_type, const std::wstring& message_arg = L"")
|
||||
{
|
||||
if (m_write_pipe)
|
||||
{
|
||||
const auto message = message_arg.empty() ? std::format(L"{}\r\n", message_type) : std::format(L"{} {}\r\n", message_type, message_arg);
|
||||
|
||||
const CString file_name(message.c_str());
|
||||
m_write_pipe->Write(file_name, file_name.GetLength() * sizeof(TCHAR));
|
||||
}
|
||||
}
|
||||
|
||||
// Load the settings file.
|
||||
void init_settings()
|
||||
{
|
||||
@@ -691,66 +607,6 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void bring_process_to_front()
|
||||
{
|
||||
auto enum_windows = [](HWND hwnd, LPARAM param) -> BOOL {
|
||||
HANDLE process_handle = reinterpret_cast<HANDLE>(param);
|
||||
DWORD window_process_id = 0;
|
||||
|
||||
GetWindowThreadProcessId(hwnd, &window_process_id);
|
||||
if (GetProcessId(process_handle) == window_process_id)
|
||||
{
|
||||
SetForegroundWindow(hwnd);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
};
|
||||
|
||||
EnumWindows(enum_windows, (LPARAM)m_hProcess);
|
||||
}
|
||||
|
||||
HRESULT start_named_pipe_server(const std::wstring& pipe_name)
|
||||
{
|
||||
const constexpr DWORD BUFSIZE = 4096 * 4;
|
||||
|
||||
const auto full_pipe_name = std::format(L"\\\\.\\pipe\\{}", pipe_name);
|
||||
|
||||
const auto hPipe = CreateNamedPipe(
|
||||
full_pipe_name.c_str(), // pipe name
|
||||
PIPE_ACCESS_OUTBOUND, // write access
|
||||
PIPE_TYPE_MESSAGE | // message type pipe
|
||||
PIPE_READMODE_MESSAGE | // message-read mode
|
||||
PIPE_WAIT, // blocking mode
|
||||
1, // max. instances
|
||||
BUFSIZE, // output buffer size
|
||||
0, // input buffer size
|
||||
0, // client time-out
|
||||
NULL); // default security attribute
|
||||
|
||||
if (hPipe == NULL || hPipe == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// This call blocks until a client process connects to the pipe
|
||||
BOOL connected = ConnectNamedPipe(hPipe, NULL);
|
||||
if (!connected)
|
||||
{
|
||||
if (GetLastError() == ERROR_PIPE_CONNECTED)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
CloseHandle(hPipe);
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
m_write_pipe = std::make_unique<CAtlFile>(hPipe);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
public:
|
||||
AdvancedPaste()
|
||||
{
|
||||
@@ -854,28 +710,19 @@ public:
|
||||
Logger::trace("AdvancedPaste::enable()");
|
||||
Trace::AdvancedPaste_Enable(true);
|
||||
m_enabled = true;
|
||||
|
||||
launch_process_and_named_pipe();
|
||||
m_process_manager.start();
|
||||
};
|
||||
|
||||
void Disable(bool traceEvent)
|
||||
{
|
||||
if (m_enabled)
|
||||
{
|
||||
send_named_pipe_message(CommonSharedConstants::ADVANCED_PASTE_TERMINATE_APP_MESSAGE);
|
||||
WaitForSingleObject(m_hProcess, 1500);
|
||||
|
||||
m_write_pipe = nullptr;
|
||||
|
||||
TerminateProcess(m_hProcess, 1);
|
||||
m_process_manager.stop();
|
||||
|
||||
if (traceEvent)
|
||||
{
|
||||
Trace::AdvancedPaste_Enable(false);
|
||||
}
|
||||
|
||||
CloseHandle(m_hProcess);
|
||||
m_hProcess = 0;
|
||||
}
|
||||
|
||||
m_enabled = false;
|
||||
@@ -892,11 +739,7 @@ public:
|
||||
Logger::trace(L"AdvancedPaste hotkey pressed");
|
||||
if (m_enabled)
|
||||
{
|
||||
if (!is_process_running())
|
||||
{
|
||||
Logger::trace(L"Launching new process");
|
||||
launch_process_and_named_pipe();
|
||||
}
|
||||
m_process_manager.start();
|
||||
|
||||
// hotkeyId in same order as set by get_hotkeys
|
||||
if (hotkeyId == 0)
|
||||
@@ -917,22 +760,22 @@ public:
|
||||
{ // m_advanced_paste_ui_hotkey
|
||||
Logger::trace(L"Setting start up event");
|
||||
|
||||
bring_process_to_front();
|
||||
send_named_pipe_message(CommonSharedConstants::ADVANCED_PASTE_SHOW_UI_MESSAGE);
|
||||
m_process_manager.bring_to_front();
|
||||
m_process_manager.send_message(CommonSharedConstants::ADVANCED_PASTE_SHOW_UI_MESSAGE);
|
||||
Trace::AdvancedPaste_Invoked(L"AdvancedPasteUI");
|
||||
return true;
|
||||
}
|
||||
if (hotkeyId == 2)
|
||||
{ // m_paste_as_markdown_hotkey
|
||||
Logger::trace(L"Starting paste as markdown directly");
|
||||
send_named_pipe_message(CommonSharedConstants::ADVANCED_PASTE_MARKDOWN_MESSAGE);
|
||||
m_process_manager.send_message(CommonSharedConstants::ADVANCED_PASTE_MARKDOWN_MESSAGE);
|
||||
Trace::AdvancedPaste_Invoked(L"MarkdownDirect");
|
||||
return true;
|
||||
}
|
||||
if (hotkeyId == 3)
|
||||
{ // m_paste_as_json_hotkey
|
||||
Logger::trace(L"Starting paste as json directly");
|
||||
send_named_pipe_message(CommonSharedConstants::ADVANCED_PASTE_JSON_MESSAGE);
|
||||
m_process_manager.send_message(CommonSharedConstants::ADVANCED_PASTE_JSON_MESSAGE);
|
||||
Trace::AdvancedPaste_Invoked(L"JsonDirect");
|
||||
return true;
|
||||
}
|
||||
@@ -947,7 +790,7 @@ public:
|
||||
|
||||
Trace::AdvancedPaste_Invoked(std::format(L"{}Direct", kebab_to_pascal_case(id)));
|
||||
|
||||
send_named_pipe_message(CommonSharedConstants::ADVANCED_PASTE_ADDITIONAL_ACTION_MESSAGE, id);
|
||||
m_process_manager.send_message(CommonSharedConstants::ADVANCED_PASTE_ADDITIONAL_ACTION_MESSAGE, id);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -958,7 +801,7 @@ public:
|
||||
|
||||
Logger::trace(L"Starting custom action id={}", id);
|
||||
|
||||
send_named_pipe_message(CommonSharedConstants::ADVANCED_PASTE_CUSTOM_ACTION_MESSAGE, std::to_wstring(id));
|
||||
m_process_manager.send_message(CommonSharedConstants::ADVANCED_PASTE_CUSTOM_ACTION_MESSAGE, std::to_wstring(id));
|
||||
Trace::AdvancedPaste_Invoked(L"CustomActionDirect");
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user