For our Universal terminal for development purposes, we will use telnet to escape the universal application container and empower developers to debug/diagnose issues with their own machine on loopback to the already-elevated telnet context.
## Summary of the Pull Request
Fix the `TabTests`, and enable testing of types with XAML content. The `TabTests` were written many, many moons ago. they were intended to be our tests of XAML-like content within the Terminal app, so we could have unittests of Tabs, Panes, etc. Between their initial authoring and the day they were checked in, we had a bunch of build changes come in and break them irreperably.
We've gotten them fixed now with _one weird trick_ <sup>doctors hate me</sup>. As long as there isn't an `App.xbf` in the test's output directory, then the tests will deploy just fine.
We also needed a bit of magic, cribbed straight from TAEF, to enable running test code synchronously on the UI thread. Hence, `CppwinrtTailored.h`.
## References
## PR Checklist
* [x] Closes#2472
* [x] I work here
* [x] Tests added/passed - you better believe it
* [n/a] Requires documentation to be updated
## Validation Steps Performed
![image](https://user-images.githubusercontent.com/18356694/70185192-ef1d0b00-16ae-11ea-8799-b77061e3cdb0.png)
This pull request implements the new
`ITerminalConnection::ConnectionState` interface (enum, event) and
connects it through TerminalControl to Pane, Tab and App as specified in
#2039. It does so to implement `closeOnExit` = `graceful` in addition to
the other two normal CoE types.
It also:
* exposes the singleton `CascadiaSettings` through a function that
looks it up by using the current Xaml application's `AppLogic`.
* In so doing, we've broken up the weird runaround where App tells
TerminalSettings to CloseOnExit and then later another part of App
_asks TerminalControl_ to tell it what TerminalSettings said App
told it earlier. `:crazy_eyes:`
* wires up a bunch of connection state points to `AzureConnection`.
This required moving the Azure connection's state machine to use another
enum name (oops).
* ships a helper class for managing connection state transitions.
* contains a bunch of template magic.
* introduces `WINRT_CALLBACK`, a oneshot callback like `TYPED_EVENT`.
* replaces a bunch of disparate `_connecting` and `_closing` members
with just one uberstate.
* updates the JSON schema and defaults to prefer closeOnExit: graceful
* updates all relevant documentation
Specified in #2039Fixes#2563
Co-authored-by: mcpiroman <38111589+mcpiroman@users.noreply.github.com>
This commit renames the functions in conpty.lib to Conpty* so that they
can be explicitly linked and introduces a header so they can be located.
It also updates the DEF for conpty.dll to reexport them with their
original names.
The crux of the issue here is that TerminalConnection is consuming the
_import_ symbols for the *PseudoConsole family of APIs, which simply
cannot be supplanted by a static library.
Avenues explored: * Exporting __imp_x from the static library to get all
up in kernel32's business. * Using /ALTERNATENAME:__imp_X=StaticX. It
turns out ALTERNATENAME is only consulted when the symbol isn't found
through traditional means.
This, renaming them, is the straightest path forward.
Fixes#3553.
* Make ConPTY build as both LIB and DLL.
* Update TerminalConnection reference to LIB version (because Terminal builds both UWP and Centennial, requiring different CRTs each).
* DLL is now available (and against desktop CRT) to be PInvokable from C# for WPF terminal.
Note, DLL MUST BUILD PRECOMP to get the magic pragma linking information to the Desktop CRT.
* don't audit PTY lib. I can't do safe things because the safe things we use don't fit back inside kernelbase.dll.
Closes#3563.
This new cpprestsdk package, 2.10.14, switches us to the app CRT.
cpprestsdk turns fof a bunch of boost and openssl dependencies when it's
built for the Windows Store subplatform, so we got a bunch of stuff for
free.
Incidentally, I fixed#2338 the real/correct way -- the build rules in
the package now make sure they're not using the system vcpkg root.
This commit deletes ConhostConnection and replaces it with
ConptyConnection. The ConptyConnection uses CreatePseudoConsole and
depends on winconpty to override the one from kernel32.
* winconpty must be packageable, so I've added GetPackagingOutputs.
* To validate this, I added conpty.dll to the MSIX regression script.
* I moved the code from conpty-universal that deals with environment
strings into the types library.
This puts us in a way better place to implement #2563, as we can now
separately detect a failure to launch a pseudoconsole, a failure to
CreateProcess, and an unexpected termination of the launched process.
Fixes#1131.
This commit cleans up and deduplicates all of the common build
preamble/postamble across exe, dll, lib and c++/winrt projects.
The following specific changes have been made:
* All projects now define their ConfigurationType
* All projects now set all their properties *before* including a common
build file (or any other build files)
* cppwinrt.pre and cppwinrt.post now delegate most of their
configuration to common.pre and common.post
* (becuase of the above,) all build options are conserved between
console and c++/winrt components, including specific warnings and
preprocessor definitions.
* More properties that are configurable per-project are now
conditioned so the common props don't override them.
* The exe, dll, exe.or.dll, and lib postincludes have been merged into
pre or post and switched based on condition as required
* Shared items (-shared, -common) are now explicitly vcxitems instead of
vcxproj files.
* The link line is now manipulated after Microsoft.Cpp sets it, so the
libraries we specify "win". All console things link first against
onecore_apiset.lib.
* Fix all compilation errors caused by build unification
* Move CascadiaPackage's resources into a separate item file
Fixes#922.
It turns out that if you CATCH_LOG without including this file, and you
end up catching a C++/WinRT hresult_exception, IT TURNS IT INTO A
FAILFAST.
Fixes#2591.
Fixes#2881.
Fixes#2807.
* Revert "Add source linking information during the build (#2857)"
This reverts commit 6b728cd6d0.
* Need reference to renderer base inside UnitTests_TerminalCore
* add dependency for TerminalControl to Types project.
* Set build to single threaded as parallel build is broken by 16.3 build toolchain.
* Disable new rule C26814 as it's breaking builds
Wrote a follow up task #2941 to roll it out later.
* Add noexcept to dx header.
Copies source linking scripts and processes from Microsoft/Microsoft-UI-XAML. This embeds source information inside the PDBs in two formats: One for WinDBG using a PowerShell script that runs during the build, and one for Visual Studio using the Microsoft.SourceLink.GitHub NuGet pacakge. Sources are automatically pulled from raw.githubusercontent.com when debugging a release build inside either of these utilities as of this change.
Adds a number of TL events we can use to track startup time better. Adds events for:
* Initial exe start
* Time the window is created
* time we start loading settings
* time we finish loading setings
* time when a connection recieves its first byte
Also updates our `ConnectionCreated` event to include the session GUID, so that we can correlate that with the connection's `RecievedFirstByte` event.
On occasion, in certain delegated access scenarios, we'll fail to read
the name of one or more of the user's Azure tenants. We would summarily
explode (because we're being strict about our incoming JSON, and we
didn't know that this was possible.)
Now we'll substitute in an alternate name and present the ID.
Fixes#2249.
* Update src/cascadia/TerminalConnection/AzureConnection.cpp
When we change the client ID, we're going to need to force people to log
in again.
We can do that either by:
1. Trying to log in and refresh the user's token and failing (displaying
a cryptic message like "you aren't on the internet, please get on the
internet"), **OR** by...
2. Getting out ahead of it, detecting when we would have failed for client
ID (and other) reasons, and _not trying at all._
This is option 2.
### User Stories:
1. A user wants to be able to use the executable path as their starting title
- Does anyone want this?
2. A user wants to be able to set a custom starting title, but have that title be overridable
3. A user wants to be able to set an overridable starting title, different from the profile name
- Presumably someone will want this
4. A user totally wants to ignore the VT title and use something else
- This will make more sense in the post [#1320] "Support runtime variables in the custom user title" settings
### Solutions:
1. `name`, `startingTitle`, `tabTitle`
* a. `name` is only ever used as the profile name.
* b. If `startingTitle` isn't set, then the executable path is used
* c. If `startingTitle` is set, it's used as the initial title
* d. If `tabTitle` is set, it overrides the title from the terminal
* e. Current users of `tabTitle` need to manually update to the new behavior.
2. `name` as starting title, `tabTitle` as a different starting title
* a. `name` is used as the starting title and the profile name in the dropdown
* b. If `tabTitle` is set, we'll use that as the overridable starting title instead.
* c. In the future, `dynamicTabTitle` or `tabTitleOverride` could be added to support [#1320]
* d. Current users of `tabTitle` automatically get the new (different!) behavior.
* e. User Story 1 is impossible
- Does anyone want the behavior _ever_? Perhaps making that scenario impossible is good?
3. `name` unchanged, `tabTitle` as the starting title
* a. `name` is only ever used as the profile name.
* b. If `tabTitle` is set, we'll use that as the overridable starting title.
* c. In the future, `dynamicTabTitle` or `tabTitleOverride` could be added to support [#1320]
* d. Current users of `tabTitle` automatically get the new (different!) behavior.
4. `name` as starting title, `tabTitle` as different starting title, `suppressApplicationTitle` Boolean to force it to override
* a. `name`, `tabTitle` work as in Solution 2.
* b. When someone wants to be able to statically totally override that title (story 4), they can use `suppressApplicationTitle`
* c. `suppressApplicationTitle` name is WIP
* d. We'll add `suppressApplicationTitle` when someone complains
* e. If you really want story 1, use `tabTitle: c:\path\to\foo.exe` and `suppressApplicationTitle`.
[#1320]: https://github.com/microsoft/terminal/issues/1320
We've decided to pursue path 4.
The default azure connector profile only shows up if a) its a release build and b) its non-ARM64
Co-Authored-By: Dustin L. Howett (MSFT) <duhowett@microsoft.com>
This commit addresses some lingering issues in UTF8OutPipeReader and cleans up its termination logic. It also fixes some issues exposed in the test.
Fixes#1997.
* Fix for UTF-8 partials in functions `ConhostConnection::_OutputThread` and `ApiRoutines::WriteConsoleOutputCharacterAImpl`
The implementation needs to check whether or not the buffer ends with a partial character. If so, only convert the code points which are complete, and save the partial code units in a cache that gets prepended to the next chunk of text.
* Utf8OutPipeReader class added
* Unit Test added
* use specific macros and WIL classes
* avoid possible deadlock caused by unclosed pipe handle
* Refactors TerminalApp into two projects:
- TerminalAppLib, which builds a .lib, and includes all the code
- TerminalApp, which builds a dll by linking the lib
* Adds a TerminalApp.Unit.Tests project
- Includes the ability to test cppwinrt types we've authored using a SxS manifest for unpackaged winrt activation
- includes the ability to test types with XAML content using an appxmanifest
* Adds a giant doc explaining how this was all done. Really, just go read that doc, it'll really help you understand what's going on in this PR.
-------------------------
These are some previous commit messages. They may be helpful to future readers.
* Start adding unittests for json parsing, end up creating a TerminalAppLib project to make a lib. See #1042
* VS automatically did this for me
* This is a dead end
I tried including the idl-y things into the lib, but that way leads insanity
If you want to make a StaticLibrary, then suddenly the winrt toolchain forgets
that ProjectReferences can have winmd's in them, so it won't be able to
compile any types from the referenced projects. If you instead try to manually
reference the types, you'll get duplicate types up the wazoo, which of course
is insane, since we're referencing them the _one_ time
* Yea just follow #1042 on github for status
So current state:
1. If you try to add a `Reference` to all of MUX.Markup, TerminalControl and
TerminalSettings, then mdmerge will complain about all the types from
TerminalSettings being defined twice. In this magic scenario, the
dependencies of TerminalControl are used directly for some reason:
```
12> Load input metadata file ...OpenConsole\x64\Debug\TerminalSettings\Microsoft.Terminal.Settings.winmd.
12> Load input metadata file ...OpenConsole\x64\Debug\TerminalControl\Microsoft.Terminal.Settings.winmd.
12> Load input metadata file ...OpenConsole\x64\Debug\TerminalControl\Microsoft.Terminal.TerminalConnection.winmd.
12> Load input metadata file ...OpenConsole\x64\Debug\TerminalControl\Microsoft.Terminal.TerminalControl.winmd.
12> Load input metadata file ...OpenConsole\x64\Debug\Microsoft.UI.Xaml.Markup\Microsoft.UI.Xaml.Markup.winmd.
```
2. If you don't add a `Reference` TerminalControl, then it'll complain about
being unable to find the type TitleChangedEventArgs, which is defined in
TerminalControl.
3. If you don't add a `Reference` TerminalSettings, then it'll complain about
being unable to find the type KeyChord and other types from
TerminalSettings. In this scenario, it doesn't recurse on the other
dependencies from TerminalControl for whatever reason.
4. If you instead try to add all 3 as a `ProjectReference`, then it'll
complain about being unable to find TitleChangedEventArgs, as in 2.
Presumably, it;ll have troubles with the other types too, as none of the 3
are actually included in the midlrt.rsp file.
5. If you add all 3 as a `ProjectReference`, then also add TerminalControl as
a `Reference`, you'll get a `MIDL2011: [msg] unresolved type declaration
Microsoft.UI.Xaml.Markup.XamlApplication`
6. If you add all 3 as a `ProjectReference`, then also add TerminalControl AND
MUX.Markup as a `Reference`, you'll get the same result as 3.
* what if we just don't idl
This seems to compile
* This compiles but I broke the MUX resources
look at the App.xaml change. in this changelist. That's what's broken right now. Lets fix that!
* lets do this
If I leave the MUX nuget out of the project, I'll get a compile error in
App.xaml:
```
...OpenConsole\src\cascadia\TerminalApp\App.xaml(21,40): XamlCompiler error WMC0001: Unknown type 'XamlControlsResources' in XML namespace 'using:Microsoft.UI.Xaml.Controls'
```
If I add it back to the project, it works
* Some cleanup from the previous commit
* This is busted again.
Doing a clean build didn't work.
A clean rebuild of the project, paired with some removal of dead code
revealed a problem with what I have so far.
TerminalAppLib depends on the generation of two headers,
`AppKeyBindings.g.h` and `App.g.h`, as those define some of bits of the
winrt types. They're needed to be able to compile the implementations.
Presumably that's not getting generated by the lib project, because the dll
project is the one to generate that file.
So we need to move the idl's to the lib project. This created maddness,
because of course the Duplicate Type thing. The solution to that is to
actually mark the winrt DLLs that we're chaining up through us as
```
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
```
This will prevent them from getting double-included.
This still doesn't work however, since
```
app.cpp(40): error C2039: 'XamlMetaDataProvider': is not a member of 'winrt::TerminalApp'
error C3861: 'XamlMetaDataProvider': identifier not found
```
So we need to figure that out. The dll project is still generating the right
header, so lets look there.
* Move the xaml stuff to the lib
This compiles, but when we launch, we fail to load the tabviewcontrol
resources again. So that's not what you want. Why is it not included?
* It works again!
* Use the pri, xbf files from TerminalAppLib, not TerminalApp
* Manually make TerminalApp include a reference to TerminalAppLib's
TerminalApp.winmd. This will force the build to copy TerminalApp.winmd to
TerminalApp/, which WindowsTerminal needs to be able to ProjectReference the
TerminalApp project (it's expecting it to have a winmd)
* Remove the module.g.cpp from TerminalApp, and move to TerminalAppLib. The
dll doesn't do any codegen anymore.
* Agressively clean up these files
* Clean up unnecessary includes in the dll pch.h
* This does NOT work.
The WindowsxamlManager call crashes. I'm thinking it has to do with activation
of winrt types from a dll.
Email out to @Austin-Lamb to see if he can assist
* This gets our cppwinrt types working, but xaml islands is still broken
* Split the tests apart, so they aren't insane
* These are the magic words to make xaml islands work
* All this witchcraft is necessary to make XAML+MUX work right
* Clean this up a bit and add comments
* Create an enormous doc explaining this madness
* Unsure how this got changed.
* Trying to get the CI build to work again.
This resolves the MUX issue. We need to manually include it, because their package's target doesn't mark it as CopyLocalSatelliteAssemblies=false, Private=false.
However, the TerminalApp project is still able to magically reason that the TerminalAppLib project should be included in the MdMerge step, because it think's it's a `GetCppWinRTStaticProjectReferences` reference.
* Update cppwinrt to the latest version - this fixes the MSBuild
* I still need to re-add the KeyModifiers checks from TermControl. I think
this update broke `operator&` for that enum.
* There needs to be some cleanup obviously
* The doc should be updated as well
* Clean up changes from cppwinrt update
* Try doing this, even though it seems wrong
* Lets try this (press x to doubt)
* Clean up vcxproj file, and remove appxmanifest change from previous commit
* Update to the latest TAEF release, maybe that'll work
* Let's try a prerelease version, shall we?
* Add notes about TAEF package, comment out tests
* Format the code
* Hopefully fix the arm64 and x86 builds
also a typo
* Fix PR nits
* Fix some bad merge conflicts
* Some cleanup from the merge
* Well I was close to getting the merge right
* I believe this will fix CI
* Apply suggestions from code review
Co-Authored-By: Carlos Zamora <carlos.zamora@microsoft.com>
* These definitely need to be fixed
* Try version detecting in the test
IDK if this will build, I'm letting the CI try while I clean rebuild locally
* Try blindly updating to the newest nuget version
* Revert "Try blindly updating to the newest nuget version"
This reverts commit b72bd9eb73.
* We're just going to see if these work in CI with this change
* Comment the tests back out. Windows Server 2019 is 10.0.17763.557
* Remove the nuget package
We don't need this package anymore now that we're hosting it
* Okay this _was_ important
The signal pipe must be terminated first. It is this very termination
that signals to the connected console host that it should begin exiting
in an orderly manner.
We're introducing an indefinite wait (yes, I know: it's not great) for
conhost to exit. **This matches ClosePseudoConsole in
kernelbase/winconpty.**
If it does not exit in an orderly manner, powershell (and perhaps other
.NET CLI applications) may crash immediately after conhost exits.
Fixes#1338.
* Connection: run all pseudoconsole hosts in jobs
This commit also switches the manual resource management in
ConhostConnection to use WIL, and modernizes the constructor to follow
new code style guidelines.
* Terminate conhost before trying to run down the pipes
* Cascadia/TerminalConnection: Close the output thread on exit.
It seems that TerminateThread() is available in the code...
* VtPipeTerm: Don't crash when closing the app.
- Gracefully handle ReadFile returning false (usually because of ERROR_BROKEN_PIPE on exit).
- Minor whitespace formatting.
* Cascadia/TerminalConnection: Finish to implement the ConhostConnection::Close() 'TODO' block.
Almost all functions in the Windows API that open or create objects and return HANDLEs to them return null on failure; only a few (mostly to do with the file system) return INVALID_HANDLE_VALUE on failure. This PR scrubs the repo of a few, but not necessarily all, cases where INVALID_HANDLE_VALUE was mistakenly used or tested against instead of null. In particular, it fixes 2 cases reported in issue #427 where the return value of CreateThread() was compared against INVALID_HANDLE_VALUE against null, causing the error handling code to run at the wrong time.
There are a lot of other uses of INVALID_HANDLE_VALUE I found that looked questionable, but which I left alone. Most of these were used to initialize HANDLE-typed variables and as a sentinel to see if those variables remained unset to a "real" value.
Fixes#427
* set identifying environment variable for new connections
Set a new 'WT_SESSION' environment variable when creating new terminal
connections to allow shells to detect a unique Windows Terminal session.
The value of the variable is a stringified GUID as returned by
CoCreateGuid.
How verified:
- "razzle" & vs debug build
- runut
- manual inspection
* * use winrt::guid type for connection guid
* use Utils::GuidToString for guid stringification
* expose guid parameter in ITerminalConnection idl
* - poke guid through ITerminalConnection
- misc. review fixes
- throw if CreateConPty fails in ConhostConnection::Start
- apply [[nodiscard]] and noexcept in various places
* - simplify environment variable extraction in UpdateEnvironmentMapW
* - use Utils::CreateGuid instead of CoCreateGuid in ConHostConnection()