mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-06-07 17:42:45 +08:00
Update environment variables changed (#12689)
This commit is contained in:
parent
31a5d49246
commit
e87e06bae6
@ -0,0 +1,98 @@
|
|||||||
|
// 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;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security.Principal;
|
||||||
|
using Microsoft.Win32.SafeHandles;
|
||||||
|
using Wox.Plugin.Logger;
|
||||||
|
|
||||||
|
namespace PowerLauncher.Helper
|
||||||
|
{
|
||||||
|
public static class EnvironmentHelper
|
||||||
|
{
|
||||||
|
private const string EnvironmentChangeType = "Environment";
|
||||||
|
private const string Username = "USERNAME";
|
||||||
|
private const string ProcessorArchitecture = "PROCESSOR_ARCHITECTURE";
|
||||||
|
private const string Path = "PATH";
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA1801:Review unused parameters", Justification = "Params are required for delegate signature requirements.")]
|
||||||
|
public static IntPtr ProcessWindowMessages(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
|
||||||
|
{
|
||||||
|
switch ((WM)msg)
|
||||||
|
{
|
||||||
|
case WM.SETTINGCHANGE:
|
||||||
|
string changeType = Marshal.PtrToStringUni(lparam);
|
||||||
|
if (changeType == EnvironmentChangeType)
|
||||||
|
{
|
||||||
|
Log.Info("Reload environment", typeof(EnvironmentHelper));
|
||||||
|
UpdateEnvironment();
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateEnvironment()
|
||||||
|
{
|
||||||
|
// Username and process architecture are set by the machine vars, this
|
||||||
|
// may lead to incorrect values so save off the current values to restore.
|
||||||
|
string originalUsername = Environment.GetEnvironmentVariable(Username, EnvironmentVariableTarget.Process);
|
||||||
|
string originalArch = Environment.GetEnvironmentVariable(ProcessorArchitecture, EnvironmentVariableTarget.Process);
|
||||||
|
|
||||||
|
var environment = new Dictionary<string, string>();
|
||||||
|
MergeTargetEnvironmentVariables(environment, EnvironmentVariableTarget.Process);
|
||||||
|
MergeTargetEnvironmentVariables(environment, EnvironmentVariableTarget.Machine);
|
||||||
|
|
||||||
|
if (!IsRunningAsSystem())
|
||||||
|
{
|
||||||
|
MergeTargetEnvironmentVariables(environment, EnvironmentVariableTarget.User);
|
||||||
|
|
||||||
|
// Special handling for PATH - merge Machine & User instead of override
|
||||||
|
var pathTargets = new[] { EnvironmentVariableTarget.Machine, EnvironmentVariableTarget.User };
|
||||||
|
var paths = pathTargets
|
||||||
|
.Select(t => Environment.GetEnvironmentVariable(Path, t))
|
||||||
|
.Where(e => e != null)
|
||||||
|
.SelectMany(e => e.Split(';', StringSplitOptions.RemoveEmptyEntries))
|
||||||
|
.Distinct();
|
||||||
|
|
||||||
|
environment[Path] = string.Join(';', paths);
|
||||||
|
}
|
||||||
|
|
||||||
|
environment[Username] = originalUsername;
|
||||||
|
environment[ProcessorArchitecture] = originalArch;
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string, string> kv in environment)
|
||||||
|
{
|
||||||
|
Environment.SetEnvironmentVariable(kv.Key, kv.Value, EnvironmentVariableTarget.Process);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void MergeTargetEnvironmentVariables(
|
||||||
|
Dictionary<string, string> environment, EnvironmentVariableTarget target)
|
||||||
|
{
|
||||||
|
IDictionary variables = Environment.GetEnvironmentVariables(target);
|
||||||
|
foreach (DictionaryEntry entry in variables)
|
||||||
|
{
|
||||||
|
environment[(string)entry.Key] = (string)entry.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsRunningAsSystem()
|
||||||
|
{
|
||||||
|
using (var identity = WindowsIdentity.GetCurrent())
|
||||||
|
{
|
||||||
|
return identity.IsSystem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,7 @@ using System.ComponentModel;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Microsoft.Win32.SafeHandles;
|
||||||
using static PowerLauncher.Helper.WindowsInteropHelper;
|
using static PowerLauncher.Helper.WindowsInteropHelper;
|
||||||
|
|
||||||
// http://blogs.microsoft.co.il/arik/2010/05/28/wpf-single-instance-application/
|
// http://blogs.microsoft.co.il/arik/2010/05/28/wpf-single-instance-application/
|
||||||
@ -108,6 +109,7 @@ namespace PowerLauncher.Helper
|
|||||||
ERASEBKGND = 0x0014,
|
ERASEBKGND = 0x0014,
|
||||||
SYSCOLORCHANGE = 0x0015,
|
SYSCOLORCHANGE = 0x0015,
|
||||||
SHOWWINDOW = 0x0018,
|
SHOWWINDOW = 0x0018,
|
||||||
|
SETTINGCHANGE = 0x001A,
|
||||||
ACTIVATEAPP = 0x001C,
|
ACTIVATEAPP = 0x001C,
|
||||||
SETCURSOR = 0x0020,
|
SETCURSOR = 0x0020,
|
||||||
MOUSEACTIVATE = 0x0021,
|
MOUSEACTIVATE = 0x0021,
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
Icon="Images/app.dark.png"
|
Icon="Images/app.dark.png"
|
||||||
AllowsTransparency="True"
|
AllowsTransparency="True"
|
||||||
|
SourceInitialized="OnSourceInitialized"
|
||||||
Loaded="OnLoaded"
|
Loaded="OnLoaded"
|
||||||
Closing="OnClosing"
|
Closing="OnClosing"
|
||||||
Background="Transparent"
|
Background="Transparent"
|
||||||
|
@ -9,6 +9,7 @@ using System.Timers;
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Interop;
|
||||||
using interop;
|
using interop;
|
||||||
using Microsoft.PowerLauncher.Telemetry;
|
using Microsoft.PowerLauncher.Telemetry;
|
||||||
using Microsoft.PowerToys.Telemetry;
|
using Microsoft.PowerToys.Telemetry;
|
||||||
@ -29,8 +30,10 @@ namespace PowerLauncher
|
|||||||
private readonly MainViewModel _viewModel;
|
private readonly MainViewModel _viewModel;
|
||||||
private bool _isTextSetProgrammatically;
|
private bool _isTextSetProgrammatically;
|
||||||
private bool _deletePressed;
|
private bool _deletePressed;
|
||||||
|
private HwndSource _hwndSource;
|
||||||
private Timer _firstDeleteTimer = new Timer();
|
private Timer _firstDeleteTimer = new Timer();
|
||||||
private bool _coldStateHotkeyPressed;
|
private bool _coldStateHotkeyPressed;
|
||||||
|
private bool _disposedValue;
|
||||||
|
|
||||||
public MainWindow(PowerToysRunSettings settings, MainViewModel mainVM)
|
public MainWindow(PowerToysRunSettings settings, MainViewModel mainVM)
|
||||||
: this()
|
: this()
|
||||||
@ -93,6 +96,12 @@ namespace PowerLauncher
|
|||||||
Activate();
|
Activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnSourceInitialized(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
_hwndSource = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
|
||||||
|
_hwndSource.AddHook(EnvironmentHelper.ProcessWindowMessages);
|
||||||
|
}
|
||||||
|
|
||||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
private void OnLoaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
WindowsInteropHelper.DisableControlBox(this);
|
WindowsInteropHelper.DisableControlBox(this);
|
||||||
@ -359,8 +368,6 @@ namespace PowerLauncher
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool disposedValue;
|
|
||||||
|
|
||||||
private void QueryTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
private void QueryTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
{
|
{
|
||||||
var textBox = (TextBox)sender;
|
var textBox = (TextBox)sender;
|
||||||
@ -451,7 +458,7 @@ namespace PowerLauncher
|
|||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (!disposedValue)
|
if (!_disposedValue)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
@ -459,12 +466,14 @@ namespace PowerLauncher
|
|||||||
{
|
{
|
||||||
_firstDeleteTimer.Dispose();
|
_firstDeleteTimer.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_hwndSource?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
|
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
|
||||||
// TODO: set large fields to null
|
// TODO: set large fields to null
|
||||||
_firstDeleteTimer = null;
|
_firstDeleteTimer = null;
|
||||||
disposedValue = true;
|
_disposedValue = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user