When Windows Terminal is installed on Windows 10, according to UWP package setting: https://github.com/microsoft/Terminal/blob/e37ba7a923427c9a874a6d5bdc27c80fe59db83c/src/cascadia/CascadiaPackage/Package.appxmanifest#L51
A ReparsePoint of type IO_REPARSE_TAG_APPEXECLINK is created in path %LOCALAPPDATA%\Microsoft\WindowsApps\wt.exe
to start Windows Terminal. This is great, however, wt.exe should support richer command line arguments to enable third-party applications to open specific terminals.
It absolutely should. I'll mark this and use it as the backlog entry for supporting things like:
--profile
--command
--connection
--workdir
(or whatever)
This'll help out with shortcut pinning, and let you do things like "I want to temporary launch WSL with my Powershell profile/keybindings (wt --profile Powershell -c wsl.exe
)
@DHowett-MSFT Very Good. you can use CommandLineToArgvW convert Commandline to Argv.
If you need to parse Argv, the ParseArgv I wrote may be useful :https://github.com/M2Team/Privexec/blob/master/include/parseargv.hpp
ParseArgv support subcommand
// https://github.com/M2Team/Privexec/blob/master/wsudo/wsudo.cc
// ParseArgv todo
int AppMode::ParseArgv(int argc, wchar_t **argv) {
av::ParseArgv pa(argc, argv, true);
pa.Add(L"version", av::no_argument, L'v')
.Add(L"help", av::no_argument, L'h')
.Add(L"user", av::required_argument, L'u')
.Add(L"new-console", av::no_argument, L'n')
.Add(L"hide", av::no_argument, L'H')
.Add(L"wait", av::no_argument, L'w')
.Add(L"verbose", av::no_argument, L'V')
.Add(L"appx", av::required_argument, L'x')
.Add(L"cwd", av::required_argument, L'c')
.Add(L"env", av::required_argument, L'e')
.Add(L"lpac", av::no_argument, L'L')
.Add(L"", av::no_argument, L'a')
.Add(L"", av::no_argument, L'M')
.Add(L"", av::no_argument, L'U')
.Add(L"", av::no_argument, L'A')
.Add(L"", av::no_argument, L'S')
.Add(L"", av::no_argument, L'T')
.Add(L"appname", av::required_argument, 1001)
.Add(L"disable-alias", av::no_argument, 1002);
av::error_code ec;
auto result = pa.Execute(
[&](int val, const wchar_t *va, const wchar_t *) {
switch (val) {
case 'v':
Version();
exit(0);
case 'h':
Usage();
exit(0);
case 'u':
if (!IsAppLevel(va, level)) {
priv::Print(priv::fc::Red, L"wsudo unsupport user level: %s\n", va);
return false;
}
break;
case 'n':
visible = priv::VisibleNewConsole;
break;
case 'H':
visible = priv::VisibleHide;
break;
case 'w':
wait = true;
break;
case 'V':
verbose = true;
break;
case 'x':
appx = va;
break;
case 'c':
cwd = va;
break;
case 'e':
envctx.Append(va);
break;
case 'L':
lpac = true;
break;
case 'a':
level = priv::ProcessAppContainer;
break;
case 'M':
level = priv::ProcessMandatoryIntegrityControl;
break;
case 'U':
level = priv::ProcessNoElevated;
break;
case 'A':
level = priv::ProcessElevated;
break;
case 'S':
level = priv::ProcessSystem;
break;
case 'T':
level = priv::ProcessTrustedInstaller;
break;
case 1001:
appname = va;
break;
case 1002:
disablealias = true;
break;
default:
break;
}
return true;
},
ec);
if (!result) {
priv::Print(priv::fc::Red, L"wsudo ParseArgv: %s\n", ec.message);
return 1;
}
/// Copy TO
args = pa.UnresolvedArgs();
return 0;
}
Hey, that's pretty helpful.
Thanks!
@DHowett-MSFT
I created a commit and I don't know if such a change meets the requirements of the Windows Terminal team. see: https://github.com/fcharlie/Terminal/commit/e4cc84f1db77e7f268bbfc9dea9703ea3a5877a1
I'm not sure if I should create new issue so I'll write my idea here.
What about additional option to select which way this request will be treated?
By this I mean, option to select should this command be executed in new window or in new tab.
Is it possible to implement same behavoir just like almost any multifile editor to execute command (similar to file) in separate tab, not window, if window already exists?
Just curious on status of this? Maybe a WIP PR?
The status of this issue appears to be “Spec Needed”, “Open”, “Issue-Feature” (it is a big enough request that it needs a specification). If there’s a WIP pull request, I am not seeing it mentioned.
It would be nice when the --workdir
option would default to the current working directory of the calling process. That way one can open wt
from the explorer bar:
And from other tools such as "Open here" and 3rd part tools like the Tower Git Client.
Just commenting to show my support for this. It would be super nice if this made it possible to open a new Terminal window with a pre-defined set of tabs.
Some applications take argument order into consideration, i.e. example.exe --one-arg --two-arg
is not the same as example.exe --two-arg --one-arg
. Implementing something like this would make it possible to start multiple tabs with different configuration in a single command, by repeating arguments in different contexts.
Example: wt.exe --command cmd.exe --workdir d:\Projects\API --title API --command cmd.exe --workdir d:\Projects\UI --title UI
In fact, I would recommend the same command-line style as wsudo mentioned above (similar to the conhost command line). After parsing the parameters that wt can handle, the rest are shells (cmd/pwsh/bash .. .) parameters.
wt.exe --workdir d:\some\dir --title "some title" cmd.exe /c /path/to/some.bat
I have more ideas about the wt support command line, for reference only:
Through experimentation, I found that starting the wt from the command line and starting the Windows terminal from the start menu is different. This is a prerequisite for wt to support more command lines.
Start wt from cmd:
Run Windows Termianl from Start:
View the CreateProcessW statement:
BOOL WINAPI CreateProcessW(
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
We can almost speculate that Windows sets lpApplicationName to the full path of Windows Terminal when starting wt, and sets lpCommandLine to the command line. In wsudo(wsudo-tie), I did the same.
Having said that, we can use GetCommandLine and CommandLineToArgv to split the commandline. If Argv0 is wt(wt.exe/wtd/wtd.exe), we can be sure that this is the terminal started from wt, so we start parsing the parameters. Replace the workdir
title
connection
with a specific configuration item (or the first profile if no profile is specified). If --workdir is not specified then the current directory of wt is used.
Also I don't recommend --command
to set the command line, which may cause the caller to need double escaping.
I would also like to suggest the ability to target a specific window of terminal. Say that I have an application that wants to open several CMD windows over time, I can use terminal to open them all in the same window, in different tabs.
I would also like to suggest using Protocol Activation to enable command line params when launching Terminal from a UWP application.
Specifying this in the package manifest
And running this: ms-terminal: -profile something -command something
Will result in the wWinMain getting this exact string as a command line argument.
“ms-terminal: -profile something -command something”
Yes, the first thing I wanted to do was create a shortcut to launch a specific profile, and after fumbling around trying things like /? /help --help -h, passing the profile guid I came to the issues looking to see if anyone else wanted more than "default"
Why double dash when powershell uses single dash?
--
and all short ones are -
. PowerShell may not have made the right choice, but that choice was made more than ten years ago so it's a compatibility concern. Consider WSL: --list, -l [Options]
Lists distributions.
Options:
--all
List all distributions, including distributions that are currently
being installed or uninstalled.
--running
List only distributions that are currently running.
--quiet, -q
Only show distribution names.
--verbose, -v
Show detailed information about all distributions.
--set-default, -s <Distro>
Sets the distribution as the default.
--set-default-version <Version>
Changes the default install version for new distributions.
--set-version <Distro> <Version>
Changes the version of the specified distribution.
I think it's mostly a linux tradition that is not bad but I also like powershell way of using -SetVersion instead of --set-version. Probably It has something to do with the dotnet background of powershell.
It's not just a tradition, it's encoded in the getopt family of functions, which are available in libc basically everywhere but Windows.
In Windows we use a version of getopt for wsl's option parsing. It might be useful to do the same (e.g. grab a copy of getopt from musl libc) so that things like --
(to separate options from non-option arguments) work in a predictable fashion.
After thinking about this I agree now.
I didn't even know I could use 'wt' to run Terminal. I was looking for my quick Win+R+cmd+Enter replacement, yay! 🙂
We need consistent treatment of starting (working) directory.
Window terminal should NOT chdir to %USERPROFILE%
if there is no "StartingDirectory" entry in profile.json
and no directory option. (like -d directory) And if -d option exist, then StartingDirectory entry should be ignored always.
Currently if no "StartingDirectory" entry in profile.json
, and wt is run in cmd.exe or from "run command" menu, it always starts in %USERPROFILE% directory, regardless of current directory of invoking process. This is inconsistent behavior with other Windows command line programs and user expectation. It should start in current directory of cmd.exe it was invoked from or "C: Windows/win32" which is current directory of Window Explorer shell "Run command". This is how cmd.exe
works.
The "StartingDirectory" entry in profile.json
should be ignored if -d directory option exists, regardless that it has directory arguement or not.
Currently, to implement #1060 (Add "open Windows terminal here" into right-click context menu), the "StartingDirectory" should be always set to ".", which invalidates the purpose of having StartingDirectory
entry in profile.json. "wt -d" should do the trick regardless of StartingDirectory.
In summary:
No -d option and no StartingDirectory : use current directory of invoking process.
No -d option but have StartingDirectory : use StartingDirectory
-d option without argument (-d alone) : use use current directory of invoking process., ignoring StartingDirectory, i.e -d will let wt ignore StartingDirectory entry.
-d option with argument (-d directory) : use the directory argument
EDIT:
-d~ option: wt will ignore StartingDirectory and use %USERPROFILE%
@qqkookie you're looking for #3547
Now that we have the option to split windows and it's almost Christmas, I'd like to have that option from the command line as well.
I would like to be able to run a shortcut that (in order of priority)
@henriksen If that's what you want, then I have a PR that will make you very happy: #3495
@zadjii-msft Well, I guess Christmas came early this year! Looks like the spec has everything I wanted! 👍
Part of this being able to launch WT via external processes/shortcuts should also make a constant way to reference and include the WT icon in shortcuts. I might have missed the best way to do it, but so far the only way I was able to get this working is to manually convert a file from C:Program FilesWindowsAppsMicrosoft.WindowsTerminal_0.7.3451.0_x64__8wekyb3d8bbweImages and include it in my app myself, which I imagine would encourage fragmentation and not a good thing.
In regards to the icon, there is likely no good way to do that. A wt launcher / profile editor maybe... In theory images could be loaded dynamically from a dll, but I imagine that becomes more trouble than it would be worth. When distributions are registered it would be kind of nice to have a shortcut of some sort created imo
The proposed ability to select profiles on the command line doesn't seem to be available yet (at least as of 2020/01) so I've hacked together a solution that let's you specify profile (and currently also the window size) using the current Windows Terminal found in the app store (or via github).
See:
http://davesource.com/Solutions/20200114.Windows-Terminal-command-line-options/
It wouldn't be too hard to add the ability to control other options from the command line as well.
@daveola For the record, this is in a PR currently over in #4023. It's actually nearly complete as well (_*cough*_ @DHowett-MSFT)
Almost complete doesn't open a terminal on my computer.. :)
:tada:This issue was addressed in #4023, which has now been successfully released as Windows Terminal Preview v0.9.433.0
.:tada:
Handy links:
Most helpful comment
It absolutely should. I'll mark this and use it as the backlog entry for supporting things like:
--profile
--command
--connection
--workdir
(or whatever)This'll help out with shortcut pinning, and let you do things like "I want to temporary launch WSL with my Powershell profile/keybindings (
wt --profile Powershell -c wsl.exe
)