make "open terminal here" context menu work for directory background (#8638)
This commit makes "Open in Windows Terminal" Context menu work again for directory background even on system that OS fix is not applied. This is a fallback solution to OS fixes mentioned in #6414. While OS fix is on its way, we need a fallback that works on existing OS versions. The approach to this is: when no item is selected (nullptr for IShellItemArray*), we use shell api to query the path of current active Explorer window. A special case is handled for Windows Desktop. Once we are able to obtain the path, we launch Windows Terminal with it. ## Validation Steps Performed 1. Right click on desktop to bring up the Context menu, pick "Open in Windows Terminal", verify that a terminal is opened with correct initial path. 2. Open a few File Explorer windows, pick any window, navigate to a folder, click on "Background" to bring up the context menu, click "Open in Windows Terminal" verify that a terminal is opened with correct initial path. Closes #6414
This commit is contained in:
parent
6b2ae625a5
commit
fcca88ab25
14
.github/actions/spell-check/expect/a129ff14ec985d6b7bf09e296a831c955d41040b.txt
vendored
Normal file
14
.github/actions/spell-check/expect/a129ff14ec985d6b7bf09e296a831c955d41040b.txt
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
checkboxes
|
||||
CSIDL
|
||||
csv
|
||||
horiz
|
||||
IDispatch
|
||||
inlines
|
||||
IWeb
|
||||
Progman
|
||||
reserialize
|
||||
SHANDLE
|
||||
SHGFP
|
||||
udk
|
||||
unfocus
|
||||
WClass
|
40
.github/actions/spell-check/expect/expect.txt
vendored
40
.github/actions/spell-check/expect/expect.txt
vendored
|
@ -168,7 +168,6 @@ BOLDFONT
|
|||
BOOLIFY
|
||||
bools
|
||||
boostorg
|
||||
Bopomofo
|
||||
Borland
|
||||
BOTTOMLEFT
|
||||
BOTTOMRIGHT
|
||||
|
@ -248,7 +247,6 @@ charset
|
|||
CHARSETINFO
|
||||
chcp
|
||||
checkbox
|
||||
Checkboxes
|
||||
chh
|
||||
Childitem
|
||||
chk
|
||||
|
@ -384,7 +382,6 @@ CORESYSTEM
|
|||
cotaskmem
|
||||
countof
|
||||
cout
|
||||
CParams
|
||||
CPG
|
||||
cpinfo
|
||||
CPINFOEX
|
||||
|
@ -413,7 +410,6 @@ csbi
|
|||
csbiex
|
||||
csharp
|
||||
CSHORT
|
||||
cso
|
||||
csproj
|
||||
Csr
|
||||
csrmsg
|
||||
|
@ -426,7 +422,6 @@ cstdlib
|
|||
cstr
|
||||
cstring
|
||||
cstyle
|
||||
CSV
|
||||
CSwitch
|
||||
CText
|
||||
ctime
|
||||
|
@ -628,7 +623,6 @@ doskey
|
|||
dotnet
|
||||
doubleclick
|
||||
downlevel
|
||||
DOWNSCALE
|
||||
dpg
|
||||
dpi
|
||||
DPIAPI
|
||||
|
@ -841,7 +835,6 @@ gcy
|
|||
gdi
|
||||
gdip
|
||||
gdirenderer
|
||||
GENERATEPROJECTPRIFILE
|
||||
geopol
|
||||
GETALIAS
|
||||
GETALIASES
|
||||
|
@ -957,7 +950,6 @@ hfont
|
|||
hglobal
|
||||
hh
|
||||
hhh
|
||||
hhhh
|
||||
hhook
|
||||
hhx
|
||||
HIBYTE
|
||||
|
@ -984,7 +976,6 @@ hmod
|
|||
hmodule
|
||||
hmon
|
||||
HMONITOR
|
||||
Horiz
|
||||
HORZ
|
||||
hostable
|
||||
hostlib
|
||||
|
@ -1097,10 +1088,8 @@ INITMENU
|
|||
inkscape
|
||||
inl
|
||||
INLINEPREFIX
|
||||
Inlines
|
||||
INotify
|
||||
inout
|
||||
INPATHROOT
|
||||
inproc
|
||||
Inputkeyinfo
|
||||
INPUTPROCESSORPROFILE
|
||||
|
@ -1113,7 +1102,6 @@ INTERCEPTCOPYPASTE
|
|||
INTERNALNAME
|
||||
interop
|
||||
interoperability
|
||||
intersectors
|
||||
inthread
|
||||
intptr
|
||||
intsafe
|
||||
|
@ -1212,7 +1200,6 @@ KJ
|
|||
KLF
|
||||
KLMNOPQRST
|
||||
KLMNOPQRSTQQQQQ
|
||||
Kode
|
||||
KU
|
||||
KVM
|
||||
KX
|
||||
|
@ -1344,7 +1331,6 @@ mailto
|
|||
majorly
|
||||
makeappx
|
||||
MAKEINTRESOURCE
|
||||
MAKEINTRESOURCEA
|
||||
MAKEINTRESOURCEW
|
||||
MAKELANGID
|
||||
MAKELONG
|
||||
|
@ -1417,7 +1403,6 @@ monostate
|
|||
MOUSEACTIVATE
|
||||
MOUSEFIRST
|
||||
MOUSEHWHEEL
|
||||
mousemode
|
||||
MOUSEMOVE
|
||||
mousewheel
|
||||
MOVESTART
|
||||
|
@ -1439,7 +1424,6 @@ MSGSELECTMODE
|
|||
msiexec
|
||||
MSIL
|
||||
msix
|
||||
msixbundle
|
||||
msrc
|
||||
msvcrt
|
||||
MSVS
|
||||
|
@ -1842,7 +1826,6 @@ pshn
|
|||
PSHNOTIFY
|
||||
PSHORT
|
||||
pshpack
|
||||
psin
|
||||
PSINGLE
|
||||
psl
|
||||
psldl
|
||||
|
@ -1962,16 +1945,13 @@ Replymessage
|
|||
repositorypath
|
||||
rescap
|
||||
Resequence
|
||||
Reserialize
|
||||
RESETCONTENT
|
||||
resheader
|
||||
resizable
|
||||
resmimetype
|
||||
reso
|
||||
restrictedcapabilities
|
||||
resw
|
||||
resx
|
||||
RETROII
|
||||
retval
|
||||
rfa
|
||||
rfc
|
||||
|
@ -1991,7 +1971,6 @@ rgpwsz
|
|||
rgrc
|
||||
rgs
|
||||
rgui
|
||||
rgus
|
||||
rgw
|
||||
rgwch
|
||||
rhs
|
||||
|
@ -2042,14 +2021,11 @@ SBCSDBCS
|
|||
sbi
|
||||
sbiex
|
||||
sbold
|
||||
sbri
|
||||
scanbri
|
||||
scancode
|
||||
scanline
|
||||
schemename
|
||||
SCL
|
||||
scm
|
||||
scol
|
||||
scprintf
|
||||
SCRBUF
|
||||
SCRBUFSIZE
|
||||
|
@ -2128,7 +2104,6 @@ sfi
|
|||
SFINAE
|
||||
SFUI
|
||||
sgr
|
||||
SGRXY
|
||||
SHCo
|
||||
shcore
|
||||
shellapi
|
||||
|
@ -2183,9 +2158,6 @@ SOURCESDIRECTORY
|
|||
SPACEBAR
|
||||
spammy
|
||||
spand
|
||||
spe
|
||||
sph
|
||||
spherefunctions
|
||||
splashscreen
|
||||
sprintf
|
||||
sqlproj
|
||||
|
@ -2303,7 +2275,6 @@ TCI
|
|||
tcome
|
||||
tcommandline
|
||||
tcommands
|
||||
tcon
|
||||
TDelegated
|
||||
TDP
|
||||
TEAMPROJECT
|
||||
|
@ -2449,8 +2420,6 @@ ucdxml
|
|||
uch
|
||||
UCHAR
|
||||
ucs
|
||||
UDK
|
||||
UDKs
|
||||
UDM
|
||||
uer
|
||||
uget
|
||||
|
@ -2473,7 +2442,6 @@ UNCPRIORITY
|
|||
undef
|
||||
Unescape
|
||||
unexpand
|
||||
Unfocus
|
||||
unhighlighting
|
||||
unhosted
|
||||
unicode
|
||||
|
@ -2564,7 +2532,6 @@ vga
|
|||
vgaoem
|
||||
viewkind
|
||||
viewports
|
||||
Viginetting
|
||||
Virt
|
||||
VIRTTERM
|
||||
Virtualizing
|
||||
|
@ -2781,7 +2748,6 @@ wwaproj
|
|||
WWith
|
||||
wx
|
||||
wxh
|
||||
wz
|
||||
xa
|
||||
xact
|
||||
xamarin
|
||||
|
@ -2800,14 +2766,12 @@ XColors
|
|||
xcopy
|
||||
XCount
|
||||
xdy
|
||||
xe
|
||||
XEncoding
|
||||
xes
|
||||
Xes
|
||||
XES
|
||||
xff
|
||||
XFile
|
||||
xlang
|
||||
XManifest
|
||||
XMath
|
||||
XMFLOAT
|
||||
|
@ -2831,9 +2795,7 @@ xutr
|
|||
xvalue
|
||||
XVIRTUALSCREEN
|
||||
XWalk
|
||||
XWV
|
||||
xy
|
||||
xyw
|
||||
Xzn
|
||||
yact
|
||||
YAML
|
||||
|
@ -2850,7 +2812,6 @@ YVIRTUALSCREEN
|
|||
Yw
|
||||
YWalk
|
||||
yx
|
||||
yzx
|
||||
Zc
|
||||
ZCmd
|
||||
ZCtrl
|
||||
|
@ -2862,7 +2823,6 @@ zu
|
|||
zxcvbnm
|
||||
zy
|
||||
AAAAABBBBBBCCC
|
||||
AAAAA
|
||||
BBBBBCCC
|
||||
abcd
|
||||
LPMINMAXINFO
|
||||
|
|
|
@ -82,14 +82,9 @@
|
|||
<desktop5:ItemType Type="Directory">
|
||||
<desktop5:Verb Id="Command1" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
|
||||
</desktop5:ItemType>
|
||||
<!-- Due to a bug in the OS, this doesn't actually work right -
|
||||
we'll get a nullptr in our implementation. So this is disabled
|
||||
temporarily. See MSFT:24623699 for more details.
|
||||
|
||||
<desktop5:ItemType Type="Directory\Background">
|
||||
<desktop5:Verb Id="Command2" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
|
||||
</desktop5:ItemType>
|
||||
-->
|
||||
<desktop5:Verb Id="Command2" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
|
||||
</desktop5:ItemType>
|
||||
</desktop4:FileExplorerContextMenus>
|
||||
</desktop4:Extension>
|
||||
|
||||
|
|
|
@ -82,15 +82,9 @@
|
|||
<desktop5:ItemType Type="Directory">
|
||||
<desktop5:Verb Id="Command1" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
|
||||
</desktop5:ItemType>
|
||||
<!-- Due to a bug in the OS, this doesn't actually work right -
|
||||
we'll get a nullptr in our implementation. So this is disabled
|
||||
temporarily. See MSFT:24623699 for more details.
|
||||
|
||||
<desktop5:ItemType Type="Directory\Background">
|
||||
<desktop5:Verb Id="Command2" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
|
||||
<desktop5:Verb Id="Command2" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
|
||||
</desktop5:ItemType>
|
||||
-->
|
||||
|
||||
</desktop4:FileExplorerContextMenus>
|
||||
</desktop4:Extension>
|
||||
|
||||
|
|
|
@ -83,14 +83,9 @@
|
|||
<desktop5:ItemType Type="Directory">
|
||||
<desktop5:Verb Id="Command1" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
|
||||
</desktop5:ItemType>
|
||||
<!-- Due to a bug in the OS, this doesn't actually work right -
|
||||
we'll get a nullptr in our implementation. So this is disabled
|
||||
temporarily. See MSFT:24623699 for more details.
|
||||
|
||||
<desktop5:ItemType Type="Directory\Background">
|
||||
<desktop5:Verb Id="Command2" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
|
||||
<desktop5:Verb Id="Command2" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
|
||||
</desktop5:ItemType>
|
||||
-->
|
||||
</desktop4:FileExplorerContextMenus>
|
||||
</desktop4:Extension>
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "pch.h"
|
||||
#include "OpenTerminalHere.h"
|
||||
#include <ShlObj.h>
|
||||
|
||||
// TODO GH#6112: Localize these strings
|
||||
static constexpr std::wstring_view VerbDisplayName{ L"Open in Windows Terminal" };
|
||||
|
@ -117,14 +118,29 @@ static std::wstring _getExePath()
|
|||
HRESULT OpenTerminalHere::Invoke(IShellItemArray* psiItemArray,
|
||||
IBindCtx* /*pBindContext*/)
|
||||
{
|
||||
DWORD count;
|
||||
psiItemArray->GetCount(&count);
|
||||
|
||||
winrt::com_ptr<IShellItem> psi;
|
||||
RETURN_IF_FAILED(psiItemArray->GetItemAt(0, psi.put()));
|
||||
|
||||
wil::unique_cotaskmem_string pszName;
|
||||
RETURN_IF_FAILED(psi->GetDisplayName(SIGDN_FILESYSPATH, &pszName));
|
||||
|
||||
if (psiItemArray == nullptr)
|
||||
{
|
||||
// get the current path from explorer.exe
|
||||
const auto path = this->_GetPathFromExplorer();
|
||||
|
||||
// no go, unable to get a reasonable path
|
||||
if (path.empty())
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
pszName = wil::make_cotaskmem_string(path.c_str(), path.length());
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD count;
|
||||
psiItemArray->GetCount(&count);
|
||||
|
||||
winrt::com_ptr<IShellItem> psi;
|
||||
RETURN_IF_FAILED(psiItemArray->GetItemAt(0, psi.put()));
|
||||
RETURN_IF_FAILED(psi->GetDisplayName(SIGDN_FILESYSPATH, &pszName));
|
||||
}
|
||||
|
||||
{
|
||||
wil::unique_process_information _piClient;
|
||||
|
@ -214,3 +230,90 @@ HRESULT OpenTerminalHere::EnumSubCommands(IEnumExplorerCommand** ppEnum)
|
|||
*ppEnum = nullptr;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
std::wstring OpenTerminalHere::_GetPathFromExplorer() const
|
||||
{
|
||||
using namespace std;
|
||||
using namespace winrt;
|
||||
|
||||
wstring path;
|
||||
HRESULT hr = NOERROR;
|
||||
|
||||
auto hwnd = ::GetForegroundWindow();
|
||||
if (hwnd == nullptr)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
TCHAR szName[MAX_PATH] = { 0 };
|
||||
::GetClassName(hwnd, szName, MAX_PATH);
|
||||
if (0 == StrCmp(szName, L"WorkerW") ||
|
||||
0 == StrCmp(szName, L"Progman"))
|
||||
{
|
||||
//special folder: desktop
|
||||
hr = ::SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, szName);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
path = szName;
|
||||
return path;
|
||||
}
|
||||
|
||||
if (0 != StrCmp(szName, L"CabinetWClass"))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
auto shell = create_instance<IShellWindows>(CLSID_ShellWindows);
|
||||
if (shell == nullptr)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
com_ptr<IDispatch> disp;
|
||||
wil::unique_variant variant;
|
||||
variant.vt = VT_I4;
|
||||
|
||||
com_ptr<IWebBrowserApp> browser;
|
||||
// look for correct explorer window
|
||||
for (variant.intVal = 0;
|
||||
shell->Item(variant, disp.put()) == S_OK;
|
||||
variant.intVal++)
|
||||
{
|
||||
com_ptr<IWebBrowserApp> tmp;
|
||||
if (FAILED(disp->QueryInterface(tmp.put())))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
HWND tmpHWND = NULL;
|
||||
hr = tmp->get_HWND(reinterpret_cast<SHANDLE_PTR*>(&tmpHWND));
|
||||
if (hwnd == tmpHWND)
|
||||
{
|
||||
browser = tmp;
|
||||
break; //found
|
||||
}
|
||||
}
|
||||
|
||||
if (browser != nullptr)
|
||||
{
|
||||
wil::unique_bstr url;
|
||||
hr = browser->get_LocationURL(&url);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
wstring sUrl(url.get(), SysStringLen(url.get()));
|
||||
DWORD size = MAX_PATH;
|
||||
hr = ::PathCreateFromUrl(sUrl.c_str(), szName, &size, NULL);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
path = szName;
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,9 @@ struct __declspec(uuid("9f156763-7844-4dc4-b2b1-901f640f5155"))
|
|||
STDMETHODIMP GetCanonicalName(GUID* pguidCommandName);
|
||||
STDMETHODIMP EnumSubCommands(IEnumExplorerCommand** ppEnum);
|
||||
#pragma endregion
|
||||
|
||||
private:
|
||||
std::wstring _GetPathFromExplorer() const;
|
||||
};
|
||||
|
||||
CoCreatableClass(OpenTerminalHere);
|
||||
|
|
|
@ -11,10 +11,13 @@
|
|||
<!-- sets a bunch of Windows Universal properties -->
|
||||
<OpenConsoleUniversalApp>true</OpenConsoleUniversalApp>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<Link>
|
||||
<AdditionalDependencies>User32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="OpenTerminalHere.h" />
|
||||
|
@ -40,7 +43,6 @@
|
|||
<None Include="packages.config" />
|
||||
<None Include="WindowsTerminalShellExt.def" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ========================= Project References ======================== -->
|
||||
<ItemGroup>
|
||||
<!--
|
||||
|
@ -56,7 +58,5 @@
|
|||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
</Project>
|
||||
|
|
|
@ -81,6 +81,5 @@
|
|||
<AdditionalDependencies>$(OpenConsoleCommonOutDir)\conptylib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
|
||||
</Project>
|
||||
|
|
Loading…
Reference in a new issue