Add Visual Studio extension for Linux platform support

VSIX extension that adds:
- "OpenMaui Linux App" project template in File → New → Project
- Pre-configured launch profiles for Linux debugging
- WSL integration for Windows developers
- x64 and ARM64 build configurations

Launch Profiles included:
- Linux (Local) - Direct execution
- Linux (WSL) - Run via WSL
- Linux (x64 Release) - Release build for x64
- Linux (ARM64 Release) - Release build for ARM64
- Publish Linux x64/ARM64 - Self-contained publishing

Build with: msbuild /p:Configuration=Release
Output: OpenMaui.VisualStudio.vsix
This commit is contained in:
logikonline 2025-12-19 05:13:16 -05:00
parent d238dde5a4
commit ae5c9ab738
13 changed files with 549 additions and 0 deletions

View File

@ -0,0 +1,23 @@
MIT License
Copyright (c) 2025 MarketAlly LLC
Lead Architect: David H. Friedel Jr.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,44 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<!-- VSIX Properties -->
<GeneratePkgDefFile>true</GeneratePkgDefFile>
<IncludeAssemblyInVSIXContainer>true</IncludeAssemblyInVSIXContainer>
<IncludeDebugSymbolsInVSIXContainer>false</IncludeDebugSymbolsInVSIXContainer>
<IncludeDebugSymbolsInLocalVSIXDeployment>false</IncludeDebugSymbolsInLocalVSIXDeployment>
<CopyBuildOutputToOutputDirectory>true</CopyBuildOutputToOutputDirectory>
<CopyOutputSymbolsToOutputDirectory>false</CopyOutputSymbolsToOutputDirectory>
<UseCodebase>true</UseCodebase>
<!-- Extension Info -->
<ExtensionInstallationRoot>Extensions</ExtensionInstallationRoot>
<ExtensionInstallationFolder>MarketAlly\OpenMaui</ExtensionInstallationFolder>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VSSDK.BuildTools" Version="17.8.2365" />
<PackageReference Include="Microsoft.VisualStudio.SDK" Version="17.8.37221" />
</ItemGroup>
<ItemGroup>
<None Include="source.extension.vsixmanifest">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<Content Include="ProjectTemplates\**\*">
<IncludeInVSIX>true</IncludeInVSIX>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Resources\**\*">
<IncludeInVSIX>true</IncludeInVSIX>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

View File

@ -0,0 +1,17 @@
namespace $safeprojectname$;
/// <summary>
/// Application configuration and lifecycle management.
/// </summary>
public partial class App
{
public App()
{
InitializeComponent();
}
private void InitializeComponent()
{
// Initialize application resources here
}
}

View File

@ -0,0 +1,76 @@
using Microsoft.Maui.Controls;
namespace $safeprojectname$;
/// <summary>
/// The main page of the application.
/// </summary>
public partial class MainPage : ContentPage
{
private int _count = 0;
public MainPage()
{
InitializeComponent();
}
private void InitializeComponent()
{
Title = "Home";
var layout = new VerticalStackLayout
{
Spacing = 25,
Padding = new Thickness(30, 0),
VerticalOptions = LayoutOptions.Center
};
var welcomeLabel = new Label
{
Text = "Hello, OpenMaui!",
FontSize = 32,
HorizontalOptions = LayoutOptions.Center
};
var instructionLabel = new Label
{
Text = "Welcome to .NET MAUI on Linux",
FontSize = 18,
HorizontalOptions = LayoutOptions.Center
};
var counterButton = new Button
{
Text = "Click me",
HorizontalOptions = LayoutOptions.Center
};
counterButton.Clicked += OnCounterClicked;
var image = new Image
{
Source = "dotnet_bot.png",
HeightRequest = 185,
HorizontalOptions = LayoutOptions.Center
};
layout.Children.Add(welcomeLabel);
layout.Children.Add(instructionLabel);
layout.Children.Add(counterButton);
layout.Children.Add(image);
Content = new ScrollView { Content = layout };
}
private void OnCounterClicked(object? sender, EventArgs e)
{
_count++;
if (sender is Button button)
{
button.Text = _count == 1
? $"Clicked {_count} time"
: $"Clicked {_count} times";
}
}
}

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Note: OpenMaui currently uses code-based UI (MainPage.cs).
This XAML file is provided for future XAML support compatibility.
The code-behind in MainPage.cs takes precedence.
-->
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="$safeprojectname$.MainPage">
<ScrollView>
<VerticalStackLayout
Padding="30,0"
Spacing="25">
<Label
Text="Hello, OpenMaui!"
Style="{StaticResource Headline}"
SemanticProperties.HeadingLevel="Level1" />
<Label
Text="Welcome to .NET MAUI on Linux"
Style="{StaticResource SubHeadline}"
SemanticProperties.Description="Welcome message" />
<Button
x:Name="CounterBtn"
Text="Click me"
Clicked="OnCounterClicked"
HorizontalOptions="Fill" />
<Image
Source="dotnet_bot.png"
HeightRequest="185"
Aspect="AspectFit"
SemanticProperties.Description="dot net bot waving" />
</VerticalStackLayout>
</ScrollView>
</ContentPage>

View File

@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>$safeprojectname$</RootNamespace>
<AssemblyName>$safeprojectname$</AssemblyName>
<ApplicationTitle>$projectname$</ApplicationTitle>
<!-- Linux Runtime -->
<RuntimeIdentifiers>linux-x64;linux-arm64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<DefineConstants>$(DefineConstants);DEBUG</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
<PublishTrimmed>false</PublishTrimmed>
</PropertyGroup>
<ItemGroup>
<!-- OpenMaui Linux Platform -->
<PackageReference Include="OpenMaui.Controls.Linux" Version="1.0.0-preview.*" />
<!-- Core MAUI packages -->
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.*" />
<PackageReference Include="Microsoft.Maui.Graphics" Version="9.0.*" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\**\*" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,43 @@
<VSTemplate Version="3.0.0" Type="Project" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
<TemplateData>
<Name>OpenMaui Linux App</Name>
<Description>A .NET MAUI application targeting Linux desktop using OpenMaui and SkiaSharp rendering.</Description>
<Icon>__TemplateIcon.ico</Icon>
<PreviewImage>__PreviewImage.png</PreviewImage>
<ProjectType>CSharp</ProjectType>
<ProjectSubType></ProjectSubType>
<LanguageTag>csharp</LanguageTag>
<PlatformTag>linux</PlatformTag>
<ProjectTypeTag>desktop</ProjectTypeTag>
<ProjectTypeTag>maui</ProjectTypeTag>
<RequiredFrameworkVersion>4.8</RequiredFrameworkVersion>
<SortOrder>1000</SortOrder>
<TemplateID>OpenMaui.Linux.App.CSharp</TemplateID>
<CreateNewFolder>true</CreateNewFolder>
<DefaultName>OpenMauiLinuxApp</DefaultName>
<ProvideDefaultName>true</ProvideDefaultName>
<LocationField>Enabled</LocationField>
<EnableLocationBrowseButton>true</EnableLocationBrowseButton>
<CreateInPlace>true</CreateInPlace>
</TemplateData>
<TemplateContent>
<Project File="OpenMauiLinuxApp.csproj" ReplaceParameters="true">
<ProjectItem ReplaceParameters="true" TargetFileName="Program.cs">Program.cs</ProjectItem>
<ProjectItem ReplaceParameters="true" TargetFileName="App.cs">App.cs</ProjectItem>
<ProjectItem ReplaceParameters="true" TargetFileName="MainPage.cs">MainPage.cs</ProjectItem>
<ProjectItem ReplaceParameters="true" TargetFileName="MainPage.xaml">MainPage.xaml</ProjectItem>
<Folder Name="Properties" TargetFolderName="Properties">
<ProjectItem ReplaceParameters="true" TargetFileName="launchSettings.json">launchSettings.json</ProjectItem>
</Folder>
<Folder Name="Resources" TargetFolderName="Resources">
<Folder Name="Images" TargetFolderName="Images">
<ProjectItem TargetFileName="dotnet_bot.png">dotnet_bot.png</ProjectItem>
</Folder>
</Folder>
</Project>
</TemplateContent>
<WizardExtension>
<Assembly>Microsoft.VisualStudio.TemplateEngine.Wizard, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Assembly>
<FullClassName>Microsoft.VisualStudio.TemplateEngine.Wizard.TemplateEngineWizard</FullClassName>
</WizardExtension>
</VSTemplate>

View File

@ -0,0 +1,20 @@
using OpenMaui.Platform.Linux;
namespace $safeprojectname$;
public class Program
{
public static void Main(string[] args)
{
var app = new LinuxApplication();
// Configure the application
app.Title = "$projectname$";
// Set the main page
app.MainPage = new MainPage();
// Run the application
app.Run();
}
}

View File

@ -0,0 +1,49 @@
{
"profiles": {
"Linux (Local)": {
"commandName": "Project",
"commandLineArgs": "",
"environmentVariables": {
"DISPLAY": ":0",
"DOTNET_ENVIRONMENT": "Development"
}
},
"Linux (WSL)": {
"commandName": "Executable",
"executablePath": "wsl.exe",
"commandLineArgs": "-e dotnet run --project .",
"workingDirectory": "${workspaceFolder}",
"environmentVariables": {
"DISPLAY": ":0",
"WAYLAND_DISPLAY": "",
"DOTNET_ENVIRONMENT": "Development"
}
},
"Linux (x64 Release)": {
"commandName": "Executable",
"executablePath": "dotnet",
"commandLineArgs": "run -c Release -r linux-x64",
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Production"
}
},
"Linux (ARM64 Release)": {
"commandName": "Executable",
"executablePath": "dotnet",
"commandLineArgs": "run -c Release -r linux-arm64",
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Production"
}
},
"Publish Linux x64": {
"commandName": "Executable",
"executablePath": "dotnet",
"commandLineArgs": "publish -c Release -r linux-x64 --self-contained -o ./publish/linux-x64"
},
"Publish Linux ARM64": {
"commandName": "Executable",
"executablePath": "dotnet",
"commandLineArgs": "publish -c Release -r linux-arm64 --self-contained -o ./publish/linux-arm64"
}
}
}

View File

@ -0,0 +1,3 @@
# Placeholder for dotnet_bot.png
# Download from: https://raw.githubusercontent.com/dotnet/brand/main/dotnet-bot/dotnet-bot_waving.png
# Rename to: dotnet_bot.png

View File

@ -0,0 +1,3 @@
# Add the following images:
# - Icon.png (128x128) - Extension icon
# - Preview.png (200x200) - Preview image for marketplace

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
<Metadata>
<Identity Id="OpenMaui.VisualStudio.a1b2c3d4-e5f6-7890-abcd-ef1234567890" Version="1.0.0" Language="en-US" Publisher="MarketAlly LLC" />
<DisplayName>OpenMaui - Linux Platform for .NET MAUI</DisplayName>
<Description xml:space="preserve">Adds Linux platform support to .NET MAUI projects in Visual Studio. Build and deploy MAUI applications to Linux desktops with full SkiaSharp rendering support.
Features:
• Linux project templates
• Linux build configurations
• WSL debugging integration
• Remote Linux debugging
• Linux-specific launch profiles
Developed by MarketAlly LLC
Lead Architect: David H. Friedel Jr.</Description>
<MoreInfo>https://github.com/open-maui/maui-linux</MoreInfo>
<License>LICENSE.txt</License>
<GettingStartedGuide>https://github.com/open-maui/maui-linux/blob/main/docs/GETTING_STARTED.md</GettingStartedGuide>
<ReleaseNotes>https://github.com/open-maui/maui-linux/releases</ReleaseNotes>
<Icon>Resources\Icon.png</Icon>
<PreviewImage>Resources\Preview.png</PreviewImage>
<Tags>maui, linux, desktop, cross-platform, skia, openmaui, dotnet</Tags>
</Metadata>
<Installation>
<InstallationTarget Id="Microsoft.VisualStudio.Community" Version="[17.0,18.0)">
<ProductArchitecture>amd64</ProductArchitecture>
</InstallationTarget>
<InstallationTarget Id="Microsoft.VisualStudio.Pro" Version="[17.0,18.0)">
<ProductArchitecture>amd64</ProductArchitecture>
</InstallationTarget>
<InstallationTarget Id="Microsoft.VisualStudio.Enterprise" Version="[17.0,18.0)">
<ProductArchitecture>amd64</ProductArchitecture>
</InstallationTarget>
</Installation>
<Dependencies>
<Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="[4.8,)" />
<Dependency Id="Microsoft.VisualStudio.Component.CoreEditor" DisplayName="Visual Studio core editor" d:Source="Installed" Version="[17.0,18.0)" />
<Dependency Id="Microsoft.VisualStudio.Workload.NetCrossPlat" DisplayName=".NET MAUI Workload" d:Source="Installed" Version="[17.0,18.0)" />
</Dependencies>
<Prerequisites>
<Prerequisite Id="Microsoft.VisualStudio.Component.CoreEditor" Version="[17.0,18.0)" DisplayName="Visual Studio core editor" />
</Prerequisites>
<Assets>
<Asset Type="Microsoft.VisualStudio.ProjectTemplate" d:Source="File" Path="ProjectTemplates" d:TargetPath="ProjectTemplates" />
<Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
</Assets>
</PackageManifest>

143
vsix/README.md Normal file
View File

@ -0,0 +1,143 @@
# OpenMaui Visual Studio Extension
This Visual Studio extension adds Linux platform support for .NET MAUI applications.
## Features
### Project Templates
When installed, you'll see **"OpenMaui Linux App"** in Visual Studio's New Project dialog:
```
File → New → Project → Search "OpenMaui"
```
### Launch Profiles
The template includes pre-configured launch profiles:
| Profile | Description |
|---------|-------------|
| **Linux (Local)** | Run directly (requires Linux or WSL with GUI) |
| **Linux (WSL)** | Run via Windows Subsystem for Linux |
| **Linux (x64 Release)** | Build and run release for x64 |
| **Linux (ARM64 Release)** | Build and run release for ARM64 |
| **Publish Linux x64** | Create self-contained x64 package |
| **Publish Linux ARM64** | Create self-contained ARM64 package |
### How It Works
```
┌─────────────────────────────────────────────────────────┐
│ Visual Studio │
├─────────────────────────────────────────────────────────┤
│ File → New → Project │
│ └── OpenMaui Linux App ← This extension adds this │
├─────────────────────────────────────────────────────────┤
│ Debug Dropdown │
│ ├── Linux (Local) │
│ ├── Linux (WSL) ← Launch profiles │
│ ├── Linux (x64 Release) │
│ └── Publish Linux... │
└─────────────────────────────────────────────────────────┘
```
## Installation
### From Visual Studio Marketplace
1. Open Visual Studio 2022
2. Extensions → Manage Extensions
3. Search for "OpenMaui"
4. Click Download and restart VS
### From VSIX File
1. Download `OpenMaui.VisualStudio.vsix`
2. Double-click to install
3. Restart Visual Studio
## Building the Extension
### Prerequisites
- Visual Studio 2022 with "Visual Studio extension development" workload
- .NET Framework 4.8 Developer Pack
### Build Steps
```bash
cd vsix/OpenMaui.VisualStudio
dotnet restore
msbuild /p:Configuration=Release
```
The VSIX will be in `bin/Release/OpenMaui.VisualStudio.vsix`
## Project Structure
```
vsix/
└── OpenMaui.VisualStudio/
├── OpenMaui.VisualStudio.csproj # Extension project
├── source.extension.vsixmanifest # VSIX metadata
├── ProjectTemplates/ # VS project templates
│ └── OpenMauiLinuxApp/
│ ├── OpenMauiLinuxApp.vstemplate
│ ├── OpenMauiLinuxApp.csproj
│ ├── Program.cs
│ ├── App.cs
│ ├── MainPage.cs
│ ├── MainPage.xaml
│ └── Properties/
│ └── launchSettings.json
└── Resources/
├── Icon.png
└── Preview.png
```
## Adding Linux to Existing MAUI Projects
If you have an existing MAUI project and want to add Linux support:
### Option 1: Add Platform Folder
1. Add `Platforms/Linux/Program.cs` to your project
2. Add `OpenMaui.Controls.Linux` NuGet package
3. Copy `launchSettings.json` from template to `Properties/`
### Option 2: Create Companion Project
1. Create new "OpenMaui Linux App" project
2. Reference your shared MAUI library
3. Build Linux version separately
## Debugging on Linux
### Via WSL (Recommended)
1. Install WSL 2 with Ubuntu
2. Install .NET SDK in WSL: `sudo apt install dotnet-sdk-9.0`
3. Install X11 libs: `sudo apt install libx11-6`
4. Select "Linux (WSL)" profile and press F5
### Via Remote Machine
1. Set up SSH access to Linux machine
2. Install `vsdbg` on remote machine
3. Configure remote debugging in VS
### Via Virtual Machine
1. Set up Linux VM (VMware, VirtualBox, Hyper-V)
2. Share project folder with VM
3. Build and run inside VM
## Troubleshooting
### "Cannot find 'wsl.exe'"
Install WSL: `wsl --install` in PowerShell (Admin)
### "Display not found"
Ensure WSLg is enabled (Windows 11) or configure X server (Windows 10)
### Template not appearing
1. Clear template cache: `devenv /updateconfiguration`
2. Restart Visual Studio
## License
MIT License - Copyright (c) 2025 MarketAlly LLC
---
*Developed by MarketAlly LLC • Lead Architect: David H. Friedel Jr.*