mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
## Summary of the Pull Request
**Part 5** of a [slow-running 7-part
refactor](https://github.com/microsoft/PowerToys/issues/35155#issuecomment-2583334110)
of the giant "Common" class in Mouse Without Borders into individual
classes with tighter private scope.
In this PR:
* Extract the "Common" code from the following files:
* ```Common.Clipboard.cs``` -> ```Clipboard.cs```
* ```Common.InitAndCleanup.cs``` -> ```InitAndCleanup.cs```
* Update references to the types in the new locations
* Update unit test to verify functionality has only changed in an
expected way
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] Partially addresses #35155
- [x] **Communication:** I've discussed this with core contributors
already. If work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [x] **Localization:** All end user facing strings can be localized
- no changes in this PR
- [x] **Dev docs:** Added/updated
- no changes in this PR
- [x] **New binaries:** Added on the required places
- no changes in this PR
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [x] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
- no changes in this PR
<!-- Provide a more detailed description of the PR, other things fixed
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
### Run manual tests from [Test Checklist
Template](5bc7201ae2/doc/releases/tests-checklist-template.md (mouse-without-borders)):
* Install PowerToys on two PCs in the same local network:
- [x] Verify that PowerToys is properly installed on both PCs.
- [x] Configure Windows Firewall Rules
- ```netsh advfirewall firewall add rule
name="PowerToys.MouseWithoutBorders" dir=in action=allow
program="C:\src\mc\PowerToys\x64\Debug\PowerToys.exe" enable=yes
remoteip=any profile=any protocol=tcp"```
* Setup Connection:
- [x] Open MWB's settings on the first PC and click the "New Key"
button. Verify that a new security key is generated.
- [x] Copy the generated security key and paste it in the corresponding
input field in the settings of MWB on the second PC. Also enter the name
of the first PC in the required field.
- [x] Press "Connect" and verify that the machine layout now includes
two PC tiles, each displaying their respective PC names.
* Verify Connection Status:
- [x] Ensure that the border of the remote PC turns green, indicating a
successful connection.
- [x] Enter an incorrect security key and verify that the border of the
remote PC turns red, indicating a failed connection.
* Test Remote Mouse/Keyboard Control:
- [x] With the PCs connected, test the mouse/keyboard control from one
PC to another. Verify that the mouse/keyboard inputs are correctly
registered on the other PC.
- [ ] Test remote mouse/keyboard control across all four PCs, if
available. Verify that inputs are correctly registered on each connected
PC when the mouse is active there.
- unable to test - only 2 machines available
* Test Remote Control with Elevated Apps:
- note - the main PowerToys.exe must be running as a **non**-admin for
these tests
- [x] Open an elevated app on one of the PCs. Verify that without "Use
Service" enabled, PowerToys does not control the elevated app.
- [x] Enable "Use Service" in MWB's settings (need to run PowerToys.exe
as admin to enable "Use Service", then restart PowerToys.exe as
non-admin). Verify that PowerToys can now control the elevated app
remotely. Verify that MWB processes are running as LocalSystem, while
the MWB helper process is running non-elevated.
- ```get-process -Name "PowerToys.MouseWithoutBorders*" -IncludeUserName
| format-table Id, ProcessName, UserName```
- [x] Process: ```PowerToys.MouseWithoutBorders.exe``` - running as
```SYSTEM```
- [x] Process: ```PowerToys.MouseWithoutBorders.Helper.exe``` - running
as current user
- ```get-service -Name "PowerToys.*" | ft Status, Name, UserName;
get-ciminstance -Class "Win32_Service" -Filter "Name like 'PowerToys%'"
| ft ProcessId, Name```
- [x] Service: ```PowerToys.MWB.Service``` - running as ```Local
System```
- [x] Toggle "Use Service" again, verify that each time you do that, the
MWB processes are restarted.
- [x] Run PowerToys elevated on one of the machines, verify that you can
control elevated apps remotely now on that machine.
* Test Module Enable Status:
- [x] For all combinations of "Use Service"/"Run PowerToys as admin",
try enabling/disabling MWB module and verify that it's indeed being
toggled using task manager.
* Test Disconnection/Reconnection:
- [x] Disconnect one of the PCs from network. Verify that the machine
layout updates to reflect the disconnection.
- [x] Do the same, but now by exiting PowerToys.
- [x] Start PowerToys again, verify that the PCs are reconnected.
* Test Various Local Network Conditions:
- [ ] Test MWB performance under various network conditions (e.g., low
bandwidth, high latency). Verify that the tool maintains a stable
connection and functions correctly.
* Clipboard Sharing:
- [x] Copy some text on one PC and verify that the same text can be
pasted on another PC.
- [x] Use the screenshot key and Win+Shift+S to take a screenshot on one
PC and verify that the screenshot can be pasted on another PC.
- [x] Copy a file in Windows Explorer and verify that the file can be
pasted on another PC. Make sure the file size is below 100MB.
- [x] Try to copy multiple files and directories and verify that it's
not possible (only the first selected file is being copied).
* Drag and Drop:
- [ ] Drag a file from Windows Explorer on one PC, cross the screen
border onto another PC, and release it there. Verify that the file is
copied to the other PC. Make sure the file size is below 100MB.
- [ ] While dragging the file, verify that a corresponding icon is
displayed under the mouse cursor.
- [ ] Without moving the mouse from one PC to the target PC, press
CTRL+ALT+F1/2/3/4 hotkey to switch to the target PC directly and verify
that file sharing/dropping is not working.
* Lock and Unlock with "Use Service" Enabled:
- [x] Enable "Use Service" in MWB's settings.
- [x] Lock a remote PC using Win+L, move the mouse to it remotely, and
try to unlock it. Verify that you can unlock the remote PC.
- [x] Disable "Use Service" in MWB's settings, lock the remote PC, move
the mouse to it remotely, and try to unlock it. Verify that you can't
unlock the remote PC.
* Test Settings:
- [ ] Change the rest of available settings on MWB page and verify that
each setting works as described.
### Group Policy Tests
See https://learn.microsoft.com/en-us/windows/powertoys/grouppolicy
- [ ] Install *.admx / *.adml and check settings behave as expected
- [ ] I'll expand the list of settings here when I get this far :-)
- [ ] HKEY_LOCAL_MACHINE\SOFTWARE\Policies\PowerToys
- [x] ConfigureEnabledUtilityMouseWithoutBorders
- [x] ```[missing]``` - "Activation -> Enable Mouse Without Borders"
enabled, with GPO warning hidden
- ```reg delete HKEY_LOCAL_MACHINE\SOFTWARE\Policies\PowerToys /v
ConfigureEnabledUtilityMouseWithoutBorders /f```
- [x] ```0``` - "Activation -> Enable Mouse Without Borders" set to
"off" and disabled, with GPO warning visible
- ```reg add HKEY_LOCAL_MACHINE\SOFTWARE\Policies\PowerToys /v
ConfigureEnabledUtilityMouseWithoutBorders /t REG_DWORD /d 0 /f```
- [x] ```1``` - "Activation -> Enable Mouse Without Borders" set to "on"
and disabled, with GPO warning visible
- ```reg add HKEY_LOCAL_MACHINE\SOFTWARE\Policies\PowerToys /v
ConfigureEnabledUtilityMouseWithoutBorders /t REG_DWORD /d 1 /f```
- [ ] MwbClipboardSharingEnabled
- [ ] MwbFileTransferEnabled
- [ ] MwbUseOriginalUserInterface
- [ ] MwbDisallowBlockingScreensaver
- [ ] MwbSameSubnetOnly
- [ ] MwbValidateRemoteIp
- [x] MwbDisableUserDefinedIpMappingRules
- [x] ```[missing]``` - "Advanced Settings -> IP address mapping"
enabled, with GPO warning hidden
- ```reg delete HKEY_LOCAL_MACHINE\SOFTWARE\Policies\PowerToys /v
MwbDisableUserDefinedIpMappingRules /f```
- [x] ```0``` - "Advanced Settings -> IP address mapping" enabled, with
GPO warning hidden
- ```reg add HKEY_LOCAL_MACHINE\SOFTWARE\Policies\PowerToys /v
MwbDisableUserDefinedIpMappingRules /t REG_DWORD /d 0 /f```
- [x] ```1``` - "Advanced Settings -> IP address mapping" disabled, with
GPO warning visible
- ```reg add HKEY_LOCAL_MACHINE\SOFTWARE\Policies\PowerToys /v
MwbDisableUserDefinedIpMappingRules /t REG_DWORD /d 1 /f```
- [x] MwbPolicyDefinedIpMappingRules
- [x] ```[missing]``` - "Advanced Settings -> IP address mapping"
enabled, with GPO warning and GPO values hidden
- ```reg delete HKEY_LOCAL_MACHINE\SOFTWARE\Policies\PowerToys /v
MwbPolicyDefinedIpMappingRules /f```
- [x] ```[empty value]``` - "Advanced Settings -> IP address mapping"
enabled, with GPO warning hidden and GPO values hidden
- ```reg add HKEY_LOCAL_MACHINE\SOFTWARE\Policies\PowerToys /v
MwbPolicyDefinedIpMappingRules /t REG_MULTI_SZ /d "" /f```
- [x] ```[non-empty value]``` - "Advanced Settings -> IP address
mapping" enabled, with GPO warning visible and GPO values visible
- ```reg add HKEY_LOCAL_MACHINE\SOFTWARE\Policies\PowerToys /v
MwbPolicyDefinedIpMappingRules /t REG_MULTI_SZ /d "aaa 10.0.0.1\0bbb
10.0.0.2" /f```
364 lines
15 KiB
C#
364 lines
15 KiB
C#
// Copyright (c) Microsoft Corporation
|
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
using System.Windows.Forms;
|
|
|
|
// <summary>
|
|
// Screen/Desktop helper functions.
|
|
// </summary>
|
|
// <history>
|
|
// 2008 created by Truong Do (ductdo).
|
|
// 2009-... modified by Truong Do (TruongDo).
|
|
// 2023- Included in PowerToys.
|
|
// </history>
|
|
using MouseWithoutBorders.Class;
|
|
using MouseWithoutBorders.Core;
|
|
|
|
using Thread = MouseWithoutBorders.Core.Thread;
|
|
|
|
namespace MouseWithoutBorders
|
|
{
|
|
// Desktops, and GetScreenConfig routines
|
|
internal partial class Common
|
|
{
|
|
private static MyRectangle newDesktopBounds;
|
|
private static MyRectangle newPrimaryScreenBounds;
|
|
private static string activeDesktop;
|
|
|
|
internal static string ActiveDesktop => Common.activeDesktop;
|
|
|
|
internal static void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
|
|
{
|
|
GetScreenConfig();
|
|
}
|
|
|
|
internal static readonly List<Point> SensitivePoints = new();
|
|
|
|
private static bool MonitorEnumProc(IntPtr hMonitor, IntPtr hdcMonitor, ref NativeMethods.RECT lprcMonitor, IntPtr dwData)
|
|
{
|
|
// lprcMonitor is wrong!!! => using GetMonitorInfo(...)
|
|
// Log(String.Format( CultureInfo.CurrentCulture,"MONITOR: l{0}, t{1}, r{2}, b{3}", lprcMonitor.Left, lprcMonitor.Top, lprcMonitor.Right, lprcMonitor.Bottom));
|
|
NativeMethods.MonitorInfoEx mi = default;
|
|
mi.cbSize = Marshal.SizeOf(mi);
|
|
_ = NativeMethods.GetMonitorInfo(hMonitor, ref mi);
|
|
|
|
try
|
|
{
|
|
// For logging only
|
|
_ = NativeMethods.GetDpiForMonitor(hMonitor, 0, out uint dpiX, out uint dpiY);
|
|
Logger.Log(string.Format(CultureInfo.CurrentCulture, "MONITOR: ({0}, {1}, {2}, {3}). DPI: ({4}, {5})", mi.rcMonitor.Left, mi.rcMonitor.Top, mi.rcMonitor.Right, mi.rcMonitor.Bottom, dpiX, dpiY));
|
|
}
|
|
catch (DllNotFoundException)
|
|
{
|
|
Logger.Log("GetDpiForMonitor is unsupported in Windows 7 and lower.");
|
|
}
|
|
catch (EntryPointNotFoundException)
|
|
{
|
|
Logger.Log("GetDpiForMonitor is unsupported in Windows 7 and lower.");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Logger.Log(e);
|
|
}
|
|
|
|
if (mi.rcMonitor.Left == 0 && mi.rcMonitor.Top == 0 && mi.rcMonitor.Right != 0 && mi.rcMonitor.Bottom != 0)
|
|
{
|
|
// Primary screen
|
|
_ = Interlocked.Exchange(ref screenWidth, mi.rcMonitor.Right - mi.rcMonitor.Left);
|
|
_ = Interlocked.Exchange(ref screenHeight, mi.rcMonitor.Bottom - mi.rcMonitor.Top);
|
|
|
|
newPrimaryScreenBounds.Left = mi.rcMonitor.Left;
|
|
newPrimaryScreenBounds.Top = mi.rcMonitor.Top;
|
|
newPrimaryScreenBounds.Right = mi.rcMonitor.Right;
|
|
newPrimaryScreenBounds.Bottom = mi.rcMonitor.Bottom;
|
|
}
|
|
else
|
|
{
|
|
if (mi.rcMonitor.Left < newDesktopBounds.Left)
|
|
{
|
|
newDesktopBounds.Left = mi.rcMonitor.Left;
|
|
}
|
|
|
|
if (mi.rcMonitor.Top < newDesktopBounds.Top)
|
|
{
|
|
newDesktopBounds.Top = mi.rcMonitor.Top;
|
|
}
|
|
|
|
if (mi.rcMonitor.Right > newDesktopBounds.Right)
|
|
{
|
|
newDesktopBounds.Right = mi.rcMonitor.Right;
|
|
}
|
|
|
|
if (mi.rcMonitor.Bottom > newDesktopBounds.Bottom)
|
|
{
|
|
newDesktopBounds.Bottom = mi.rcMonitor.Bottom;
|
|
}
|
|
}
|
|
|
|
lock (SensitivePoints)
|
|
{
|
|
SensitivePoints.Add(new Point(mi.rcMonitor.Left, mi.rcMonitor.Top));
|
|
SensitivePoints.Add(new Point(mi.rcMonitor.Right, mi.rcMonitor.Top));
|
|
SensitivePoints.Add(new Point(mi.rcMonitor.Right, mi.rcMonitor.Bottom));
|
|
SensitivePoints.Add(new Point(mi.rcMonitor.Left, mi.rcMonitor.Bottom));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
internal static void GetScreenConfig()
|
|
{
|
|
try
|
|
{
|
|
Logger.LogDebug("==================== GetScreenConfig started");
|
|
newDesktopBounds = new MyRectangle();
|
|
newPrimaryScreenBounds = new MyRectangle();
|
|
newDesktopBounds.Left = newPrimaryScreenBounds.Left = Screen.PrimaryScreen.Bounds.Left;
|
|
newDesktopBounds.Top = newPrimaryScreenBounds.Top = Screen.PrimaryScreen.Bounds.Top;
|
|
newDesktopBounds.Right = newPrimaryScreenBounds.Right = Screen.PrimaryScreen.Bounds.Right;
|
|
newDesktopBounds.Bottom = newPrimaryScreenBounds.Bottom = Screen.PrimaryScreen.Bounds.Bottom;
|
|
|
|
Logger.Log(string.Format(
|
|
CultureInfo.CurrentCulture,
|
|
"logon = {0} PrimaryScreenBounds = {1},{2},{3},{4} desktopBounds = {5},{6},{7},{8}",
|
|
Common.RunOnLogonDesktop,
|
|
Common.newPrimaryScreenBounds.Left,
|
|
Common.newPrimaryScreenBounds.Top,
|
|
Common.newPrimaryScreenBounds.Right,
|
|
Common.newPrimaryScreenBounds.Bottom,
|
|
Common.newDesktopBounds.Left,
|
|
Common.newDesktopBounds.Top,
|
|
Common.newDesktopBounds.Right,
|
|
Common.newDesktopBounds.Bottom));
|
|
|
|
#if USE_MANAGED_ROUTINES
|
|
// Managed routines do not work well when running on secure desktop:(
|
|
screenWidth = Screen.PrimaryScreen.Bounds.Width;
|
|
screenHeight = Screen.PrimaryScreen.Bounds.Height;
|
|
screenCount = Screen.AllScreens.Length;
|
|
for (int i = 0; i < Screen.AllScreens.Length; i++)
|
|
{
|
|
if (Screen.AllScreens[i].Bounds.Left < desktopBounds.Left) desktopBounds.Left = Screen.AllScreens[i].Bounds.Left;
|
|
if (Screen.AllScreens[i].Bounds.Top < desktopBounds.Top) desktopBounds.Top = Screen.AllScreens[i].Bounds.Top;
|
|
if (Screen.AllScreens[i].Bounds.Right > desktopBounds.Right) desktopBounds.Right = Screen.AllScreens[i].Bounds.Right;
|
|
if (Screen.AllScreens[i].Bounds.Bottom > desktopBounds.Bottom) desktopBounds.Bottom = Screen.AllScreens[i].Bounds.Bottom;
|
|
}
|
|
#else
|
|
lock (SensitivePoints)
|
|
{
|
|
SensitivePoints.Clear();
|
|
}
|
|
|
|
NativeMethods.EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, MonitorEnumProc, IntPtr.Zero);
|
|
|
|
// 1000 calls to EnumDisplayMonitors cost a dozen of milliseconds
|
|
#endif
|
|
Interlocked.Exchange(ref MachineStuff.desktopBounds, newDesktopBounds);
|
|
Interlocked.Exchange(ref MachineStuff.primaryScreenBounds, newPrimaryScreenBounds);
|
|
|
|
Logger.Log(string.Format(
|
|
CultureInfo.CurrentCulture,
|
|
"logon = {0} PrimaryScreenBounds = {1},{2},{3},{4} desktopBounds = {5},{6},{7},{8}",
|
|
Common.RunOnLogonDesktop,
|
|
MachineStuff.PrimaryScreenBounds.Left,
|
|
MachineStuff.PrimaryScreenBounds.Top,
|
|
MachineStuff.PrimaryScreenBounds.Right,
|
|
MachineStuff.PrimaryScreenBounds.Bottom,
|
|
MachineStuff.DesktopBounds.Left,
|
|
MachineStuff.DesktopBounds.Top,
|
|
MachineStuff.DesktopBounds.Right,
|
|
MachineStuff.DesktopBounds.Bottom));
|
|
|
|
Logger.Log("==================== GetScreenConfig ended");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Logger.Log(e);
|
|
}
|
|
}
|
|
|
|
#if USING_SCREEN_SAVER_ROUTINES
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
|
private static extern int PostMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
|
private static extern IntPtr OpenDesktop(string hDesktop, int Flags, bool Inherit, UInt32 DesiredAccess);
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
|
private static extern bool CloseDesktop(IntPtr hDesktop);
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
|
private static extern bool EnumDesktopWindows( IntPtr hDesktop, EnumDesktopWindowsProc callback, IntPtr lParam);
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
|
private static extern bool IsWindowVisible(IntPtr hWnd);
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
|
private static extern bool SystemParametersInfo(int uAction, int uParam, ref int pvParam, int flags);
|
|
|
|
private delegate bool EnumDesktopWindowsProc(IntPtr hDesktop, IntPtr lParam);
|
|
private const int WM_CLOSE = 16;
|
|
private const int SPI_GETSCREENSAVERRUNNING = 114;
|
|
|
|
internal static bool IsScreenSaverRunning()
|
|
{
|
|
int isRunning = 0;
|
|
SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0,ref isRunning, 0);
|
|
return (isRunning != 0);
|
|
}
|
|
|
|
internal static void CloseScreenSaver()
|
|
{
|
|
IntPtr hDesktop = OpenDesktop("Screen-saver", 0, false, DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS);
|
|
if (hDesktop != IntPtr.Zero)
|
|
{
|
|
LogDebug("Closing screen saver...");
|
|
EnumDesktopWindows(hDesktop, new EnumDesktopWindowsProc(CloseScreenSaverFunc), IntPtr.Zero);
|
|
CloseDesktop(hDesktop);
|
|
}
|
|
}
|
|
|
|
private static bool CloseScreenSaverFunc(IntPtr hWnd, IntPtr lParam)
|
|
{
|
|
if (IsWindowVisible(hWnd))
|
|
{
|
|
LogDebug("Posting WM_CLOSE to " + hWnd.ToString(CultureInfo.InvariantCulture));
|
|
PostMessage(hWnd, WM_CLOSE, 0, 0);
|
|
}
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
internal static string GetMyDesktop()
|
|
{
|
|
byte[] arThreadDesktop = new byte[256];
|
|
IntPtr hD = NativeMethods.GetThreadDesktop(NativeMethods.GetCurrentThreadId());
|
|
if (hD != IntPtr.Zero)
|
|
{
|
|
_ = NativeMethods.GetUserObjectInformation(hD, NativeMethods.UOI_NAME, arThreadDesktop, arThreadDesktop.Length, out _);
|
|
return GetString(arThreadDesktop).Replace("\0", string.Empty);
|
|
}
|
|
|
|
return string.Empty;
|
|
}
|
|
|
|
internal static string GetInputDesktop()
|
|
{
|
|
byte[] arInputDesktop = new byte[256];
|
|
IntPtr hD = NativeMethods.OpenInputDesktop(0, false, NativeMethods.DESKTOP_READOBJECTS);
|
|
if (hD != IntPtr.Zero)
|
|
{
|
|
_ = NativeMethods.GetUserObjectInformation(hD, NativeMethods.UOI_NAME, arInputDesktop, arInputDesktop.Length, out _);
|
|
return GetString(arInputDesktop).Replace("\0", string.Empty);
|
|
}
|
|
|
|
return string.Empty;
|
|
}
|
|
|
|
internal static void StartMMService(string desktopToRunMouseWithoutBordersOn)
|
|
{
|
|
if (!Common.RunWithNoAdminRight)
|
|
{
|
|
Logger.LogDebug("*** Starting on active Desktop: " + desktopToRunMouseWithoutBordersOn);
|
|
Service.StartMouseWithoutBordersService(desktopToRunMouseWithoutBordersOn);
|
|
}
|
|
}
|
|
|
|
internal static void CheckForDesktopSwitchEvent(bool cleanupIfExit)
|
|
{
|
|
try
|
|
{
|
|
if (!IsMyDesktopActive() || Common.CurrentProcess.SessionId != NativeMethods.WTSGetActiveConsoleSessionId())
|
|
{
|
|
Helper.RunDDHelper(true);
|
|
int waitCount = 20;
|
|
|
|
while (NativeMethods.WTSGetActiveConsoleSessionId() == 0xFFFFFFFF && waitCount > 0)
|
|
{
|
|
waitCount--;
|
|
Logger.LogDebug("The session is detached/attached.");
|
|
Thread.Sleep(500);
|
|
}
|
|
|
|
string myDesktop = GetMyDesktop();
|
|
activeDesktop = GetInputDesktop();
|
|
|
|
Logger.LogDebug("*** Active Desktop = " + activeDesktop);
|
|
Logger.LogDebug("*** My Desktop = " + myDesktop);
|
|
|
|
if (myDesktop.Equals(activeDesktop, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
Logger.LogDebug("*** Active Desktop == My Desktop (TS session)");
|
|
}
|
|
|
|
if (!activeDesktop.Equals("winlogon", StringComparison.OrdinalIgnoreCase) &&
|
|
!activeDesktop.Equals("default", StringComparison.OrdinalIgnoreCase) &&
|
|
!activeDesktop.Equals("disconnect", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
try
|
|
{
|
|
StartMMService(activeDesktop);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Logger.Log($"{nameof(CheckForDesktopSwitchEvent)}: {e}");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!myDesktop.Equals(activeDesktop, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
Logger.Log("*** Active Desktop <> My Desktop");
|
|
}
|
|
|
|
uint sid = NativeMethods.WTSGetActiveConsoleSessionId();
|
|
|
|
if (Process.GetProcessesByName(Common.BinaryName).Any(p => (uint)p.SessionId == sid))
|
|
{
|
|
Logger.Log("Found MouseWithoutBorders on the active session!");
|
|
}
|
|
else
|
|
{
|
|
Logger.Log("MouseWithoutBorders not found on the active session!");
|
|
StartMMService(null);
|
|
}
|
|
}
|
|
|
|
if (!myDesktop.Equals("winlogon", StringComparison.OrdinalIgnoreCase) &&
|
|
!myDesktop.Equals("default", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
Logger.LogDebug("*** Desktop inactive, exiting: " + myDesktop);
|
|
Setting.Values.LastX = JUST_GOT_BACK_FROM_SCREEN_SAVER;
|
|
if (cleanupIfExit)
|
|
{
|
|
InitAndCleanup.Cleanup();
|
|
}
|
|
|
|
Process.GetCurrentProcess().KillProcess();
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Logger.Log(e);
|
|
}
|
|
}
|
|
|
|
private static Point p;
|
|
|
|
internal static bool IsMyDesktopActive()
|
|
{
|
|
return NativeMethods.GetCursorPos(ref p);
|
|
}
|
|
}
|
|
}
|