Include Files using Wildcard into a folder in Visual Studio - visual-studio

I am using
<ItemGroup>
<EmbeddedResource Include="..\..\resources\hbm\*.hbm.xml" />
</ItemGroup>
to include a bunch of xml files into my C# project. Works fine.
But, I don't want them in the "root level" of my project, I would rather see them in a subfolder in my project.
For example, this file is included into a Mapping folder in Visual Studio:
<ItemGroup>
<EmbeddedResource Include="Mapping\User.hbm.xml" />
</ItemGroup>
That's what I want for my *.hbm.xml files.
I can't figure out how to do it and still keep my wildcard *.hbm.xml part and also keep the actual files in a different directory.
I've looked at MSDN's doc on MSBUILD and items, but no luck.

Perhaps this has changed in MSBuild since the original answer was posted, but it is possible to use both wildcards and links at the same time. For example, I use the following block in a C# project to import data files into a test library.
<ItemGroup>
<None Include="..\SOMENAME.Tests\data\**\*.*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>data\%(RecursiveDir)%(Filename)%(Extension)</Link>
</None>
</ItemGroup>
The only disadvantage I've seen so far is that MSBuild recreates the folder names on the file system (ie $(ProjectPath)\data\somesubfolder) which is a little annoying but not a huge issue.
As a test, I also tried the OP's request of embedding resources, using the following snippet, and again this seemed to work fine - dotPeek showed the resources were present in the compiled assembly in addition to being present in the Solution Explorer.
<ItemGroup>
<EmbeddedResource Include="..\SOMENAME.Tests\data\**\*.*">
<Link>resources\%(RecursiveDir)%(Filename)%(Extension)</Link>
</EmbeddedResource>
</ItemGroup>
(This was using Visual Studio 2013 and still works as of VS2019)
Update 08Jun2021: The above syntax works is fine for old style csproj files, but if you are using the new SDK format, the syntax is a little different, albeit simpler.
The OP's original question of wildcard embedding can be accomplished with the following
<ItemGroup>
<EmbeddedResource Include="data\**\*.*" />
</ItemGroup>
And to have wildcard file copies for changed or missing files.
<ItemGroup>
<None Update="data\**\*.*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

I think you can't use links and wildcard at the same time.
You could use this notation to link to include User.hbm.xml file in Mapping folder in Visual Studio :
<ItemGroup>
<EmbeddedResource Include="..\..\resources\hbm\User.hbm.xml">
<Link>Mapping\User.hbm.xml</Link>
</EmbeddedResource>
</ItemGroup>
But you can't do that
<ItemGroup>
<EmbeddedResource Include="..\..\resources\hbm\**\*.hbm.xml">
<Link>%(RecursiveDir)\%(Filename)%(Extension)</Link>
</EmbeddedResource>
</ItemGroup>

I have been able to create the logical name based on some regex (for only one folder depth). The root namespace I want is Agility.BmsData.Create and and example of the final name of the resource could be Agility.BmsData.Create.tables.mytable.sql where the file is in a folder tables\mytable.sql
<ItemGroup>
<EmbeddedResource Include="..\..\AgilityDatabase\Create\**\*.sql" >
<!-- see https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-well-known-item-metadata?view=vs-2022 -->
<!-- https://learn.microsoft.com/en-us/visualstudio/msbuild/property-functions?view=vs-2022 -->
<LogicalName>
Agility.BmsData.Create.$(
[System.Text.RegularExpressions.Regex]::Match("%(Directory)", "(?<=\\)[^\\]+(?=[\\]*$)")
).%(Filename)%(Extension)
</LogicalName>
</EmbeddedResource>
</ItemGroup>
It is also possible to customise the Link attribute of the EmbeddedResource element but the value needs to be suitably encoded for embedding in an xml attribute.
Following on from the above example, I have sql files located in the database project on a relative path to the current project of ..\..\AgilityDatabase\Create\ and I want to mimic the file structure (and resource names) in my other project. I can use the following MsBuild command $([System.Text.RegularExpressions.Regex]::Match("%(Directory)", "(?<=\\AgilityDatabase\\Create\\).+$"))\%(Filename)%(Extension)
So my Item group becomes:
<EmbeddedResource Include="..\..\AgilityDatabase\Create\**\*.sql"
Link="Create\$([System.Text.RegularExpressions.Regex]::Match("%(Directory)", "(?<=\\AgilityDatabase\\Create\\).+$"))\%(Filename)%(Extension)">
</EmbeddedResource>

Related

Xamarin forms Resources designer.cs not creating using visual studio mac

I'm facing a strange issue I have created a brand new xamarin forms project and i'm trying to adding Resource file in the shared project but when i add the Resource file then .resx extenshion file is created Like AppResources.resx creates but the code behind like AppResource.designer.cs not creating
Things that i have tried.
I have try multiple time and clean rebuild the project.
Create new project and try to again add resource file.
use custom tool to build the resource.
To manually fix the csproj, so it generates AppResources.designer.cs from AppResources.resx, follow these steps:
Close Solution (or quit Visual Studio).
Open YourProject.csproj in any text editor.
Find all lines that refer to AppResources.designer.cs or AppResources.resx.
Add or change as needed, to be similar to this (from https://github.com/xamarin/xamarin-forms-samples/blob/main/UsingResxLocalization/UsingResxLocalization/UsingResxLocalization/UsingResxLocalization.csproj):
<ItemGroup>
<Compile Update="Resx\AppResources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>AppResources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Resx\AppResources.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>AppResources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
Save the csproj file.
Open your solution.

Visual Studio - Prevent Creation of <Compile> and <None> tags when moving files in CSPROJ

In my CSPROJ I have a subfolder ›None‹. It is setup like this:
<ItemGroup Label="None">
<Compile Remove="None/**/*.cs" />
<None Include="None/**/*.cs" />
</ItemGroup>
In there I have CS files, that I don't want to compile.
No, I want to move a file (lets say ‌›CompileIt.cs‹ from ›None‹ back to the project, because now I want to compile it again.
If I move it outside of Visual Studio (like directly in the explorer or via PowerShell) it does exactly what I want, the file is now in a different folder inside the project and the Build-Action changes from ›None‹ to ›C# Compiler‹.
But if I move the file in Visual Studio, something different happens. Visual Studio changes the CSPROJ file like this:
<ItemGroup Label="None">
<Compile Remove="None/**/*.cs" />
<None Include="None/**/*.cs" />
</ItemGroup>
<ItemGroup>
<None Include="CompileIt.cs" />
</ItemGroup>
Now I have to either delete the ItemGroup from the CSPROJ again or change the "Build Action" in the Solution Explorer`s Properties page of the file.
Of course I know, this is usually exactly what you would expect, because normally a build action shouldn't change if you only move the file.
But anyway, is there a way to let Visual Studio know to not change CPSROJ file if I move a file inside it?
Or alternatively, is there a way to mark a subfolder in Visual Studio so that Visual Studios knows it should ignore all files in it?
PS: Oh, I forgot to say this, it is a Core-Style CSPROJ file, that means, all CS files are included automatically.

Visual Studio not respecting msbuild schema

Using Visual Studio 2017, I am trying to conditionally include a project based on the Configuration. I have added a Choose/When in the csproj of the project in question, instead of directly adding a condition on the project reference due to the problem with MSBUILD/Visual Studio integration (see the remark in this)
However, the build order is not respected when building through visual studio (the solution has been closed and reopened to make sure the Configuration is set).
Has anybody been through this problem?
The choose/when looks like the following:
<Choose>
<When Condition="'$(Configuration)' == 'MyConfiguration'">
<ItemGroup>
<ProjectReference Include="..\Project\MyProject.sqlproj">
<Name>MyProject</Name>
<Project>{ece60b8e-84ad-4c4d-94d3-97a1fb1a5d91}</Project>
<Private>True</Private>
</ProjectReference>
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<ProjectReference Include="..\Project\MyProject2.sqlproj">
<Name>MyProject2</Name>
<Project>{ece70c8e-84ad-4c4d-94d3-97a1fb1a5d93}</Project>
<Private>True</Private>
</ProjectReference>
</ItemGroup>
</Otherwise>
</Choose>
However, the build order is not respected when building through visual studio
I have created a sample with your code snippet, but it works fine on my side. Since there is no build log, I would like provide you some troubleshooting to help you find the reason for this issue.
First, I noticed that you reference different projects from the same project folder ..\Project\.., Could you confirm that is correct? Have you move the project file MyProject.sqlproj and MyProject2.sqlproj to the same folder Project? If not, please make sure the path of ProjectReference is correct, following is my code snippet:
<Choose>
<When Condition="'$(Configuration)' == 'Test'">
<ItemGroup>
<ProjectReference Include="..\MyProject\MyProject.sqlproj">
<Name>MyProject</Name>
<Project>{529deb62-9f35-4594-8627-203b19d7cb6d}</Project>
<Private>True</Private>
</ProjectReference>
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<ProjectReference Include="..\MyProject2\MyProject2.sqlproj">
<Name>MyProject2</Name>
<Project>{a6db4708-27d6-40b2-824e-f469372622d9}</Project>
<Private>True</Private>
</ProjectReference>
</ItemGroup>
</Otherwise>
</Choose>
Second, make sure the configuration for all projects are the same, for example, my configuration for all projects are Test:
With above condition project reference, the project MyProject.sqlproj only build when configuration is Test, otherwise, the project MyProject2.sqlproj will be built:
If above not help you, please share me the build log and what have you done, I will keep follow. Hope this helps.

Web config transformation in visual studio 2012

I am using visual studio 2012 and I am finding it difficult to add web.config files for diff environment. I looked at this link and tried right clicking on .pubxml file and choose add config transform option. After I do this, system adds web.simplePublish.config file which I am not able to rename using visual studio.
If I rename the file using windows explorer, the file is not listed under web.config tree in the solution.
What is the right way to add web.config files for various environments in Visual Studio 2012.
you can try to modify the *.csproj then find out the filename before you rename it and to revise the filename that you using windows explorer.
or you can just try to add a new tag into *.csproj
<ItemGroup>
<Content Include="..\default.licenseheader">
<Link>default.licenseheader</Link>
</Content>
<Content Include="packages.config" />
<None Include="Properties\PublishProfiles\xxxx.pubxml" />
<None Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon>
</None>
<None Include="Web.Release.config">
<DependentUpon>Web.config</DependentUpon>
</None>
<None Include="Web.SimplePublish.config">
<DependentUpon>Web.config</DependentUpon>
</None>
The other way that you can use Configuration Manager at your visual studio please refer the following link Add an Additional
I used SlowCheetah - XML Transforms plugin of visual studio to create web.config files for diff environment.

Conditionally embed ASP.NET MVC2 Views as resources during build in Visual Studio 2010

I have a ASP.NET MVC2 project in VS2010 that can be deployed in two modes: standalone or plugin. In standalone mode, the views should live outside the compiled assembly as .aspx files (the default setup). In plugin mode, the views are switched (currently by hand) to embedded resources and the entire assembly is dropped into a host project folder.
Currently, this requires the developer to go through each view and switch it from Build Action: "Content" to "Embedded Resource" and vice versa. I would like to create a new solution configuration to automatically grab all .aspx files and build them as resources.
This SO post seems like the solution, but I would prefer not to have to edit the .csproj every single time I add a new view to the project. Is there a way to use a wild cards or some other batch/global conditionally statement to change resources from content to embedded?
Well, sometimes I should experiment before I post.
I modified my .csproj file and just went ahead and tried a wild card:
Views\*\*.aspx
...and it worked great. I posted a snippet of my reconfigured project file below. One thing to note: adding a new view puts it in the "always content" category at the top of the snippet below. You can either live with having .aspx files deployed even when the views are embedded as resources (not an issue for me) or you can move them from the first ItemGroup below to the Otherwise section each time by hand.
<ItemGroup> <-- Always included as content
<Content Include="Global.asax" />
<Content Include="Web.config">
<SubType>Designer</SubType>
</Content>
<Content Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon>
</Content>
<Content Include="Web.Release.config">
<DependentUpon>Web.config</DependentUpon>
</Content>
</ItemGroup>
<Choose> <--- Only added to assembly in "Plugin Mode"
<When Condition=" '$(Configuration)'=='Plugin' ">
<ItemGroup>
<EmbeddedResource Include="Views\*\*.aspx">
</EmbeddedResource>
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<Content Include="Views\Comment\Create.aspx" />
<Content Include="Views\Record\Create.aspx" />
</ItemGroup>
</Otherwise>
</Choose>

Resources