Skip to content

feat: add sqlcmd open vscode and sqlcmd open ssms commands#688

Open
dlevy-msft-sql wants to merge 9 commits into
microsoft:mainfrom
dlevy-msft-sql:pr-685
Open

feat: add sqlcmd open vscode and sqlcmd open ssms commands#688
dlevy-msft-sql wants to merge 9 commits into
microsoft:mainfrom
dlevy-msft-sql:pr-685

Conversation

@dlevy-msft-sql
Copy link
Copy Markdown
Contributor

@dlevy-msft-sql dlevy-msft-sql commented Feb 1, 2026

Problem

sqlcmd open ads is the only tool-launch command, but Azure Data Studio is deprecated and no longer the primary tool for SQL Server development.

Solution

Add sqlcmd open vscode and sqlcmd open ssms commands alongside the existing sqlcmd open ads.

Changes

Area Change
cmd/modern/root/open/vscode.go VS Code command: creates connection profile in mssql.connections, launches via vscode:// URI
cmd/modern/root/open/ssms.go SSMS command (Windows): tries ssms://connect URI for remote servers, falls back to direct exe launch with -C for local containers
cmd/modern/root/open/jsonc*.go JSONC parser and patcher: preserves comments/trailing commas in VS Code settings.json
cmd/modern/root/open/clipboard.go Shared clipboard-based password transfer (VS Code sandboxes creds; SSMS 18+ removed -P)
cmd/modern/root/open/uri_*.go OS protocol handlers (
undll32/open/xdg-open) shared by both commands
internal/tools/tool/vscode*.go VS Code tool discovery across Windows/macOS/Linux (user + system installs, Insiders priority)
internal/tools/tool/ssms*.go SSMS tool discovery with dynamic version-sorted path scanning
internal/pal/clipboard*.go Cross-platform clipboard (clip/pbcopy/xclip/xsel/wl-copy)
internal/tools/tool/tool.go ExePath(), RunWithOutput(), error instead of panic on unchecked IsInstalled()
README.md Updated quickstart with VS Code and SSMS examples

Design Decisions

  • URI-based launch: Both commands use OS protocol handlers (vscode://, ssms://) rather than direct exe launch where possible. This avoids hardcoding paths and works with multiple installed versions.
  • SSMS local connection fallback: The ssms:// protocol handler has no -C (trust server certificate) mapping, so local container connections skip the URI path and launch SSMS directly with -C for self-signed cert support.
  • JSONC preservation: VS Code settings.json supports comments and trailing commas. The JSONC patcher replaces only the mssql.connections value, preserving all other formatting and comments byte-for-byte.
  • Clipboard for passwords: VS Code uses sandboxed credential storage (no API to inject passwords). SSMS 18+ removed the -P flag. Clipboard is the common denominator.

Testing

  • 45 tests across cmd/modern/root/open/..., internal/tools/..., internal/pal/...
  • JSONC parser/patcher: comments, trailing commas, real-world VS Code settings
  • Tool discovery: SSMS version extraction, path scanning
  • Profile management: create, update, dedup
  • Manual testing: sqlcmd open vscode (confirmed working), sqlcmd open ssms (confirmed working)

Supersedes #685. Fixes #584.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for opening Visual Studio Code and SQL Server Management Studio (SSMS) to work with SQL Server connections managed by sqlcmd, addressing the deprecation of Azure Data Studio. The implementation uses clipboard-based password sharing since both tools use sandboxed credential storage.

Changes:

  • Adds sqlcmd open vscode command that creates connection profiles in VS Code settings and auto-installs the MSSQL extension
  • Adds sqlcmd open ssms command (Windows-only) that launches SSMS with pre-configured connection parameters
  • Implements cross-platform clipboard support for secure password sharing
  • Includes comprehensive tests and documentation updates

Reviewed changes

Copilot reviewed 30 out of 31 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
cmd/modern/root/open.go Updates open command to include VSCode and SSMS subcommands
cmd/modern/root/open/vscode.go Main VSCode command implementation with settings file manipulation
cmd/modern/root/open/vscode_*.go Platform-specific VSCode implementations
cmd/modern/root/open/ssms.go Main SSMS command implementation
cmd/modern/root/open/ssms_*.go Platform-specific SSMS implementations (Fatal on non-Windows)
cmd/modern/root/open/clipboard.go Helper function for clipboard-based password sharing
cmd/modern/root/open/*_test.go Comprehensive test coverage for new commands
internal/tools/tool/vscode*.go VSCode tool detection and configuration
internal/tools/tool/ssms*.go SSMS tool detection and configuration
internal/pal/clipboard*.go Cross-platform clipboard implementation using native APIs
internal/tools/tools.go Registers VSCode and SSMS tools
README.md Adds clear documentation with usage examples
.gitignore Adds /modern build artifact

Comment thread cmd/modern/root/open/vscode.go Outdated
Comment thread cmd/modern/root/open/ssms.go Outdated
Comment thread cmd/modern/root/open/vscode.go Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 30 out of 31 changed files in this pull request and generated 9 comments.

Comment thread cmd/modern/root/open/ssms_unix.go
Comment thread cmd/modern/root/open/vscode.go Outdated
Comment thread cmd/modern/root/open/ssms.go Outdated
Comment thread cmd/modern/root/open/ssms.go Outdated
Comment thread cmd/modern/root/open/vscode_test.go Outdated
Comment thread cmd/modern/root/open/ssms_test.go Outdated
Comment thread cmd/modern/root/open/ssms_darwin.go Outdated
Comment thread cmd/modern/root/open/vscode.go Outdated
Comment thread cmd/modern/root/open/vscode.go Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 30 out of 31 changed files in this pull request and generated 1 comment.

Comment thread cmd/modern/root/open/vscode.go Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 30 out of 31 changed files in this pull request and generated 1 comment.

Comment thread cmd/modern/root/open/vscode.go Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 32 out of 33 changed files in this pull request and generated 3 comments.

Comment thread cmd/modern/root/open/vscode.go Outdated
Comment thread internal/tools/tool/vscode_linux.go
Comment thread README.md Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 33 out of 34 changed files in this pull request and generated 1 comment.

Comment thread cmd/modern/root/open/ssms.go Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 33 out of 34 changed files in this pull request and generated 2 comments.

Comment thread cmd/modern/root/open/vscode.go Outdated
Comment thread cmd/modern/root/open/ssms.go Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 33 out of 34 changed files in this pull request and generated 4 comments.

Comment thread internal/tools/tool/tool.go Outdated
Comment thread cmd/modern/root/open.go Outdated
Comment thread cmd/modern/root/open/ssms.go Outdated
Comment thread cmd/modern/root/open/vscode.go Outdated
@dlevy-msft-sql dlevy-msft-sql force-pushed the pr-685 branch 3 times, most recently from dd1141d to 675a0df Compare February 6, 2026 00:34
@dlevy-msft-sql dlevy-msft-sql force-pushed the pr-685 branch 8 times, most recently from f2b4a78 to de898f1 Compare April 24, 2026 20:14
@dlevy-msft-sql dlevy-msft-sql added this to the v1.11 milestone Apr 24, 2026
Comment thread cmd/modern/root/open.go Outdated
Comment thread cmd/modern/root/open/ads.go Outdated
"github.com/microsoft/go-sqlcmd/internal/tools"
)

func (c *Ssms) DefineCommand(...cmdparser.CommandOptions) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ma

does SSMS have a url handler yet? If so, it might be the preferred method to use.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked into it — couple of tradeoffs before committing to it in this PR:

  1. ssms:// only ships in SSMS 21+ (released 2025). Adopting it as the primary path would silently break users still on SSMS 18–20.
  2. The URL handler doesn't accept a password, so the clipboard handoff in this PR would stay regardless of launch mechanism — URL adoption doesn't simplify the security story.
  3. A hybrid (URL when SSMS 21+, argv otherwise) is doable but the only net win is cleaner arg construction, which doesn't feel worth the version-detection branch.

Happy to go either way — want me to add the hybrid path in this PR, or defer to a follow-up issue? Leaving this thread open for your call.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"silently break users" - this is a new feature, there are no existing users to break. We can limit this functionality to ssms 21+, and SSMS only supports its latest release anyway.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"silently break users" - this is a new feature, there are no existing users to break. We can limit this functionality to ssms 21+, and SSMS only supports its latest release anyway.

lol...the bot wasn't supposed to respond to this. I will make sure it fails loud and proud with instructions to install the latest ssms.

Comment thread internal/pal/clipboard_linux.go Outdated
// System Insiders Install
// User non-Insiders install
// System non-Insiders install
func (t *VSCode) searchLocations() []string {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(t *VSCode)

does vscode not write its location to the registry somewhere? Can't a user choose a custom location for it?

I feel like since vscode supports a URL handler we don't need to bother looking for it, and if the user tries to open vscode using sqlcmd without having installed vscode first, it's a fairly obvious user error that we don't need to spend time/code defending against.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember using the URI for vs code and not for SSMS. Will need to get my head back into this code.

Comment thread internal/tools/tool/ssms_windows.go Outdated
`Common7\IDE\Ssms.exe`,
}

func (t *SSMS) searchLocations() []string {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MS) searchLocations() []string {

i always install to d:\ssms

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe for modern ssms

 $vswhere `
  -products Microsoft.VisualStudio.Product.Ssms `
  -format json
``

Copy link
Copy Markdown
Collaborator

@shueybubbles shueybubbles left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🕐

VS Code settings.json is JSONC (JSON with Comments) which allows line
comments (//), block comments (/* */), and trailing commas. The previous
implementation used plain json.Unmarshal which fails on any JSONC input.

Add stripJSONC() to remove comments and trailing commas before parsing,
preserving comment-like content inside string literals.

Also make writeSettings() atomic: write to a temp file then rename, with
fallback to direct write if rename fails. This prevents settings.json
corruption if the process is interrupted mid-write.
TestVSCode runs the full command via TestCmd which calls
createConnectionProfile -> getVSCodeSettingsPath, resolving to the
real %APPDATA%\Code\User\settings.json. This silently mutates the
developer's actual VS Code settings on every test run.

Add testSettingsPathOverride hook so TestVSCode redirects writes to
t.TempDir(). The hook is cleared in t.Cleanup so other tests like
TestVSCodeGetSettingsPath still exercise the real path resolution.
Route the final `failed to copy to clipboard'' error through localizer.Errorf so the user-facing message can be translated. Per-tool fragments in �ttempts remain plain English: they're tool-name-keyed debugging strings appended for diagnostics, and localizing them adds catalog churn without user value.
Azure Data Studio was retired in August 2025 and is no longer available. Remove the sqlcmd open ads subcommand and the AzureDataStudio tool factory entry, and re-point downstream hints at sqlcmd open vscode (always) and sqlcmd open ssms (Windows only).

Changes:

- Delete cmd/modern/root/open/ads*.go and internal/tools/tool/ads*.go

- Drop ADS from open.go SubCommands and tools.go tool list

- Re-point hints in cmd/modern/root.go, add-context.go, mssql-base.go, ssms_unix.go installText, and .devcontainer/README.md

- Remove Linux test skips referencing the deleted ADS factory entry

- Regenerate translation catalog
Resolved conflict in internal/translations/catalog.go by accepting main's version and regenerating with GOOS=windows go generate ./internal/translations/... so both main's new strings (raw-errors -j, mssql: prefix) and this PR's open vscode/ssms strings are present.
…etection

Drop the hardcoded `Microsoft SQL Server Management Studio 18/19/20\Common7\IDE\Ssms.exe`
search paths. They miss custom install locations and would need a new entry
for every future major version (SSMS 21+ now ships through the VS Installer
under `Microsoft Visual Studio\Shared\SSMSProtocolSelector\`).

Instead:

* Detect install by probing `HKEY_CLASSES_ROOT\ssms\shell\open\command`,
  which both the legacy MSI installers and the VS Installer register.
* Launch via the `ssms://connect?...` URL handler instead of invoking
  Ssms.exe directly. The URL grammar (`s`, `u`, `a`, `p` short keys)
  matches the "Open in SSMS" link emitted by SQL database in Fabric.
* Pass the password as `p=...` when basic auth is configured, replacing
  the clipboard-copy workaround used for the dropped SSMS 18+ `-P` flag.

Addresses PR microsoft#688 review feedback from @shueybubbles on hardcoded paths
and the suggestion to use the SSMS URL handler.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Size: S Small issue (less than one week effort) SSMS vscode-mssql-ext

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remove ADS and add support for VSCode + MSSQL

3 participants