# Attach and send keys

Source: https://libtmux.org/en/csharp/latest/examples/attach-and-send-keys/

> Get a session handle, send a command to a pane, and capture output.

Get a session handle, send a command to a pane, and capture output. These
examples use libtmux from your program; to attach your terminal interactively,
see [Attaching to tmux](https://libtmux.org/en/csharp/latest/guides/attaching-to-tmux/).

The examples include setup, error handling, and cleanup. [Source and
verification](https://libtmux.org/en/csharp/latest/examples/attach-and-send-keys/#where-this-comes-from) identifies their files and checks.

```csharp file="examples/LibTmux.Examples/Snippets/OneShot.cs"
using System.Runtime.Versioning;

namespace LibTmux.Examples.Snippets;

/// <summary>The default mode: one command, one client, one materialized object.</summary>
[UnsupportedOSPlatform("windows")]
public static class OneShot
{
    /// <summary>Connects, builds a hierarchy, and types into the pane it made.</summary>
    [Example("Connect, build a session and window, and type into a pane")]
    public static async Task ConnectAndBuild()
    {
        #region ConnectAndBuild
        // Requires a tmux server already listening on this socket:
        // ConnectAsync() discovers one, it never starts one. With nothing
        // running yet, call Server.CreateOwnedAsync() instead.
        Server server = await Server.ConnectAsync();
        Session session = await server.CreateSessionAsync(new NewSessionRequest { Name = "build" });
        Window window = await session.CreateWindowAsync(new NewWindowRequest { Name = "tests" });
        Pane pane = (await window.GetPanesAsync())[0];

        await pane.SendTextAsync("dotnet test");
        #endregion
    }

    /// <summary>Creates a window and prints what tmux answered about it.</summary>
    [Example("One command, one materialized window")]
    public static async Task CreateWindow(Session session, CancellationToken ct)
    {
        #region CreateWindow
        Window window = await session.CreateWindowAsync(new NewWindowRequest { Name = "build" }, ct);
        Console.WriteLine($"{window.Id} {window.Index}:{window.Name}");
        #endregion
    }
}
```

## Finding an existing session instead

For a script that runs repeatedly, look up a session before creating it.
[Attaching to
tmux](https://libtmux.org/en/csharp/latest/guides/attaching-to-tmux/#finding-a-session-instead-of-always-creating-one)
shows that pattern, and [Filtering and querying, in
practice](https://libtmux.org/en/csharp/latest/guides/querying-and-filtering/) covers absent and ambiguous matches.

## Where this comes from

**Source:** [`examples/LibTmux.Examples/Snippets/OneShot.cs`](<https://github.com/libtmux/libtmux-dotnet/blob/cf34b255c896d19a97e7d7fabea58609c916012d/examples/LibTmux.Examples/Snippets/OneShot.cs>)

**In this page:** read whole from the file

**Checked by:** its `ConnectAndBuild` region is mirrored into README.md and
checked by `sync_snippets.py --check`; the mirrored `csharp run` block is
additionally compiled and run by `ReadmeExampleTests`

### Source inclusion

A `file="..."` fence reads the named source during the site build. Hand-quoted
excerpts are copies; their source files and regions are listed above.
