Compare commits

...

4 Commits

Author SHA1 Message Date
Alekhya
2ba99d14e1 Launcher hot fixes (#4003)
* Add resource only when it is not already present (#3842)

(cherry picked from commit d2dfbff832)

* Take space into consideration while calculating the first matched index (#3874)

(cherry picked from commit a8d67a1c60)

* Fix for File explorer not showing up and multiple notepads (#3969)

* reverted the dedup code, file explorer shows up but so do duplicates

* Fixed file explorer and dedup

* Formatting

* Added tests for all the cases

* Formatting

* Tests

* take name and exe into consideration while calculating hash

* unique primes while calculating hash code

(cherry picked from commit 8cddd595d4)
2020-06-03 09:11:39 -07:00
Enrico Giordani
bbbbf0954d [CDPx] publish symbols (#4016) 2020-06-03 09:11:11 -07:00
Enrico Giordani
f81ccdda3d [runner] Change way of dropping privileges to start PT Run 2020-06-01 20:42:50 +02:00
Enrico Giordani
ef7285fb9a Now working on 0.18.2 (#3542) 2020-06-01 20:42:50 +02:00
19 changed files with 320 additions and 97 deletions

View File

@@ -41,6 +41,11 @@ build:
name: 'Build Power Toys'
command: '.pipelines\build.cmd'
artifacts:
- to: 'Symbols'
include:
- 'x64/**/*.pdb'
exclude:
- 'x64/Release/obj/**/*.pdb'
- from: 'x64/Release'
to: 'Build_Output'
include:
@@ -127,20 +132,6 @@ build:
- 'PowerToysSetup-*.msi'
signing_options:
sign_inline: true # This does signing a soon as this command completes
# - !!buildcommand
# name: 'Archive symbols to Symbol Server'
# artifacts:
# - to: 'x64 Symbols'
# include:
# - 'x64/Release/action_runner.pdb'
# - 'x64/Release/Notifications.pdb'
# - 'x64/Release/PowerRenameUWPUI.pdb'
# - 'x64/Release/PowerToys.pdb'
# - 'x64/Release/PowerToysSettings.pdb'
# - 'x64/Release/modules/fancyzones.pdb'
# - 'x64/Release/modules/FancyZonesEditor.pdb'
# - 'x64/Release/modules/PowerRenameExt.pdb'
# - 'x64/Release/modules/shortcut_guide.pdb'
package:
commands:

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Version>0.18.1</Version>
<Version>0.18.2</Version>
<DefineConstants>Version=$(Version);</DefineConstants>
</PropertyGroup>
</Project>

View File

@@ -186,26 +186,23 @@ int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
}
std::wstring_view action{ args[1] };
if (action == L"-start_PowerLauncher")
{
if (is_process_elevated(false) == true)
{
drop_elevated_privileges();
}
HANDLE hMapFile = OpenFileMappingW(FILE_MAP_WRITE, FALSE, POWER_LAUNCHER_PID_SHARED_FILE);
PDWORD pidBuffer = reinterpret_cast<PDWORD>(MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(DWORD)));
if (pidBuffer)
if (hMapFile)
{
*pidBuffer = 0;
run_non_elevated(L"modules\\launcher\\PowerLauncher.exe", L"", pidBuffer);
FlushViewOfFile(pidBuffer, sizeof(DWORD));
UnmapViewOfFile(pidBuffer);
}
PDWORD pidBuffer = reinterpret_cast<PDWORD>(MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(DWORD)));
if (pidBuffer)
{
*pidBuffer = 0;
run_same_elevation(L"modules\\launcher\\PowerLauncher.exe", L"", pidBuffer);
FlushViewOfFile(pidBuffer, sizeof(DWORD));
UnmapViewOfFile(pidBuffer);
}
FlushFileBuffers(hMapFile);
CloseHandle(hMapFile);
FlushFileBuffers(hMapFile);
CloseHandle(hMapFile);
}
}
else if (action == L"-install_dotnet")
{

View File

@@ -510,8 +510,8 @@ bool run_non_elevated(const std::wstring& file, const std::wstring& params, DWOR
siex.lpAttributeList = pptal;
siex.StartupInfo.cb = sizeof(siex);
PROCESS_INFORMATION process_info = { 0 };
auto succedded = CreateProcessW(file.c_str(),
PROCESS_INFORMATION pi = { 0 };
auto succeeded = CreateProcessW(file.c_str(),
const_cast<LPWSTR>(executable_args.c_str()),
nullptr,
nullptr,
@@ -520,34 +520,38 @@ bool run_non_elevated(const std::wstring& file, const std::wstring& params, DWOR
nullptr,
nullptr,
&siex.StartupInfo,
&process_info);
if (process_info.hProcess)
&pi);
if (succeeded)
{
if (returnPid)
if (pi.hProcess)
{
*returnPid = GetProcessId(process_info.hProcess);
}
if (returnPid)
{
*returnPid = GetProcessId(pi.hProcess);
}
CloseHandle(process_info.hProcess);
CloseHandle(pi.hProcess);
}
if (pi.hThread)
{
CloseHandle(pi.hThread);
}
}
if (process_info.hThread)
{
CloseHandle(process_info.hThread);
}
return succedded;
return succeeded;
}
bool run_same_elevation(const std::wstring& file, const std::wstring& params)
bool run_same_elevation(const std::wstring& file, const std::wstring& params, DWORD* returnPid)
{
auto executable_args = L"\"" + file + L"\"";
if (!params.empty())
{
executable_args += L" " + params;
}
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
auto succedded = CreateProcessW(file.c_str(),
auto succeeded = CreateProcessW(file.c_str(),
const_cast<LPWSTR>(executable_args.c_str()),
nullptr,
nullptr,
@@ -557,15 +561,26 @@ bool run_same_elevation(const std::wstring& file, const std::wstring& params)
nullptr,
&si,
&pi);
if (pi.hProcess)
if (succeeded)
{
CloseHandle(pi.hProcess);
if (pi.hProcess)
{
if (returnPid)
{
*returnPid = GetProcessId(pi.hProcess);
}
CloseHandle(pi.hProcess);
}
if (pi.hThread)
{
CloseHandle(pi.hThread);
}
}
if (pi.hThread)
{
CloseHandle(pi.hThread);
}
return succedded;
return succeeded;
}
std::wstring get_process_path(HWND window) noexcept

View File

@@ -72,8 +72,8 @@ bool run_elevated(const std::wstring& file, const std::wstring& params);
// Run command as non-elevated user, returns true if succeeded, puts the process id into returnPid if returnPid != NULL
bool run_non_elevated(const std::wstring& file, const std::wstring& params, DWORD* returnPid);
// Run command with the same elevation, returns true if succedded
bool run_same_elevation(const std::wstring& file, const std::wstring& params);
// Run command with the same elevation, returns true if succeeded
bool run_same_elevation(const std::wstring& file, const std::wstring& params, DWORD* returnPid);
// Returns true if the current process is running from administrator account
bool check_user_is_admin();
@@ -137,4 +137,4 @@ struct overloaded : Ts...
template<class... Ts>
overloaded(Ts...)->overloaded<Ts...>;
#define POWER_LAUNCHER_PID_SHARED_FILE L"Global\\3cbfbad4-199b-4e2c-9825-942d5d3d3c74"
#define POWER_LAUNCHER_PID_SHARED_FILE L"Local\\3cbfbad4-199b-4e2c-9825-942d5d3d3c74"

View File

@@ -14,7 +14,7 @@ namespace Microsoft.PowerLauncher.Telemetry
/// <summary>
/// Gets The version string. TODO: This should be replaced by a P/Invoke call to get_product_version
/// </summary>
public string Version => "v0.18.1";
public string Version => "v0.18.2";
public double BootTimeMs { get; set; }

View File

@@ -14,7 +14,7 @@
<RepositoryUrl>https://github.com/microsoft/PowerToys</RepositoryUrl>
<RepositoryType>Github</RepositoryType>
<PackageTags>PowerToys</PackageTags>
<Version>0.15.2.0</Version>
<Version>0.18.2.0</Version>
<Platforms>x64</Platforms>
<ApplicationIcon>icon.ico</ApplicationIcon>
<Win32Resource />

View File

@@ -9,7 +9,7 @@
<Identity
Name="f4f787a5-f0ae-47a9-be89-5408b1dd2b47"
Publisher="CN=lamotile"
Version="0.15.2.0" />
Version="0.18.2.0" />
<mp:PhoneIdentity PhoneProductId="f4f787a5-f0ae-47a9-be89-5408b1dd2b47" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>

View File

@@ -132,7 +132,7 @@ public:
// Enable the powertoy
virtual void enable()
{
if (is_process_elevated(false) == false)
if (!is_process_elevated(false))
{
SHELLEXECUTEINFOW sei{ sizeof(sei) };
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
@@ -146,32 +146,34 @@ public:
{
std::wstring action_runner_path = get_module_folderpath();
action_runner_path += L"\\action_runner.exe";
SHELLEXECUTEINFOW sei{ sizeof(sei) };
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC };
sei.lpFile = action_runner_path.c_str();
sei.nShow = SW_SHOWNORMAL;
sei.lpParameters = L"-start_PowerLauncher";
// Set up the shared file from which to retrieve the PID of PowerLauncher
HANDLE hMapFile = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(DWORD), POWER_LAUNCHER_PID_SHARED_FILE);
PDWORD pidBuffer = reinterpret_cast<PDWORD>(MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(DWORD)));
*pidBuffer = 0;
m_hProcess = NULL;
ShellExecuteExW(&sei);
const int maxRetries = 20;
for (int retry = 0; retry < maxRetries; ++retry)
if (hMapFile)
{
Sleep(50);
DWORD pid = *pidBuffer;
if (pid)
PDWORD pidBuffer = reinterpret_cast<PDWORD>(MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(DWORD)));
if (pidBuffer)
{
m_hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
break;
}
}
*pidBuffer = 0;
m_hProcess = NULL;
CloseHandle(hMapFile);
if (run_non_elevated(action_runner_path, L"-start_PowerLauncher", nullptr))
{
const int maxRetries = 20;
for (int retry = 0; retry < maxRetries; ++retry)
{
Sleep(50);
DWORD pid = *pidBuffer;
if (pid)
{
m_hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
break;
}
}
}
}
CloseHandle(hMapFile);
}
}
m_enabled = true;

View File

@@ -449,6 +449,10 @@ namespace Microsoft.Plugin.Program.Programs
{
parsed = prefix + "//" + key;
}
else if (key.Contains("resources", StringComparison.OrdinalIgnoreCase))
{
parsed = prefix + key;
}
else
{
parsed = prefix + "///resources/" + key;

View File

@@ -443,6 +443,46 @@ namespace Microsoft.Plugin.Program.Programs
return entry;
}
public class removeDuplicatesComparer : IEqualityComparer<Win32>
{
public bool Equals(Win32 app1, Win32 app2)
{
if(!string.IsNullOrEmpty(app1.Name) && !string.IsNullOrEmpty(app2.Name)
&& !string.IsNullOrEmpty(app1.ExecutableName) && !string.IsNullOrEmpty(app2.ExecutableName)
&& !string.IsNullOrEmpty(app1.FullPath) && !string.IsNullOrEmpty(app2.FullPath))
{
return app1.Name.Equals(app2.Name, StringComparison.OrdinalIgnoreCase)
&& app1.ExecutableName.Equals(app2.ExecutableName, StringComparison.OrdinalIgnoreCase)
&& app1.FullPath.Equals(app2.FullPath, StringComparison.OrdinalIgnoreCase);
}
return false;
}
// Ref : https://stackoverflow.com/questions/2730865/how-do-i-calculate-a-good-hash-code-for-a-list-of-strings
public int GetHashCode(Win32 obj)
{
int namePrime = 13;
int executablePrime = 17;
int fullPathPrime = 31;
int result = 1;
result = result * namePrime + obj.Name.GetHashCode();
result = result * executablePrime + obj.ExecutableName.GetHashCode();
result = result * fullPathPrime + obj.FullPath.GetHashCode();
return result;
}
}
// Deduplication code
public static Func<ParallelQuery<Win32>, Win32[]> DeduplicatePrograms = (programs) =>
{
var uniqueExePrograms = programs.Where(x => !string.IsNullOrEmpty(x.LnkResolvedPath) || Extension(x.FullPath) != ExeExtension);
var uniquePrograms = uniqueExePrograms.Distinct(new removeDuplicatesComparer());
return uniquePrograms.ToArray();
};
public static Win32[] All(Settings settings)
{
try
@@ -464,15 +504,7 @@ namespace Microsoft.Plugin.Program.Programs
programs = programs.Concat(startMenu);
}
var programsWithoutLnk = programs.Where(x => string.IsNullOrEmpty(x.LnkResolvedPath));
var programsAsList = programs.ToList();
foreach(var app in programsWithoutLnk)
{
programsAsList.RemoveAll(x => (x.FullPath == app.FullPath) && string.IsNullOrEmpty(x.LnkResolvedPath));
}
return programsAsList.ToArray();
return DeduplicatePrograms(programs);
}
#if DEBUG //This is to make developer aware of any unhandled exception and add in handling.
catch (Exception e)

View File

@@ -10,7 +10,7 @@ namespace Microsoft.PowerLauncher.Telemetry
/// <summary>
/// TODO: This should be replaced by a P/Invoke call to get_product_version
/// </summary>
public string Version => "v0.18.1";
public string Version => "v0.18.2";
public double BootTimeMs { get; set; }

View File

@@ -83,9 +83,18 @@ namespace Wox.Infrastructure
bool allSubstringsContainedInCompareString = true;
var indexList = new List<int>();
List<int> spaceIndices = new List<int>();
for (var compareStringIndex = 0; compareStringIndex < fullStringToCompareWithoutCase.Length; compareStringIndex++)
{
// To maintain a list of indices which correspond to spaces in the string to compare
// To populate the list only for the first query substring
if (fullStringToCompareWithoutCase[compareStringIndex].Equals(' ') && currentQuerySubstringIndex == 0)
{
spaceIndices.Add(compareStringIndex);
}
if (fullStringToCompareWithoutCase[compareStringIndex] != currentQuerySubstring[currentQuerySubstringCharacterIndex])
{
matchFoundInPreviousLoop = false;
@@ -147,7 +156,8 @@ namespace Wox.Infrastructure
// proceed to calculate score if every char or substring without whitespaces matched
if (allQuerySubstringsMatched)
{
var score = CalculateSearchScore(query, stringToCompare, firstMatchIndex, lastMatchIndex - firstMatchIndex, allSubstringsContainedInCompareString);
var nearestSpaceIndex = CalculateClosestSpaceIndex(spaceIndices, firstMatchIndex);
var score = CalculateSearchScore(query, stringToCompare, firstMatchIndex - nearestSpaceIndex - 1, lastMatchIndex - firstMatchIndex, allSubstringsContainedInCompareString);
return new MatchResult(true, UserSettingSearchPrecision, indexList, score);
}
@@ -155,6 +165,21 @@ namespace Wox.Infrastructure
return new MatchResult (false, UserSettingSearchPrecision);
}
// To get the index of the closest space which preceeds the first matching index
private int CalculateClosestSpaceIndex(List<int> spaceIndices, int firstMatchIndex)
{
if(spaceIndices.Count == 0)
{
return -1;
}
else
{
int? ind = spaceIndices.OrderBy(item => (firstMatchIndex - item)).Where(item => firstMatchIndex > item).FirstOrDefault();
int closestSpaceIndex = ind ?? -1;
return closestSpaceIndex;
}
}
private static bool AllPreviousCharsMatched(int startIndexToVerify, int currentQuerySubstringCharacterIndex,
string fullStringToCompareWithoutCase, string currentQuerySubstring)
{

View File

@@ -187,8 +187,6 @@ namespace Wox.Test
[TestCase("sql manag", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
[TestCase("sql", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
[TestCase("sql serv", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
[TestCase("sqlserv", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)]
[TestCase("sql servman", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)]
[TestCase("sql serv man", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
[TestCase("sql studio", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
[TestCase("mic", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
@@ -224,5 +222,20 @@ namespace Wox.Test
$"Raw Score: {matchResult.RawScore}{Environment.NewLine}" +
$"Precision Score: {(int)expectedPrecisionScore}");
}
[TestCase("Windows Terminal", "Windows_Terminal", "term")]
[TestCase("Windows Terminal", "WindowsTerminal", "term")]
public void FuzzyMatchingScore_ShouldBeHigher_WhenPreceedingCharacterIsSpace(string firstCompareStr, string secondCompareStr, string query)
{
// Arrange
var matcher = new StringMatcher();
// Act
var firstScore = matcher.FuzzyMatch(query, firstCompareStr).Score;
var secondScore = matcher.FuzzyMatch(query, secondCompareStr).Score;
// Assert
Assert.IsTrue(firstScore > secondScore);
}
}
}

View File

@@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using NUnit.Framework;
using Wox.Infrastructure;
using Wox.Plugin;
using Microsoft.Plugin.Program.Programs;
using Moq;
using System.IO;
namespace Wox.Test.Plugins
{
[TestFixture]
public class ProgramPluginTest
{
Win32 notepad_appdata = new Win32
{
Name = "Notepad",
ExecutableName = "notepad.exe",
FullPath = "c:\\windows\\system32\\notepad.exe",
LnkResolvedPath = "c:\\users\\powertoys\\appdata\\roaming\\microsoft\\windows\\start menu\\programs\\accessories\\notepad.lnk"
};
Win32 notepad_users = new Win32
{
Name = "Notepad",
ExecutableName = "notepad.exe",
FullPath = "c:\\windows\\system32\\notepad.exe",
LnkResolvedPath = "c:\\programdata\\microsoft\\windows\\start menu\\programs\\accessories\\notepad.lnk"
};
Win32 azure_command_prompt = new Win32
{
Name = "Microsoft Azure Command Prompt - v2.9",
ExecutableName = "cmd.exe",
FullPath = "c:\\windows\\system32\\cmd.exe",
LnkResolvedPath = "c:\\programdata\\microsoft\\windows\\start menu\\programs\\microsoft azure\\microsoft azure sdk for .net\\v2.9\\microsoft azure command prompt - v2.9.lnk"
};
Win32 visual_studio_command_prompt = new Win32
{
Name = "x64 Native Tools Command Prompt for VS 2019",
ExecutableName = "cmd.exe",
FullPath = "c:\\windows\\system32\\cmd.exe",
LnkResolvedPath = "c:\\programdata\\microsoft\\windows\\start menu\\programs\\visual studio 2019\\visual studio tools\\vc\\x64 native tools command prompt for vs 2019.lnk"
};
Win32 command_prompt = new Win32
{
Name = "Command Prompt",
ExecutableName = "cmd.exe",
FullPath = "c:\\windows\\system32\\cmd.exe",
LnkResolvedPath ="c:\\users\\powertoys\\appdata\\roaming\\microsoft\\windows\\start menu\\programs\\system tools\\command prompt.lnk"
};
Win32 file_explorer = new Win32
{
Name = "File Explorer",
ExecutableName = "File Explorer.lnk",
FullPath = "c:\\users\\powertoys\\appdata\\roaming\\microsoft\\windows\\start menu\\programs\\system tools\\file explorer.lnk",
LnkResolvedPath = null
};
Win32 wordpad = new Win32
{
Name = "Wordpad",
ExecutableName = "wordpad.exe",
FullPath = "c:\\program files\\windows nt\\accessories\\wordpad.exe",
LnkResolvedPath = "c:\\programdata\\microsoft\\windows\\start menu\\programs\\accessories\\wordpad.lnk"
};
Win32 wordpad_duplicate = new Win32
{
Name = "WORDPAD",
ExecutableName = "WORDPAD.EXE",
FullPath = "c:\\program files\\windows nt\\accessories\\wordpad.exe",
LnkResolvedPath = null
};
[Test]
public void DedupFunction_whenCalled_mustRemoveDuplicateNotepads()
{
// Arrange
List<Win32> prgms = new List<Win32>();
prgms.Add(notepad_appdata);
prgms.Add(notepad_users);
// Act
Win32[] apps = Win32.DeduplicatePrograms(prgms.AsParallel());
// Assert
Assert.AreEqual(apps.Length, 1);
}
[Test]
public void DedupFunction_whenCalled_mustNotRemovelnkWhichdoesNotHaveExe()
{
// Arrange
List<Win32> prgms = new List<Win32>();
prgms.Add(file_explorer);
// Act
Win32[] apps = Win32.DeduplicatePrograms(prgms.AsParallel());
// Assert
Assert.AreEqual(apps.Length, 1);
}
[Test]
public void DedupFunction_mustRemoveDuplicates_forExeExtensionsWithoutLnkResolvedPath()
{
// Arrange
List<Win32> prgms = new List<Win32>();
prgms.Add(wordpad);
prgms.Add(wordpad_duplicate);
// Act
Win32[] apps = Win32.DeduplicatePrograms(prgms.AsParallel());
// Assert
Assert.AreEqual(apps.Length, 1);
Assert.IsTrue(!string.IsNullOrEmpty(apps[0].LnkResolvedPath));
}
[Test]
public void DedupFunction_mustNotRemovePrograms_withSameExeNameAndFullPath()
{
// Arrange
List<Win32> prgms = new List<Win32>();
prgms.Add(azure_command_prompt);
prgms.Add(visual_studio_command_prompt);
prgms.Add(command_prompt);
// Act
Win32[] apps = Win32.DeduplicatePrograms(prgms.AsParallel());
// Assert
Assert.AreEqual(apps.Length, 3);
}
}
}

View File

@@ -40,6 +40,7 @@
<ItemGroup>
<ProjectReference Include="..\Plugins\Microsoft.Plugin.Indexer\Microsoft.Plugin.Indexer.csproj" />
<ProjectReference Include="..\Plugins\Microsoft.Plugin.Program\Microsoft.Plugin.Program.csproj" />
<ProjectReference Include="..\Wox.Core\Wox.Core.csproj" />
<ProjectReference Include="..\Wox.Infrastructure\Wox.Infrastructure.csproj" />
<ProjectReference Include="..\Wox.Plugin\Wox.Plugin.csproj" />

View File

@@ -17,7 +17,7 @@ namespace MarkdownPreviewHandler.Telemetry.Events
/// <summary>
/// Gets The version string. TODO: This should be replaced by a P/Invoke call to get_product_version.
/// </summary>
public string Version => "v0.18.1";
public string Version => "v0.18.2";
/// <inheritdoc/>
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;

View File

@@ -17,7 +17,7 @@ namespace SvgPreviewHandler.Telemetry.Events
/// <summary>
/// Gets The version string. TODO: This should be replaced by a P/Invoke call to get_product_version.
/// </summary>
public string Version => "v0.18.1";
public string Version => "v0.18.2";
/// <inheritdoc/>
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;

View File

@@ -47,5 +47,5 @@ bool restart_same_elevation()
constexpr DWORD exe_path_size = 0xFFFF;
auto exe_path = std::make_unique<wchar_t[]>(exe_path_size);
GetModuleFileNameW(nullptr, exe_path.get(), exe_path_size);
return run_same_elevation(exe_path.get(), L"--dont-elevate");
return run_same_elevation(exe_path.get(), L"--dont-elevate", nullptr);
}