Can't add images to new .NET MAUI project on Mac without getting: The name 'Resources' is reserved and cannot be used - visual-studio

I just started a brand new template .NET MAUI project on my Mac and I am able to build and run the startup project with no problems.
When I add any image to the "Resources/Images" folder and then try to build the project I get the error:
Error Description:
The name 'Resources' is reserved and cannot be used.
Error Path:
Resources/Images/icon_notes.png
SPECS
Visual Studio for Mac 17.4 Preview (17.4 build 2326)
I have tried cleaning and rebuilding the project but that does not help.
Steps to reproduce:
Install Visual Studio for Mac 17.4 Preview
Create new .NET MAUI project from startup template offered by the IDE
Build and run to make sure it runs properly (It will).
Add any image to the "Resources/Images" folder and then try to rebuild.
Please help me understand what is wrong here and how to fix it.
Here is my csproj file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0-android;net6.0-ios;net6.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net6.0-windows10.0.19041.0</TargetFrameworks>
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
<!-- <TargetFrameworks>$(TargetFrameworks);net6.0-tizen</TargetFrameworks> -->
<OutputType>Exe</OutputType>
<RootNamespace>Notes</RootNamespace>
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>
<ImplicitUsings>enable</ImplicitUsings>
<!-- Display name -->
<ApplicationTitle>Notes</ApplicationTitle>
<!-- App Identifier -->
<ApplicationId>com.companyname.notes</ApplicationId>
<ApplicationIdGuid>2cc957c4-bc4d-4867-9002-8475070561fa</ApplicationIdGuid>
<!-- Versions -->
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
<ApplicationVersion>1</ApplicationVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">14.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
</PropertyGroup>
<ItemGroup>
<!-- App Icon -->
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />
<!-- Splash Screen -->
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128" />
<!-- Images -->
<MauiImage Include="Resources\Images\*" />
<MauiFont Include="Resources\Fonts\*" />
<!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
</Project>
Here is the properties on the image that is causing this:

Thanks to Liqun Shen for the direction to the solution.
The issue is that when you add an image to the Resources/Images folder and check your csproj file you will see that each image is added as an ItemGroup to the csproj file. This must be some sort of bug and the solution was to manually delete these from the csproj file after which the code builds and runs properly.
I know that in my csproj file I listed about these ItemGroups for each image added wasn't showing but checking again they were there and removing them fixed my issue. I must have copied my csproj file from one of my attempts at erasing my project and retrying again and before I added the image.
<ItemGroup>
<None Remove="Resources\Images\icon_notes.png" />
</ItemGroup>
Here is the link that Liqun Shen posted that describes this:
https://github.com/dotnet/maui/issues/10531

I have the same error from new MAUI project (No Razor) on VS for Mac v17.4.4: The name 'Resources' is reserved and cannot be used.
What I did was:
Edit "ProjectName.csproj" and change all references to folder "Resources" and renamed to "ResourcesNet"
Change the folder name from "Resources" to "ResourcesNet"
Change in App.xaml all references to "Resources" to "ResourcesNet"

Related

Build exe and webapp using msbuild commandline

I am trying to build a solution using ms-build command line, which contains multiple projects.
Four of them are creating an exe file as output and rest are creating a single web application.
Now when I try to build them together using msbuild, it throws out error-
/p:WebPublishMethod=Package /p:DeployOnBuild=true /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:outdir="$(build.artifactstagingdirectory)\\"
Error -
error MSB4057: The target "ResolveWebJobFiles" does not exist in the
project.
Note - If I remove property "/p:WebPublishMethod=Package" then it runs well but doesn't create the zip file.
Can anyone please suggest me any property by which I can create the zip file?
Can anyone please suggest me any property by which I can create the zip file?
Are you deployed the web application as Azure WebJobs with the Azure Website? If yes, you should make sure the you have installed the below package in your web project. The package id="Microsoft.Web.WebJobs.Publish" version="1.0.2".
If not, I am not very sure the reason why you got this error "The target "ResolveWebJobFiles" does not exist in the
project" before I can access your web project. But I would like provide a workaround to you, you can check if it works for you:
Edit the *.csproj file, add zip target in your project file:
<ItemGroup>
<Link Include="bin\*.dll" />
<Link Include="bin\*.exe" />
<Link Include="bin\*.exe.config" />
</ItemGroup>
<Import Project="..\.build\MSBuild.Community.Tasks.Targets" />
<Target Name="AfterBuild" Condition="'$(Configuration)' == 'Release'">
<PropertyGroup>
<ReleasePath>bin</ReleasePath>
</PropertyGroup>
<Zip Files="#(Content);#(Link)" WorkingDirectory="$(ReleasePath)" ZipFileName="output\$(AssemblyName).zip" ZipLevel="9" />
</Target>
Note: You need add the nuget package "MSBuildTasks" and you can change the ReleasePath to other folder.
See this document for more detail info.
The issue was with Webjob-List.json file that can be found in properties.
I was using an old reference for the project that was missing from there, deleting the path solved the problem.

dll.refresh with devenv vs msbuild (Website Project, not application)

I am creating a CI server for our application(s) and have run into an issue with msbuild for our Website Project. It builds off a solution, but no proj file (as it is not a website application and cannot be). MSBuild won't pull in the dll.refresh files into the bin folder. (Not specific to a CI issue, but that's the goal) If I run it against devenv.com (CLI attempts) to build then it does pull in the dll.refresh and appears to work just fine.
From what I can find on MsBuild logs, it appears the the Copy task (which is just the default rule from msbuild itself) doesn't target the /bin folder when looking for the DLL files, but the root of the solution (/www in this case).
Just looking for some more information, as all other research points have seeming run dry at this point. (Does it have to be Msbuild? No, but I would like to make the CI configuration very simple for anyone else to re-produce and a custom build script/batch file and VS install on the CI server would make it much more complex).
Thanks.
I cannot reproduce the behavior you describe using VS2013 / MSBuild 12.0.31101.0.
Repro:
Create new website in VS
Add Reference to assembly on disk
Clean the bin directory of all files except *.refresh
Save all
Run msbuild WebsiteSolution.sln
Result: DLLs referenced in the *.refresh are re-created.
A read-through of the generated MSBuild file shows that the paths in the *.refresh files are resolved relative to the base directory of the website. I will note that this only occurs on the Build target, so I don't know what you mean when you say "the Copy task [...] is the default rule". Perhaps you are using some custom MSBuild target which needs to include the default target?
The relevant parts of the generated MSBuild (produced with MSBuildEmitSolution=1):
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<PropertyGroup>
<!-- Edit: Snipped -->
<!-- The website location is stored relative to the .sln -->
<!-- (which is the same as the location of the temporary msbuild file) -->
<Project_[...]_AspNetPhysicalPath>..\..\WebSites\WebSite1\</Project_[...]_AspNetPhysicalPath>
<!-- Edit: Snipped -->
</PropertyGroup>
<ItemDefinitionGroup />
<!-- Edit: Snipped -->
<Target Name="Build" Condition=" ('$(CurrentSolutionConfigurationContents)' != '') and (false or ( ('$(Configuration)' == 'Debug') and ('$(Platform)' == 'Any CPU') ) or ( ('$(Configuration)' == 'Release') and ('$(Platform)' == 'Any CPU') )) " DependsOnTargets="GetFrameworkPathAndRedistList">
<!-- Edit: Snipped -->
<!-- *.refresh items are discovered and saved in [...]_References_RefreshFile -->
<CreateItem Include="$(Project_[...]_AspNetPhysicalPath)\Bin\*.refresh">
<Output TaskParameter="Include" ItemName="Project_[...]_References_RefreshFile" />
</CreateItem>
<!-- The contents of the *.refresh are read to [...]_References_ReferenceRelPath -->
<ReadLinesFromFile Condition=" '%(Project_[...]_References_RefreshFile.Identity)' != '' " File="%(Project_[...]_References_RefreshFile.Identity)">
<Output TaskParameter="Lines" ItemName="Project_[...]_References_ReferenceRelPath" />
</ReadLinesFromFile>
<!-- Those contents are relative to [...]_AspNetPhysicalPath -->
<CombinePath BasePath="$(Project_[...]_AspNetPhysicalPath)" Paths="#(Project_[...]_References_ReferenceRelPath)">
<Output TaskParameter="CombinedPaths" ItemName="Project_[...]_References" />
</CombinePath>
<!-- This seems to be a no-op, since you cannot copy if it doesn't exist -->
<Copy Condition="!Exists('%(Project_[...]_References.Identity)')" ContinueOnError="true" SourceFiles="#(Project_[...]_References->'%(FullPath)')" DestinationFolder="$(Project_[...]_AspNetPhysicalPath)\Bin\" />
<!-- Edit: Snipped -->
<!-- This will copy [...]_References to [...]_References_CopyLocalFiles and add references -->
<ResolveAssemblyReference Condition="Exists('%(Project_[...]_References.Identity)')" Assemblies="#(Project_[...]_References->'%(FullPath)')" TargetFrameworkDirectories="$(Project_[...]__TargetFrameworkDirectories)" FullFrameworkFolders="$(Project_[...]__FullFrameworkReferenceAssemblyPaths)" SearchPaths="{RawFileName};{TargetFrameworkDirectory};{GAC}" FindDependencies="true" FindSatellites="true" FindSerializationAssemblies="true" FindRelatedFiles="true" TargetFrameworkMoniker=".NETFramework,Version=v4.5">
<Output TaskParameter="CopyLocalFiles" ItemName="Project_[...]_References_CopyLocalFiles" />
</ResolveAssemblyReference>
<!-- [...]_References_CopyLocalFiles is copied to the bin directory -->
<Copy Condition="(false) or ('$(AspNetConfiguration)' == 'Debug') or ('$(AspNetConfiguration)' == 'Release')" SourceFiles="#(Project_[...]_References_CopyLocalFiles)" DestinationFiles="#(Project_[...]_References_CopyLocalFiles->'$(Project_[...]_AspNetPhysicalPath)\Bin\%(DestinationSubDirectory)%(Filename)%(Extension)')" />
<!-- Edit: Snipped -->
</Target>
<!-- Edit: Snipped -->
</Project>
I have not tried this on a machine which does not have VS installed, so it may not apply directly, but you should definitely be able to build with the generated metaproj file even without Visual Studio installed.
I had this problem as well; the problem was actually that our build configuration was neither Debug nor Release, so msbuild was actually skipping the compile (and thus the restore with *.refresh):
Skipping because the "Dev" configuration is not supported for this web
project. You can use the AspNetConfiguration property to override the
configuration used for building web projects, by adding
/p:AspNetConfiguration= to the command line. Currently web
projects only support Debug and Release configurations.

Custom Build Rule fails after converting to VS2013

I need to integrate a legacy VS2008 project into my VS2013 solution. This project uses some custom build rules which initially worked after converting the .vcproj to a .vcxproj. However, when doing a fresh checkout of the project including the .vcxproj, the project file can no longer be opened.
I've tracked it down to this issue:
The project file references a couple of custom build rules like this:
<ImportGroup Label="ExtensionSettings">
<Import Project="..\..\..\tools\build\ms_mc.props" />
(8 similar lines follow)
</ImportGroup>
However, the ms_mc.props file is not present, but there is a ms_mc.rule file. If I convert the VS2008 solution with VS2013 (and assumably also if I opened it in VS2008, which I don't possess), the ms_mc.props file (plus a .targets and a .xml file) is created. However, if I delete that file and open the converted VS2013 project, the file does not get created.
I realized, in the old .vcproj, the corresponding lines are
<ToolFiles>
<ToolFile RelativePath="..\..\..\tools\build\ms_mc.rule" />
(8 similar lines follow)
</ToolFiles>
Why does VS2008 reference the .rule file and VS2013 imports the .props file without specifying the .rule file? And more importantly: How can I make this work again?
The .rule and .props file are added for reference
ms_mc.rule:
<?xml version="1.0" encoding="utf-8"?>
<VisualStudioToolFile
Name="MS MC"
Version="8,00"
>
<Rules>
<CustomBuildRule
Name="MS_MC"
DisplayName="Microsoft Message Catalogue Compiler"
CommandLine="mc [Verbose] [inputs] [RCIncludePath] [CIncludePath]"
Outputs="[$RCIncludePath]\$(InputName).rc;[$RCIncludePath]\$(InputName).h"
FileExtensions="*.mc"
ExecutionDescription="Compiling Message Catalogue $(InputName).mc"
>
<Properties>
<BooleanProperty
Name="Verbose"
DisplayName="Verbose"
Description="Gives verbose output. (-v)"
Switch="-v"
/>
<StringProperty
Name="RCIncludePath"
DisplayName="RC include file path"
Description="Gives the path of where to create the RC include file and the binary message resource files it includes. (-r [pathspec])"
Switch="-r [value]"
DefaultValue=".\"
/>
<StringProperty
Name="CIncludePath"
DisplayName="C include file path"
Description="Gives the path of where to create the include header file. (-h [pathspec])"
Switch="-h [value]"
DefaultValue=".\"
/>
</Properties>
</CustomBuildRule>
</Rules>
</VisualStudioToolFile>
ms_mc.props (after Conversion to VS2013):
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup
Condition="'$(MS_MCBeforeTargets)' == '' and '$(MS_MCAfterTargets)' == '' and '$(ConfigurationType)' != 'Makefile'">
<MS_MCBeforeTargets>Midl</MS_MCBeforeTargets>
<MS_MCAfterTargets>CustomBuild</MS_MCAfterTargets>
</PropertyGroup>
<PropertyGroup>
<MS_MCDependsOn
Condition="'$(ConfigurationType)' != 'Makefile'">_SelectedFiles;$(MS_MCDependsOn)</MS_MCDependsOn>
</PropertyGroup>
<ItemDefinitionGroup>
<MS_MC>
<Verbose>False</Verbose>
<RCIncludePath>.\</RCIncludePath>
<CIncludePath>.\</CIncludePath>
<CommandLineTemplate>mc [Verbose] [inputs] [RCIncludePath] [CIncludePath]</CommandLineTemplate>
<Outputs>%(RCIncludePath)\%(Filename).rc;%(RCIncludePath)\%(Filename).h</Outputs>
<ExecutionDescription>Compiling Message Catalogue %(Filename).mc</ExecutionDescription>
</MS_MC>
</ItemDefinitionGroup>
</Project>
I found this blog post for VS2010 which states the following:
Custom build rule is a build feature introduced in VS2005. It provides the ability for the users to easily Plug-In third party tools to use in their build process. The custom build rule is defined by “.rules” files.
and more importantly
In VS2010, due to the migration to MSBuild, the information in the rules file is represented by three files: .XML, .props and .targets files.
This basically means that the .XML, .props and .targets files are in fact not created by VS2008; instead, they are a replacement of the old .rules file format since VS2010. Using this information, I can now safely check in those new files without breaking the VS2008 solution. I might have to adapt the new files manually in order to make them work as before, as also mentioned in the blog.

Is there a way to add an 'Import' to a project in a VS extension?

I want to add a new <Import> to a project when I detect that a particular type of file has been added to the project. (the <Import> adds a task to the build process that takes the file and performs work during a build).
(Detection of a file having been added to the project is done using IVsSolutionEvents.HandleItemAdded).
I currently have code that uses Microsoft.Build.Evaluation.Project to add an Import element to the project. However this is an edit to a project file on disk. If I use this code to add an Import after detecting the addition of a new item to the project I create a conflict between a change on disk (the new Import) and an in-memory change (the addition of the new file). The user is then presented with a dialog where they must choose which change to throw away.
My question is this:
Is there a way to add a new <Import> to a project via the visual studio extensibility API in such a way that the modification to the project would be "in-memory", avoiding a conflict between the addition of the new project item, and the addition of the Import?
For existing project types, I've found the easiest way is leveraging NuGet. You can define a NuGet package which contains the .targets file in a special build/ folder, and NuGet will automatically add the <Import> when it is added to a project within Visual Studio. It will also update the references if you upgrade the package in the future. A full example is the packaging of the Antlr4BuildTasks package, which currently uses the following .nuspec file to create the package. The key here is the section following the <!-- Build Configuration --> comment.
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata minClientVersion="2.7">
<id>Antlr4</id>
<version>0.0.0</version>
<authors>Sam Harwell, Terence Parr</authors>
<owners>Sam Harwell</owners>
<description>The C# target of the ANTLR 4 parser generator for Visual Studio 2010+ projects. This package supports projects targeting .NET 2.0 or newer, and built using Visual Studio 2010 or newer.</description>
<language>en-us</language>
<projectUrl>https://github.com/sharwell/antlr4cs</projectUrl>
<licenseUrl>https://raw.github.com/sharwell/antlr4cs/master/LICENSE.txt</licenseUrl>
<iconUrl>https://raw.github.com/antlr/website-antlr4/master/images/icons/antlr.png</iconUrl>
<copyright>Copyright © Sam Harwell 2014</copyright>
<releaseNotes>https://github.com/sharwell/antlr4cs/releases/v$version$</releaseNotes>
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<developmentDependency>true</developmentDependency>
<tags>antlr antlr4 parsing</tags>
<title>ANTLR 4</title>
<summary>The C# target of the ANTLR 4 parser generator for Visual Studio 2010+ projects.</summary>
<dependencies>
<dependency id="Antlr4.Runtime" version="$version$" />
</dependencies>
</metadata>
<files>
<!-- Tools -->
<file src="..\tool\target\antlr4-csharp-$CSharpToolVersion$-complete.jar" target="tools"/>
<!-- Build Configuration -->
<file src="..\runtime\CSharp\Antlr4BuildTasks\bin\net40\$Configuration$\Antlr4.net40.props" target="build\Antlr4.props"/>
<file src="..\runtime\CSharp\Antlr4BuildTasks\bin\net40\$Configuration$\Antlr4.net40.targets" target="build\Antlr4.targets"/>
<file src="..\runtime\CSharp\Antlr4BuildTasks\bin\net40\$Configuration$\Antlr4BuildTasks.net40.dll" target="build"/>
</files>
</package>

Is there a way to add source files to visual studio project from command-line?

I want to use sublime to edit a visual studio project.
I have a custom build:
{
"cmd": ["c:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\MSBuild.exe"],
"working_dir": "${project_path:${folder:${file_path}}}/../Project"
}
But if I add new files I also need to include them in the project.
Is there a way to do this from the command line, maybe at compile-time?
I am working with opengl using c++;
I basically set up a project using one of the examples provided on the opengl website.
Then I opened the project folder in sublime text and successfully compiled it using the custom build system.
However, when I add NEW source files to the project (*.h and *.cpp) I get a linking error.
I get the same error when I build in visual studio.
The error disappeared after I had included the files by manually browsing and adding them to the project.
What I wanted was a way to automatically add all the source files in a folder to the project(via command line, or wildcard or smth else).
This way I can easily work on a vs2010 project in sublime, add new source files and build the project.
Or maybe there already is a better workflow for this?
You could try to modify your .vcxproj file to include any .h and .cpp file in your project folder or folders below.
In case of a c++ VS project you can try to alter your .vcxproj file like this:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- rest of project file untouched -->
<!-- start of modified part -->
<ItemGroup>
<ClInclude Include="**\*.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="**\*.cpp" />
</ItemGroup>
<!-- end of modified part -->
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
Be aware that adding files to your project from inside VS at later point will replace the modification described above!
As an alternative you could also create an external project file holding the same <ItemGroup /> elements described above and include this project file into your .vcxproj.
I'll add an example of this alternative if you're interested.

Resources