Extensions
Bundled extensions
The binaries include the extensions that ship with Postgres, such as pgcrypto, hstore and pg_trgm. Create one as usual:
await using var conn = new NpgsqlConnection(server.ConnectionString);
await conn.OpenAsync();
await using var cmd = new NpgsqlCommand("CREATE EXTENSION pgcrypto", conn);
await cmd.ExecuteNonQueryAsync();GetAvailableExtensionsAsync() lists everything CREATE EXTENSION can use in an install: the bundled extensions plus any you configured. It reads the install folder, so the server does not need to be running:
foreach (var ext in await server.GetAvailableExtensionsAsync())
Console.WriteLine($"{ext.Name} {ext.DefaultVersion}: {ext.Comment}");Extension archives
The library downloads extension archives and extracts them into the Postgres install; then run CREATE EXTENSION yourself.
Each archive must be a zip built for the same platform and Postgres major version as the server. A folder at the top of the zip that holds bin, lib and share is handled. For example, the PostGIS bundle below is a Windows build for Postgres 17: it extracts on Linux or macOS too, but CREATE EXTENSION then fails, so choose the extension URL per platform.
// Windows: the PostGIS bundle for Postgres 17
await using var server = new PgServer(new PgServerOptions
{
PgVersion = "17",
Extensions =
[
new PgExtensionConfig("https://download.osgeo.org/postgis/windows/pg17/postgis-bundle-pg17-3.6.2x64.zip")
]
});
await server.StartAsync();
await using var conn = new NpgsqlConnection(server.ConnectionString);
await conn.OpenAsync();
await using var cmd = new NpgsqlCommand("CREATE EXTENSION postgis", conn);
await cmd.ExecuteNonQueryAsync();Verify an archive
Give its SHA-256 to make sure the archive is exactly the one you expect. A mismatch fails the start and the archive is not installed:
var postgis = new PgExtensionConfig("https://example.com/my-extension.zip")
{
Sha256 = "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
};