Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ You will need to make sure you'll have the following elements installed:
- **Windows only:** [Visual Studio Build Tools](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2022) with ".NET desktop build tools" workload
- **Linux/macOS only:** [mono-complete](https://www.mono-project.com/docs/getting-started/install/) with msbuild, and [nuget CLI](https://www.nuget.org/downloads)

> **Note:** The `.slnx` solution format is fully supported on Windows. On Linux/macOS,
> `.slnx` requires a recent Mono installation with an updated MSBuild. If your Mono
> version does not support `.slnx`, use the classic `.sln` format instead.

### Linux-specific Requirements

On Linux, you may need to add your user to the `dialout` group to access serial ports:
Expand Down Expand Up @@ -208,6 +212,8 @@ This extension works on:

Step over in debug mode is like continue so far. We're activey working on improving this. You can setup as many break points as you want, so, if you need an equivalent of setp over, you can do this!

The new `.slnx` solution format is supported on Windows (Visual Studio Build Tools with MSBuild 17.12+). On Linux and macOS, `.slnx` support requires a recent Mono installation that includes an updated MSBuild. If your Mono version does not support `.slnx`, use the classic `.sln` format instead.

## Developing for the VS Code extension

Documentation about development for the extension can be found [here](installation.md).
Expand Down
3 changes: 3 additions & 0 deletions installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ The following packages/tools/frameworks are required on all platforms:
> The [preview](https://www.mono-project.com/download/preview/) version is recommended
> as the [stable](https://www.mono-project.com/download/stable/) version is outdated.

> **Note:** The `.slnx` solution format requires a recent Mono/MSBuild version.
> If your Mono installation does not support `.slnx`, use the classic `.sln` format.

> **Note:** If you're running into a `langversion:9` error, try installing the latest mono-nightly.

### Verify PowerShell Installation
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,12 @@
"menus": {
"explorer/context": [
{
"when": "resourceExtname == .sln || resourceExtname == .nfproj",
"when": "resourceExtname == .sln || resourceExtname == .slnx || resourceExtname == .nfproj",
"command": "vscode-nanoframework.nfbuild",
"group": "navigation@1"
},
{
"when": "resourceExtname == .sln",
"when": "resourceExtname == .sln || resourceExtname == .slnx",
"command": "vscode-nanoframework.nfdeploy",
"group": "navigation@1"
},
Expand All @@ -257,22 +257,22 @@
"group": "navigation@1"
},
{
"when": "resourceExtname == .sln",
"when": "resourceExtname == .sln || resourceExtname == .slnx",
"command": "vscode-nanoframework.nfadd",
"group": "navigation@1"
},
{
"when": "resourceExtname == .sln || resourceExtname == .nfproj",
"when": "resourceExtname == .sln || resourceExtname == .slnx || resourceExtname == .nfproj",
"command": "vscode-nanoframework.nfaddnuget",
"group": "navigation@2"
},
{
"when": "resourceExtname == .sln || resourceExtname == .nfproj",
"when": "resourceExtname == .sln || resourceExtname == .slnx || resourceExtname == .nfproj",
"command": "vscode-nanoframework.nfremovenuget",
"group": "navigation@2"
},
{
"when": "resourceExtname == .sln || resourceExtname == .nfproj",
"when": "resourceExtname == .sln || resourceExtname == .slnx || resourceExtname == .nfproj",
"command": "vscode-nanoframework.nfupdatenuget",
"group": "navigation@2"
}
Expand Down
2 changes: 1 addition & 1 deletion src/debugger/nanoDebugSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import * as path from 'path';
* Launch request arguments for nanoFramework debugging
*/
interface ILaunchRequestArguments extends DebugProtocol.LaunchRequestArguments {
/** Path to the .nfproj or .sln file */
/** Path to the .nfproj, .sln, or .slnx file */
program: string;
/** Target device (COM port or IP address) */
device?: string;
Expand Down
2 changes: 1 addition & 1 deletion src/debugger/types/debugTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export interface NanoLaunchConfig {
request: 'launch' | 'attach';
/** Configuration name */
name: string;
/** Path to the .nfproj or .sln file */
/** Path to the .nfproj, .sln, or .slnx file */
program?: string;
/** Target device (COM port or IP address) */
device?: string;
Expand Down
7 changes: 4 additions & 3 deletions src/dotnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import * as https from 'https';
import { Executor } from "./executor";
import * as cp from 'child_process';
import * as vscode from 'vscode';
import { isSolutionFile } from './utils';

const mdpBuildProperties = ' -p:NFMDP_PE_Verbose=false -p:NFMDP_PE_VerboseMinimize=false -p:UseSharedCompilation=false';

Expand Down Expand Up @@ -474,7 +475,7 @@ async function findOrDownloadWindowsNuget(extensionPath: string): Promise<string
* @returns An object with `target` (the file to restore) and `extraArgs` (additional nuget CLI flags).
*/
function resolveNugetRestoreTarget(filePath: string): { target: string; extraArgs: string } {
if (filePath.endsWith('.sln')) {
if (isSolutionFile(filePath)) {
return { target: filePath, extraArgs: '' };
}

Expand All @@ -490,7 +491,7 @@ function resolveNugetRestoreTarget(filePath: string): { target: string; extraArg

// Try to find a .sln in the parent directory (common solution layout)
try {
const slnFiles = fs.readdirSync(parentDir).filter(f => f.endsWith('.sln'));
const slnFiles = fs.readdirSync(parentDir).filter(f => isSolutionFile(f));
if (slnFiles.length > 0) {
return { target: path.join(parentDir, slnFiles[0]), extraArgs: '' };
}
Expand Down Expand Up @@ -608,7 +609,7 @@ export class Dotnet {
configuration = await vscode.window.showQuickPick(['Debug', 'Release'], { placeHolder: 'Select build configuration', canPickMany: false }) || 'Debug';
}
if (!fileUri) {
vscode.window.showErrorMessage('No solution file selected. Please select a .sln file.');
vscode.window.showErrorMessage('No solution file selected. Please select a .sln or .slnx file.');
return;
}

Expand Down
8 changes: 4 additions & 4 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { NuGetManager, showNuGetPackagePicker, showInstalledPackagePicker, showU

import { multiStepInput } from './multiStepInput';
import {
getDocumentWorkspaceFolder, solvePath, chooseSerialPort, chooseSolutionWorkspace,
getDocumentWorkspaceFolder, isSolutionFile, solvePath, chooseSerialPort, chooseSolutionWorkspace,
chooseName, chooseProjectType
} from './utils';
import { SerialPortCtrl } from './serialportctrl';
Expand Down Expand Up @@ -258,7 +258,7 @@ export async function activate(context: vscode.ExtensionContext) {
if (filePath.endsWith('.nfproj')) {
// Direct project file
projectPath = filePath;
} else if (filePath.endsWith('.sln')) {
} else if (isSolutionFile(filePath)) {
// Solution file - let user pick a project
projectPath = await showProjectPicker(filePath);
}
Expand Down Expand Up @@ -321,7 +321,7 @@ export async function activate(context: vscode.ExtensionContext) {

if (filePath.endsWith('.nfproj')) {
projectPath = filePath;
} else if (filePath.endsWith('.sln')) {
} else if (isSolutionFile(filePath)) {
projectPath = await showProjectPicker(filePath);
}
} else {
Expand Down Expand Up @@ -391,7 +391,7 @@ export async function activate(context: vscode.ExtensionContext) {

if (filePath.endsWith('.nfproj')) {
projectPath = filePath;
} else if (filePath.endsWith('.sln')) {
} else if (isSolutionFile(filePath)) {
projectPath = await showProjectPicker(filePath);
}
} else {
Expand Down
26 changes: 18 additions & 8 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ import { SerialPortCtrl } from "./serialportctrl";

const axios = require('axios');

/**
* Checks whether the given file path points to a solution file (.sln or .slnx).
*/
export function isSolutionFile(filePath: string): boolean {
return filePath.endsWith('.sln') || filePath.endsWith('.slnx');
}

/**
* Gets absolute path of current open workspace in VSCode
* @returns (first) absolute path of the workspace folder
Expand All @@ -22,16 +29,19 @@ export function getDocumentWorkspaceFolder(): string | undefined {
}

/**
* Finds all *.sln files in your VSCode Workspace
* Finds all solution files (*.sln and *.slnx) in your VSCode Workspace
* Shows a QuickPick window that lets the user select one of these solutions
* Returns the absolute path to the selected solution
* @param workspaceFolder absolute path to workspace
* @returns absolute path to selected *.sln
* @returns absolute path to selected solution file
*/
export async function chooseSolution(workspaceFolder: string) {
// Use VS Code's built-in findFiles API instead of globby
const files = await vscode.workspace.findFiles('**/*.sln', '**/node_modules/**');
const paths = files.map(file => file.fsPath);
const [slnFiles, slnxFiles] = await Promise.all([
vscode.workspace.findFiles('**/*.sln', '**/node_modules/**'),
vscode.workspace.findFiles('**/*.slnx', '**/node_modules/**')
]);
const paths = [...slnFiles, ...slnxFiles].map(file => file.fsPath);

const result = await vscode.window.showQuickPick(paths, {
placeHolder: 'Select the solution you would like to build/deploy',
Expand Down Expand Up @@ -121,11 +131,11 @@ export async function chooseTarget(_toolPath: string) {
}

/**
* If a path to a specific .sln is given, this is used.
* Otherwise, the user is prompted with a selection of all *.sln in workspace to choose from
* @param fileUri *.sln (can be empty)
* If a path to a specific solution file (.sln/.slnx) is given, this is used.
* Otherwise, the user is prompted with a selection of all solution files in workspace to choose from
* @param fileUri solution file (can be empty)
* @param workspaceFolder absolute path to workspace
* @returns absolute path to selected *.sln file
* @returns absolute path to selected solution file
*/
export async function solvePath(fileUri: vscode.Uri, workspaceFolder: string) {
let path = fileUri ? fileUri.fsPath: '';
Expand Down
Loading