Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Single File Publish - Embed MudBlazor's .\wwwroot\_content directory #147

Open
Dwarf1er opened this issue Jan 9, 2025 · 1 comment
Open
Labels
All OS enhancement New feature or request

Comments

@Dwarf1er
Copy link

Dwarf1er commented Jan 9, 2025

Hi all,

Project Dependencies

  • Blazor Server
  • MudBlazor
  • Photino.Blazor NuGet package

What I Tried

[ x ] I read the PublishPhotino README
[ x ] The fix recommended in this #94
[ x ] The fix recommended in this #106

ManifestEmbeddedFileProvider Invalid path: "wwwroot"

image

Even if my resources are correctly embedded I still get an error thrown by the embedded file provider saying that "wwwroot" is an invalid path:

services.AddSingleton<IFileProvider>(_ => new ManifestEmbeddedFileProvider(typeof(Program).Assembly, "wwwroot"));

Thanks

Here's my .csproj file for reference:

<Project Sdk="Microsoft.NET.Sdk.Web">

	<PropertyGroup>
		<OutputType>WinExe</OutputType>
		<TargetFramework>net8.0</TargetFramework>
		<ApplicationIcon>favicon.ico</ApplicationIcon>
		<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
		<PublishAot>false</PublishAot>
	</PropertyGroup>
	
	<ItemGroup>
		<PackageReference Include="Microsoft.AspNetCore.Components.WebView" Version="8.0.10" />
		<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.0">
			<PrivateAssets>all</PrivateAssets>
			<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
		</PackageReference>
		<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.0" />
		<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="9.0.0" />
        <PackageReference Include="MudBlazor" Version="7.15.0" />
		<PackageReference Include="Photino.Blazor" Version="3.2.0" />
	</ItemGroup>
	
	<ItemGroup Condition="$(RuntimeIdentifier.StartsWith('win'))">
		<RdXmlFile Include="rd.xml" />
		<RdXmlFile Include="Microsoft.AspNetCore.Components.Web.rd.xml" />
	</ItemGroup>

	<ItemGroup>
		<EmbeddedResource Include="wwwroot\**" />
		<EmbeddedResource Include="..\Common\bin\Release\net8.0\publish\wwwroot\**\*" />
	</ItemGroup>
	
	<Target Name="NormalizeLogicalName" BeforeTargets="BeforeBuild">
		<ItemGroup>
			<EmbeddedResource>
				<LogicalName>
					$(AssemblyName).wwwroot.$([System.String]::Copy('%(RecursiveDir)').Replace('\', '.'))%(Filename)%(Extension)
				</LogicalName>
			</EmbeddedResource>
		</ItemGroup>
	</Target>

	<ItemGroup>
		<Content Update="wwwroot\**\*">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
		</Content>
	</ItemGroup>

	<ItemGroup>
		<None Include="favicon.ico">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
		</None>
	</ItemGroup>
	
</Project>
@Dwarf1er
Copy link
Author

Dwarf1er commented Jan 10, 2025

So I've done some more digging and tried doing the exact same thing as was done in #106

I've ended up using the 2 repository approach to embed all the necessary resources in my assembly's Resources\ directory, along with the Manifest.xml file.

Here's my manifest file:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Manifest>
    <ManifestVersion>1.0</ManifestVersion>
    <FileSystem>
        <File Name="&#xD;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;LinguisticStimulationPlanner.wwwroot._content.MudBlazor.MudBlazor.min.css&#xD;&#xA;&#x9;&#x9;&#x9;&#x9;">
            <ResourcePath>
                 LinguisticStimulationPlanner.wwwroot._content.MudBlazor.MudBlazor.min.css
	    </ResourcePath>
        </File>
        <File Name="&#xD;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;LinguisticStimulationPlanner.wwwroot._content.MudBlazor.MudBlazor.min.js&#xD;&#xA;&#x9;&#x9;&#x9;&#x9;">
            <ResourcePath>
	         LinguisticStimulationPlanner.wwwroot._content.MudBlazor.MudBlazor.min.js
	    </ResourcePath>
        </File>
        <File Name="&#xD;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;LinguisticStimulationPlanner.wwwroot.index.html&#xD;&#xA;&#x9;&#x9;&#x9;&#x9;">
            <ResourcePath>
	         LinguisticStimulationPlanner.wwwroot.index.html
	    </ResourcePath>
        </File>
        <File Name="&#xD;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;LinguisticStimulationPlanner.wwwroot.linguistic-stimulation-planner.png&#xD;&#xA;&#x9;&#x9;&#x9;&#x9;">
            <ResourcePath>
	         LinguisticStimulationPlanner.wwwroot.linguistic-stimulation-planner.png
            </ResourcePath>
        </File>
        <File Name="Microsoft.Extensions.FileProviders.Embedded.Manifest.xml">
            <ResourcePath>Microsoft.Extensions.FileProviders.Embedded.Manifest.xml</ResourcePath>
        </File>
    </FileSystem>
</Manifest>

However, whenever I pass "wwwroot" to the ManifestEmbeddedFileProvider I get an error: Invalid path: "wwwroot"

Here's my Program.cs:

using LinguisticStimulationPlanner.Data;
using LinguisticStimulationPlanner.Services;
using LinguisticStimulationPlanner.Utilities;
using LinguisticStimulationPlanner.Components;
using Microsoft.EntityFrameworkCore;
using MudBlazor.Services;
using Photino.Blazor;
using Microsoft.Extensions.FileProviders;
using System;
using Microsoft.Extensions.DependencyInjection;

namespace LinguisticStimulationPlanner
{
    public class Program
    {
        [STAThread]
        public static void Main(string[] args)
        {
            PhotinoBlazorAppBuilder appBuilder = PhotinoBlazorAppBuilder.CreateDefault(args);

            ConfigureServices(appBuilder.Services);
            DatabaseSetup.SetupDatabase();

            appBuilder.RootComponents.Add<App>("app");

            PhotinoBlazorApp app = appBuilder.Build();

            app.MainWindow
                .SetSize(1400, 800)
                .SetLogVerbosity(0)
                .SetDevToolsEnabled(true)
                //.SetIconFile("favicon.ico")
                .SetTitle("Linguistic Stimulation Planner");

            AppDomain.CurrentDomain.UnhandledException += (sender, error) =>
            {
                app.MainWindow.ShowMessage("Fatal exception", error.ExceptionObject.ToString());
            };

            app.Run();
        }

        private static void ConfigureServices(IServiceCollection services)
        {
            string databasePath = DatabaseSetup.GetDatabasePath();

            services.AddLogging();
            services.AddSingleton<IFileProvider>(_ => new ManifestEmbeddedFileProvider(typeof(Program).Assembly, "wwwroot"));
            services.AddMudServices();
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlite($"Data Source={databasePath}"));

            services.AddScoped<GoalService>();
            services.AddScoped<LocationService>();
            services.AddScoped<PatientService>();
            services.AddScoped<ToyService>();
        }
    }
}

@MikeYeager MikeYeager added enhancement New feature or request All OS labels Feb 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
All OS enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants