mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-29 00:24:42 +01:00
fix version and win10 start error
This commit is contained in:
@@ -9,7 +9,7 @@ Param(
|
||||
[Parameter(Mandatory=$false)]
|
||||
[ValidateSet("Debug", "Release")]
|
||||
[string]$Configuration = "Release",
|
||||
|
||||
|
||||
[switch]$Clean,
|
||||
[switch]$ForceCert,
|
||||
[switch]$NoSign
|
||||
@@ -45,6 +45,7 @@ function Find-WindowsSDKTool {
|
||||
# Simple fallback: check common Windows SDK locations
|
||||
$commonPaths = @(
|
||||
"${env:ProgramFiles}\Windows Kits\10\bin\*\$Architecture\$ToolName",
|
||||
"${env:ProgramFiles(x86)}\Windows Kits\10\bin\*\$Architecture\$ToolName",
|
||||
"${env:ProgramFiles(x86)}\Windows Kits\10\bin\*\x86\$ToolName" # SignTool fallback
|
||||
)
|
||||
|
||||
@@ -62,12 +63,12 @@ function Find-WindowsSDKTool {
|
||||
}
|
||||
|
||||
function Test-CertificateValidity {
|
||||
param([string]$PfxPath, [string]$PasswordFile)
|
||||
param([string]$PfxPath, [string]$SecretFilePath)
|
||||
|
||||
if (-not (Test-Path $PfxPath) -or -not (Test-Path $PasswordFile)) { return $false }
|
||||
if (-not (Test-Path $PfxPath) -or -not (Test-Path $SecretFilePath)) { return $false }
|
||||
|
||||
try {
|
||||
$password = (Get-Content $PasswordFile -Raw).Trim()
|
||||
$password = (Get-Content $SecretFilePath -Raw).Trim()
|
||||
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($PfxPath, $password)
|
||||
$isValid = $cert.HasPrivateKey -and $cert.NotAfter -gt (Get-Date)
|
||||
$cert.Dispose()
|
||||
@@ -131,7 +132,7 @@ try {
|
||||
Get-ChildItem "Cert:\CurrentUser\My" -ErrorAction SilentlyContinue | Out-Null
|
||||
}
|
||||
} catch {
|
||||
Write-BuildLog "Note: Certificate provider setup may need manual configuration: $_" -Level Warning
|
||||
Write-BuildLog ("Note: Certificate provider setup may need manual configuration: {0}" -f $_) -Level Warning
|
||||
}
|
||||
|
||||
# Project root folder (now set to current script folder for local builds)
|
||||
@@ -163,7 +164,7 @@ if ($ForceCert -and (Test-Path $UserFolder)) {
|
||||
}
|
||||
|
||||
# Ensure dev cert (development only; not for production use) - skip if NoSign specified
|
||||
$needNewCert = -not $NoSign -and (-not (Test-Path $CertPfxFile) -or $ForceCert -or -not (Test-CertificateValidity -PfxPath $CertPfxFile -PasswordFile $CertPwdFile))
|
||||
$needNewCert = -not $NoSign -and (-not (Test-Path $CertPfxFile) -or $ForceCert -or -not (Test-CertificateValidity -PfxPath $CertPfxFile -SecretFilePath $CertPwdFile))
|
||||
|
||||
if ($needNewCert) {
|
||||
Write-BuildLog "Generating development certificate (prefix=$($script:Config.CertPrefix))..." -Level Info
|
||||
@@ -212,6 +213,30 @@ $sparseDir = $PSScriptRoot
|
||||
$manifestPath = Join-Path $sparseDir 'AppxManifest.xml'
|
||||
if (-not (Test-Path $manifestPath)) { throw "Missing AppxManifest.xml in PackageIdentity folder: $manifestPath" }
|
||||
|
||||
$versionPropsPath = Join-Path $PowerToysRoot 'src\Version.props'
|
||||
$targetManifestVersion = $null
|
||||
$versionCandidate = $null
|
||||
if (Test-Path $versionPropsPath) {
|
||||
try {
|
||||
[xml]$propsXml = Get-Content -Path $versionPropsPath -Raw
|
||||
$versionCandidate = $propsXml.Project.PropertyGroup.Version
|
||||
} catch {
|
||||
Write-BuildLog ("Unable to read version from {0}: {1}" -f $versionPropsPath, $_) -Level Warning
|
||||
}
|
||||
} else {
|
||||
Write-BuildLog "Version.props not found at $versionPropsPath; manifest version will remain unchanged." -Level Warning
|
||||
}
|
||||
|
||||
if ($versionCandidate) {
|
||||
$targetManifestVersion = $versionCandidate.Trim()
|
||||
if (($targetManifestVersion -split '\.').Count -lt 4) {
|
||||
$targetManifestVersion = "$targetManifestVersion.0"
|
||||
}
|
||||
Write-BuildLog "Using sparse package version from Version.props: $targetManifestVersion" -Level Info
|
||||
} else {
|
||||
Write-BuildLog "No version value provided; manifest version will remain unchanged." -Level Info
|
||||
}
|
||||
|
||||
# Find MakeAppx.exe from Windows SDK
|
||||
try {
|
||||
$makeAppxPath = Find-WindowsSDKTool -ToolName "makeappx.exe" -Architecture $Platform
|
||||
@@ -230,7 +255,7 @@ if (Test-Path $msixPath) {
|
||||
Remove-Item $msixPath -Force -ErrorAction Stop
|
||||
Write-BuildLog "Successfully removed existing MSIX file" -Level Success
|
||||
} catch {
|
||||
Write-BuildLog "Warning: Could not remove existing MSIX file: $_" -Level Warning
|
||||
Write-BuildLog ("Warning: Could not remove existing MSIX file: {0}" -f $_) -Level Warning
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,6 +302,37 @@ try {
|
||||
}
|
||||
}
|
||||
|
||||
# Ensure publisher matches the dev certificate for local builds
|
||||
$manifestStagingPath = Join-Path $stagingDir 'AppxManifest.xml'
|
||||
$shouldUseDevPublisher = $env:CIBuild -ne 'true'
|
||||
if (Test-Path $manifestStagingPath) {
|
||||
try {
|
||||
[xml]$manifestXml = Get-Content -Path $manifestStagingPath -Raw
|
||||
$identityNode = $manifestXml.Package.Identity
|
||||
$manifestChanged = $false
|
||||
|
||||
if ($identityNode) {
|
||||
if ($targetManifestVersion -and $identityNode.Version -ne $targetManifestVersion) {
|
||||
Write-BuildLog "Updating manifest version to $targetManifestVersion" -Level Info
|
||||
$identityNode.SetAttribute('Version', $targetManifestVersion)
|
||||
$manifestChanged = $true
|
||||
}
|
||||
|
||||
if ($shouldUseDevPublisher -and $identityNode.Publisher -ne $script:Config.CertSubject) {
|
||||
Write-BuildLog "Updating manifest publisher for local build" -Level Warning
|
||||
$identityNode.SetAttribute('Publisher', $script:Config.CertSubject)
|
||||
$manifestChanged = $true
|
||||
}
|
||||
}
|
||||
|
||||
if ($manifestChanged) {
|
||||
$manifestXml.Save($manifestStagingPath)
|
||||
}
|
||||
} catch {
|
||||
Write-BuildLog ("Unable to adjust manifest metadata: {0}" -f $_) -Level Warning
|
||||
}
|
||||
}
|
||||
|
||||
Write-BuildLog "Staging directory prepared with essential files only" -Level Success
|
||||
|
||||
# Pack MSIX using staging directory
|
||||
@@ -297,7 +353,7 @@ try {
|
||||
Remove-Item $stagingDir -Recurse -Force -ErrorAction SilentlyContinue
|
||||
Write-BuildLog "Cleaned up staging directory" -Level Info
|
||||
} catch {
|
||||
Write-BuildLog "Warning: Could not clean up staging directory: $_" -Level Warning
|
||||
Write-BuildLog ("Warning: Could not clean up staging directory: {0}" -f $_) -Level Warning
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -332,5 +388,5 @@ if ($NoSign) {
|
||||
}
|
||||
|
||||
Write-BuildLog "Register sparse package:" -Level Info
|
||||
Write-BuildLog " Add-AppxPackage -Register `"$msixPath`" -ExternalLocation `"$outDir`"" -Level Warning
|
||||
Write-BuildLog " Add-AppxPackage -Path `"$msixPath`" -ExternalLocation `"$outDir`"" -Level Warning
|
||||
Write-BuildLog "(If already installed and you changed manifest only): Add-AppxPackage -Register `"$manifestPath`" -ExternalLocation `"$outDir`" -ForceApplicationShutdown" -Level Warning
|
||||
|
||||
43
src/PackageIdentity/Check-ProcessIdentity.ps1
Normal file
43
src/PackageIdentity/Check-ProcessIdentity.ps1
Normal file
@@ -0,0 +1,43 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Determine whether a given process (by PID) runs with an MSIX/UWP package identity.
|
||||
.DESCRIPTION
|
||||
Calls the Windows API GetPackageFullName to check if the target process executes under an MSIX/Sparse App/UWP package identity.
|
||||
Returns the package full name when identity is present, or "No package identity" otherwise.
|
||||
.PARAMETER ProcessId
|
||||
The process ID to inspect.
|
||||
.EXAMPLE
|
||||
.\Check-ProcessIdentity.ps1 -pid 12345
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[int]$ProcessId
|
||||
)
|
||||
|
||||
Add-Type -TypeDefinition @'
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
public class P {
|
||||
[DllImport("kernel32.dll", SetLastError=true)]
|
||||
public static extern IntPtr OpenProcess(uint a, bool b, int p);
|
||||
[DllImport("kernel32.dll", SetLastError=true)]
|
||||
public static extern bool CloseHandle(IntPtr h);
|
||||
[DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
|
||||
public static extern int GetPackageFullName(IntPtr h, ref int l, StringBuilder b);
|
||||
public static string G(int pid) {
|
||||
IntPtr h = OpenProcess(0x1000, false, pid);
|
||||
if (h == IntPtr.Zero) return "Failed to open process";
|
||||
int len = 0;
|
||||
GetPackageFullName(h, ref len, null);
|
||||
if (len == 0) { CloseHandle(h); return "No package identity"; }
|
||||
var sb = new StringBuilder(len);
|
||||
int r = GetPackageFullName(h, ref len, sb);
|
||||
CloseHandle(h);
|
||||
return r == 0 ? sb.ToString() : "Error:" + r;
|
||||
}
|
||||
}
|
||||
'@
|
||||
|
||||
$result = [P]::G($ProcessId)
|
||||
Write-Output $result
|
||||
@@ -15,7 +15,7 @@
|
||||
<NoSignParam Condition="'$(Configuration)' != 'Debug' AND '$(NoSignCI)' != 'true'"></NoSignParam>
|
||||
</PropertyGroup>
|
||||
|
||||
<Exec Command="powershell -NonInteractive -ExecutionPolicy Bypass -File "$(MSBuildThisFileDirectory)BuildSparsePackage.ps1" -Platform $(Platform) -Configuration $(Configuration) $(NoSignParam)"
|
||||
<Exec Command="powershell -NonInteractive -ExecutionPolicy Bypass -File "$(MSBuildThisFileDirectory)BuildSparsePackage.ps1" -Platform $(Platform) -Configuration $(Configuration) $(NoSignParam)"
|
||||
ContinueOnError="false"
|
||||
WorkingDirectory="$(MSBuildThisFileDirectory)" />
|
||||
</Target>
|
||||
@@ -94,6 +94,7 @@
|
||||
<None Include="AppxManifest.xml" />
|
||||
<None Include="BuildSparsePackage.ps1" />
|
||||
<None Include="BuildSparsePackage.cmd" />
|
||||
<None Include="Check-ProcessIdentity.ps1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -101,16 +101,16 @@ HRESULT CContextMenuHandler::QueryContextMenu(_In_ HMENU hmenu, UINT indexMenu,
|
||||
AssocGetPerceivedType(pszExt, &type, &flag, NULL);
|
||||
|
||||
free(pszPath);
|
||||
|
||||
bool dragDropFlag = false;
|
||||
// If selected file is an image...
|
||||
if (type == PERCEIVED_TYPE_IMAGE)
|
||||
{
|
||||
HRESULT hr = E_UNEXPECTED;
|
||||
wchar_t strResizePictures[128] = { 0 };
|
||||
// If handling drag-and-drop...
|
||||
wchar_t strResizePictures[128] = {};
|
||||
|
||||
if (m_pidlFolder)
|
||||
{
|
||||
dragDropFlag=true;
|
||||
dragDropFlag = true;
|
||||
wcscpy_s(strResizePictures, ARRAYSIZE(strResizePictures), context_menu_caption_here.c_str());
|
||||
}
|
||||
else
|
||||
@@ -118,13 +118,15 @@ HRESULT CContextMenuHandler::QueryContextMenu(_In_ HMENU hmenu, UINT indexMenu,
|
||||
wcscpy_s(strResizePictures, ARRAYSIZE(strResizePictures), context_menu_caption.c_str());
|
||||
}
|
||||
|
||||
MENUITEMINFO mii;
|
||||
MENUITEMINFO mii{};
|
||||
mii.cbSize = sizeof(MENUITEMINFO);
|
||||
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_STATE;
|
||||
mii.wID = idCmdFirst + ID_RESIZE_PICTURES;
|
||||
mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STATE | MIIM_STRING;
|
||||
mii.fType = MFT_STRING;
|
||||
mii.dwTypeData = (PWSTR)strResizePictures;
|
||||
mii.wID = idCmdFirst + ID_RESIZE_PICTURES;
|
||||
mii.dwTypeData = strResizePictures;
|
||||
mii.cch = ARRAYSIZE(strResizePictures);
|
||||
mii.fState = MFS_ENABLED;
|
||||
|
||||
HICON hIcon = static_cast<HICON>(LoadImage(g_hInst_imageResizer, MAKEINTRESOURCE(IDI_RESIZE_PICTURES), IMAGE_ICON, 16, 16, 0));
|
||||
if (hIcon)
|
||||
{
|
||||
@@ -139,21 +141,14 @@ HRESULT CContextMenuHandler::QueryContextMenu(_In_ HMENU hmenu, UINT indexMenu,
|
||||
|
||||
if (dragDropFlag)
|
||||
{
|
||||
// Insert the menu entry at indexMenu+1 since the first entry should be "Copy here"
|
||||
indexMenu++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// indexMenu gets the first possible menu item index based on the location of the shellex registry key.
|
||||
// If the registry entry is under SystemFileAssociations for the image formats, ShellImagePreview (in Windows by default) will be at indexMenu=0
|
||||
// Shell ImagePreview consists of 4 menu items, a separator, Rotate right, Rotate left, and another separator
|
||||
// Check if the entry at indexMenu is a separator, insert the new menu item at indexMenu+1 if true
|
||||
MENUITEMINFO miiExisting;
|
||||
miiExisting.dwTypeData = NULL;
|
||||
miiExisting.fMask = MIIM_TYPE;
|
||||
MENUITEMINFO miiExisting{};
|
||||
miiExisting.cbSize = sizeof(MENUITEMINFO);
|
||||
GetMenuItemInfo(hmenu, indexMenu, TRUE, &miiExisting);
|
||||
if (miiExisting.fType == MFT_SEPARATOR)
|
||||
miiExisting.fMask = MIIM_TYPE;
|
||||
if (GetMenuItemInfo(hmenu, indexMenu, TRUE, &miiExisting) && miiExisting.fType == MFT_SEPARATOR)
|
||||
{
|
||||
indexMenu++;
|
||||
}
|
||||
@@ -173,6 +168,7 @@ HRESULT CContextMenuHandler::QueryContextMenu(_In_ HMENU hmenu, UINT indexMenu,
|
||||
{
|
||||
hr = MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 1);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
@@ -235,112 +231,147 @@ HRESULT CContextMenuHandler::ResizePictures(CMINVOKECOMMANDINFO* pici, IShellIte
|
||||
{
|
||||
// Set the application path based on the location of the dll
|
||||
std::wstring path = get_module_folderpath(g_hInst_imageResizer);
|
||||
path = path + L"\\PowerToys.ImageResizer.exe";
|
||||
LPTSTR lpApplicationName = &path[0];
|
||||
// Create an anonymous pipe to stream filenames
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
HANDLE hReadPipe;
|
||||
HANDLE hWritePipe;
|
||||
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
sa.bInheritHandle = TRUE;
|
||||
path += L"\\PowerToys.ImageResizer.exe";
|
||||
LPTSTR lpApplicationName = path.data();
|
||||
HRESULT hr = E_FAIL;
|
||||
if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0))
|
||||
|
||||
GUID pipeGuid{};
|
||||
if (FAILED(CoCreateGuid(&pipeGuid)))
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
return hr;
|
||||
}
|
||||
if (!SetHandleInformation(hWritePipe, HANDLE_FLAG_INHERIT, 0))
|
||||
|
||||
wchar_t guidBuffer[64] = {};
|
||||
StringFromGUID2(pipeGuid, guidBuffer, ARRAYSIZE(guidBuffer));
|
||||
|
||||
std::wstring pipeName = L"\\\\.\\pipe\\PowerToysImageResizer_";
|
||||
std::wstring guidString(guidBuffer);
|
||||
if (guidString.length() > 2)
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
return hr;
|
||||
pipeName.append(guidString.substr(1, guidString.length() - 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
pipeName.append(guidString);
|
||||
}
|
||||
|
||||
HANDLE hNamedPipe = CreateNamedPipeW(
|
||||
pipeName.c_str(),
|
||||
PIPE_ACCESS_OUTBOUND,
|
||||
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
nullptr);
|
||||
|
||||
if (hNamedPipe == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
CAtlFile writePipe(hWritePipe);
|
||||
|
||||
CString commandLine;
|
||||
commandLine.Format(_T("\"%s\""), lpApplicationName);
|
||||
|
||||
CString arguments;
|
||||
|
||||
// Set the output directory
|
||||
if (m_pidlFolder)
|
||||
{
|
||||
TCHAR szFolder[MAX_PATH];
|
||||
SHGetPathFromIDList(m_pidlFolder, szFolder);
|
||||
|
||||
commandLine.AppendFormat(_T(" /d \"%s\""), szFolder);
|
||||
if (SHGetPathFromIDList(m_pidlFolder, szFolder))
|
||||
{
|
||||
arguments.AppendFormat(_T("/d \"%s\""), szFolder);
|
||||
}
|
||||
}
|
||||
|
||||
int nSize = commandLine.GetLength() + 1;
|
||||
LPTSTR lpszCommandLine = new TCHAR[nSize];
|
||||
_tcscpy_s(lpszCommandLine, nSize, commandLine);
|
||||
CString pipeArgument(pipeName.c_str());
|
||||
if (!arguments.IsEmpty())
|
||||
{
|
||||
arguments.Append(_T(" "));
|
||||
}
|
||||
arguments.Append(pipeArgument);
|
||||
|
||||
STARTUPINFO startupInfo;
|
||||
ZeroMemory(&startupInfo, sizeof(STARTUPINFO));
|
||||
if (!arguments.IsEmpty())
|
||||
{
|
||||
commandLine.Append(_T(" "));
|
||||
commandLine.Append(arguments);
|
||||
}
|
||||
|
||||
STARTUPINFO startupInfo{};
|
||||
startupInfo.cb = sizeof(STARTUPINFO);
|
||||
startupInfo.hStdInput = hReadPipe;
|
||||
startupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
|
||||
if (pici)
|
||||
{
|
||||
startupInfo.wShowWindow = static_cast<WORD>(pici->nShow);
|
||||
}
|
||||
else
|
||||
{
|
||||
startupInfo.wShowWindow = SW_SHOWNORMAL;
|
||||
}
|
||||
startupInfo.dwFlags = STARTF_USESHOWWINDOW;
|
||||
startupInfo.wShowWindow = pici ? static_cast<WORD>(pici->nShow) : SW_SHOWNORMAL;
|
||||
|
||||
PROCESS_INFORMATION processInformation;
|
||||
PROCESS_INFORMATION processInformation{};
|
||||
|
||||
bool launchSucceeded = false;
|
||||
|
||||
// Try MSIX sparse package first
|
||||
std::wstring packageFamilyName;
|
||||
#if !defined(CIBUILD)
|
||||
// Non-CI Release build
|
||||
packageFamilyName = L"djwsxzxb4ksa8";
|
||||
packageFamilyName = L"djwsxzxb4ksa8";
|
||||
#else
|
||||
// Debug build or CI build
|
||||
packageFamilyName = L"8wekyb3d8bbwe";
|
||||
packageFamilyName = L"8wekyb3d8bbwe";
|
||||
#endif
|
||||
std::wstring aumidTarget = L"shell:AppsFolder\\Microsoft.PowerToys.SparseApp_" + packageFamilyName + L"!PowerToys.ImageResizerUI";
|
||||
|
||||
|
||||
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
||||
sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
|
||||
sei.fMask = SEE_MASK_FLAG_NO_UI;
|
||||
sei.lpVerb = L"open";
|
||||
sei.lpFile = aumidTarget.c_str();
|
||||
sei.lpParameters = lpszCommandLine + wcslen(lpApplicationName) + 3; // Skip the exe path and quotes
|
||||
sei.lpParameters = arguments.IsEmpty() ? nullptr : arguments.GetString();
|
||||
sei.nShow = pici ? static_cast<WORD>(pici->nShow) : SW_SHOWNORMAL;
|
||||
|
||||
if (ShellExecuteExW(&sei) && reinterpret_cast<INT_PTR>(sei.hInstApp) > 32)
|
||||
{
|
||||
// MSIX launch succeeded, use existing pipe communication
|
||||
// (no changes to the rest of the function)
|
||||
delete[] lpszCommandLine;
|
||||
launchSucceeded = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fallback to traditional exe
|
||||
// Start the resizer
|
||||
CreateProcess(
|
||||
NULL,
|
||||
lpszCommandLine,
|
||||
NULL,
|
||||
NULL,
|
||||
TRUE,
|
||||
LPWSTR mutableCommandLine = commandLine.GetBuffer();
|
||||
BOOL created = CreateProcess(
|
||||
nullptr,
|
||||
mutableCommandLine,
|
||||
nullptr,
|
||||
nullptr,
|
||||
FALSE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&startupInfo,
|
||||
&processInformation);
|
||||
delete[] lpszCommandLine;
|
||||
if (!CloseHandle(processInformation.hProcess))
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
return hr;
|
||||
}
|
||||
if (!CloseHandle(processInformation.hThread))
|
||||
commandLine.ReleaseBuffer();
|
||||
if (!created)
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
CloseHandle(hNamedPipe);
|
||||
return hr;
|
||||
}
|
||||
|
||||
CloseHandle(processInformation.hProcess);
|
||||
CloseHandle(processInformation.hThread);
|
||||
launchSucceeded = true;
|
||||
}
|
||||
|
||||
if (!launchSucceeded)
|
||||
{
|
||||
CloseHandle(hNamedPipe);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
BOOL connected = ConnectNamedPipe(hNamedPipe, nullptr);
|
||||
if (!connected && GetLastError() != ERROR_PIPE_CONNECTED)
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
CloseHandle(hNamedPipe);
|
||||
return hr;
|
||||
}
|
||||
|
||||
CAtlFile writePipe;
|
||||
writePipe.Attach(hNamedPipe);
|
||||
hNamedPipe = INVALID_HANDLE_VALUE;
|
||||
|
||||
// psiItemArray is NULL if called from InvokeCommand. This part is used for the MSI installer. It is not NULL if it is called from Invoke (MSIX).
|
||||
if (!psiItemArray)
|
||||
{
|
||||
@@ -351,33 +382,49 @@ HRESULT CContextMenuHandler::ResizePictures(CMINVOKECOMMANDINFO* pici, IShellIte
|
||||
CString fileName(i.CurrentItem());
|
||||
fileName.Append(_T("\r\n"));
|
||||
|
||||
writePipe.Write(fileName, fileName.GetLength() * sizeof(TCHAR));
|
||||
hr = writePipe.Write(fileName, fileName.GetLength() * sizeof(TCHAR));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
writePipe.Close();
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//m_pdtobj will be NULL when invoked from the MSIX build as Initialize is never called (IShellExtInit functions aren't called in case of MSIX).
|
||||
// m_pdtobj will be NULL when invoked from the MSIX build as Initialize is never called (IShellExtInit functions aren't called in case of MSIX).
|
||||
DWORD fileCount = 0;
|
||||
// Gets the list of files currently selected using the IShellItemArray
|
||||
psiItemArray->GetCount(&fileCount);
|
||||
// Iterate over the list of files
|
||||
for (DWORD i = 0; i < fileCount; i++)
|
||||
{
|
||||
IShellItem* shellItem;
|
||||
psiItemArray->GetItemAt(i, &shellItem);
|
||||
LPWSTR itemName;
|
||||
// Retrieves the entire file system path of the file from its shell item
|
||||
shellItem->GetDisplayName(SIGDN_FILESYSPATH, &itemName);
|
||||
CString fileName(itemName);
|
||||
fileName.Append(_T("\r\n"));
|
||||
// Write the file path into the input stream for image resizer
|
||||
writePipe.Write(fileName, fileName.GetLength() * sizeof(TCHAR));
|
||||
|
||||
hr = writePipe.Write(fileName, fileName.GetLength() * sizeof(TCHAR));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
writePipe.Close();
|
||||
CoTaskMemFree(itemName);
|
||||
shellItem->Release();
|
||||
return hr;
|
||||
}
|
||||
CoTaskMemFree(itemName);
|
||||
shellItem->Release();
|
||||
}
|
||||
}
|
||||
|
||||
hr = writePipe.Flush();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
writePipe.Close();
|
||||
return hr;
|
||||
}
|
||||
writePipe.Close();
|
||||
hr = S_OK;
|
||||
return hr;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT __stdcall CContextMenuHandler::GetTitle(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszName)
|
||||
|
||||
Reference in New Issue
Block a user