Including auto-generated static content in Visual Studio - c#

My web application has a node process that runs things like transpilation and minification, and produces a bunch of output files. We've had problems with our CI server not sending these auto-generated files out unless they were manually included in the project.
Manually including auto-generated files is a pain, is easy to forget, and just an all-around bad idea.
How can I get visual studio to just include everything under a specific folder, no matter what. I just need these files to exist to my script loader can load them when needed.
Per this answer I tried
<Target Name="BeforeBuild">
<ItemGroup>
<Content Include="2\application-base\**\*.js" />
</ItemGroup>
</Target>
to no avail. After adding that I've tried building the solution, the project, re-building the project, none of which cause anything in that folder to show up in the solution explorer as included.

Just put Content in the main ItemGroup of the project.
Ie
<ItemGroup>
<Content Include="2\application-base\**\*" />

Related

.NET Maui The name 'InitializeComponent' does not exist in the current context

I have created a ResourceDictionary file that comes with a .cs file. So afer creating the ResourceDictionary file I'm getting an error The name 'InitializeComponent' does not exist in the current context.
Below is the xaml file associated with the above file.
I'm using VS2022 17.5.0 Preview 1.0
I have set the build action for the c# file to C# Compiler
I have cleaned and rebuilt my project several times and tried deleting the bin and obj folders nothing seems to work
When I do Project / rt-click / Add / NewItem / .Net Maui ResourceDictionary (XAML), this is what gets added to .csproj:
<MauiXaml Update="Dictionary1.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
Note that the Compile is nested within the MauiXaml element; it is not a separate Item.
See if your .csproj has TWO separate Items, one for Dictionary1.xaml, another for Dictionary1.xaml.cs.
If so, replace those two items, with a combined item as shown above.
(For me, this builds without problem.)
In your case, the .csproj doesn't show MauiXaml BuildAction?
Replace:
<ItemGroup>
<None Include="Themes\Light.xaml" />
</ItemGroup>
with:
<ItemGroup>
<MauiXaml Update="Themes\Light.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
</ItemGroup>
I don't know whether this should be kept or removed:
<ItemGroup>
<Folder Include="Themes\" />
</ItemGroup>
Leave it in for now.
This sounds like a similar issue that often plagues Xamarin solutions. I think that there's an underlying bug, or delay in interpreting the files when displayed within Visual Studio.
Several options:
Make a small change to the file in question - even adding or deleting a space will do, save it and rebuild solution.
Clean the solution and rebuild.
Unload and reload project to which the files belong. (Right click on the project in Solution explorer window, select unload, then select load.
Xaml files may need to be set as embedded resource as their Build Action under their properties (again in Solution explorer).

Why is Visual Studio creating .meta files even outside Assets folder?

I have the following project setup:
Unity project in C:\XXX
Added an another project to solution, located in C:\XXX\Tests
Now, whenever adding a class to that Test project, I found that a .meta file is being added as well.
This doesn't seem correct as .meta files are supposedly only for files inside Assets.
Using Process Monitor I discovered that indeed it is devenv.exe that is creating these .meta files.
Quick-fix:
Using ignores Visual Studio and Unity ignores, these .meta files are not committed to the repository,
And adding this to the csproj will hide them:
<ItemGroup>
<None Update="**/*.meta" Visible="false" />
</ItemGroup>
But in reality, this only hides the problem ...
And unfortunately, this approach won't work in Directory.Build.props, forcing one to manually add former code block to each of these 'external' projects.
Question:
Why are .meta files also created outside Assets and how to turn that off?
For now, putting this in Directory.Build.props at root effectively removes the need to manually update each project:
<Project>
<PropertyGroup>
<DefaultItemExcludes>$(DefaultItemExcludes);**\*.meta</DefaultItemExcludes>
</PropertyGroup>
</Project>
But this only hides the problem instead of fixing it...
Update
The problem comes from Resharper and has been fixed:
Avoid creating meta files outside Assets and Packages (#1489)

How to publish additional files into bin folder

My .net web app project also includes some unmanaged dlls as additional files.
These are a couple of levels deep in subfolders.
When I publish this project I need these files to be copied to the bin folder alongside all the other binaries.
No matter what settings I try, the best I can get is for them to be published into their existing folder structure which is not where I need them to be.
I've created a PostBuild event to copy the files and this works when building locally but not when publishing to a server. I've not been able to get PostPublish events to work in the same way.
Is there another way to achieve this?
Note this is similar but not the same as a previous question:
Publish unmanaged DLL from referenced project
I have a similar setup. 2 projects in my solution, one .NET Core and the other C++. When I am going to publish the dotnetcoreapp2.2 I want to include the precompiled C++ DLL from the other project.
#JuanR's answer is not working for me, though it is already pretty close to my version. It looks like the <ItemGroup> needs to be in the <Target> tag.
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
<ItemGroup>
<DataModelFiles Include="$(ProjectDir)..\MyCppProject\bin\Release\MyCppProject.dll" />
</ItemGroup>
<Copy SourceFiles="#(DataModelFiles)" DestinationFolder="$(PublishDir)" SkipUnchangedFiles="false" />
</Target>
Try using an after-publish task.
You can create an item group for copy:
<ItemGroup>
<binFilesToCopy Include="$(OutDir)\somepath\to\yourexternalDLLFolder\*" />
<!-- Add more folders/files you want to copy here -->
</ItemGroup>
Then add a target for after publishing:
<Target Name="AfterPublish">
<Copy SourceFiles ="#(binFilesToCopy)" DestinationFolder ="$(OutDir)\bin" />
</Target>
I did this mostly from memory so double-check for syntax, but get you the idea.
In the properties of the file you can set Copy to output directoryto Copy always or you can edit the solution file, expand the xml tag of the file needed and add <CopyToOutputDirectory>Always</CopyToOutputDirectory> as sub-tag.

Web.config transformation causing an error when building [duplicate]

I can run my Asp.Net MVC 2 application without an issue on my local computer. Just Run / Debug.
But if I have already built it, I can't publish it! I have to clean the solution and publish it again. I know this is not system critical, but it's really annoying. "One Click Publish" is not "Clean solution and then One click publish"
The exact error is as follows:
Error 11 It is an error to use a
section registered as
allowDefinition='MachineToApplication'
beyond application level. This error
can be caused by a virtual directory
not being configured as an application
in IIS.
I suspect it's something to do with the Web.Config in the Views folder, but then why only after I build once previously. And just to note, the app works fine once published.
i had the same problem with my MVC apps. it was frustrating because i still wanted my views to be checked, so i didn't want to turn off MvcBuildViews
luckily i came across a post which gave me the answer. keep the MvcBuildViews as true, then you can add the following line underneath in your project file:
<BaseIntermediateOutputPath>[SomeKnownLocationIHaveAccessTo]</BaseIntermediateOutputPath>
And make that folder not in your project's folder. Works for me. It's not a perfect solution, but it's good for the moment. Make sure you remove the package folder (located inside the obj\Debug and/or obj\Release folder) from your project folder otherwise you'll keep getting the error.
FWIW, MS know about this error...
I deleted everything out of my obj/Debug folder and it fixed this error. This allowed me to leave in the
<MvcBuildViews>true</MvcBuildViews>
option in my project file (which comes in handy with the T4MVC T4 template).
Edit:
This can be achieved much easier by simply using the "Build" -> "Rebuild Solution" menu (because what rebuild actually does is clear the obj/Debug folder and then build solution).
I'm using this workaround on the MS Connect page for this error. It cleans all obj and temp files under your project (all configurations) before running AspNetCompiler.
Modify the MvcBuildViews target in
your project file so that it depends
on the targets that clean up the
packaging files that Visual Studio has
created. These targets are included in
web application projects
automatically.
All packaging files will be deleted
every time that the MvcBuildViews
target executes.
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'" DependsOnTargets="CleanWebsitesPackage;CleanWebsitesPackageTempDir;CleanWebsitesTransformParametersFiles;">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(MSBuildProjectDirectory)" />
</Target>
This problem occurs when there is web project output (templated web.config or temporary publish files) in the obj folder. The ASP.NET compiler used isn't smart enough to ignore stuff in the obj folder, so it throws errors instead.
Another fix is to nuke the publish output right before calling <AspNetCompiler>. Open your .csproj and change this:
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>
to this:
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<ItemGroup>
<ExtraWebConfigs Include="$(BaseIntermediateOutputPath)\**\web.config" />
<ExtraPackageTmp Include="$([System.IO.Directory]::GetDirectories("$(BaseIntermediateOutputPath)", "PackageTmp", System.IO.SearchOption.AllDirectories))" />
</ItemGroup>
<Delete Files="#(ExtraWebConfigs)" />
<RemoveDir Directories="#(ExtraPackageTmp)" />
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>
That will delete all web.configs under \obj, as well as all PackageTmp folders under \obj.
If you are using Web Publish, you can set MvcBuildViews=false and PrecompileBeforePublish=true, which precompiles after the copy to the temporary folder (immediately before publish/package).
NOTE: PrecompileBeforePublish is only supported by the "new" Web Publishing Pipeline stack (VS2010 SP1 + Azure SDK or VS2012 RTM). If you're using VS2010 RTM, you'll need use one of the alternative methods.
Regarding the solution by jrummell, the setting:
DependsOnTargets="CleanWebsitesPackage;CleanWebsitesPackageTempDir;CleanWebsitesTransformParametersFiles;"
It works in VS 2010, but not in VS 2012. In 2012 you have to put:
DependsOnTargets="CleanWebsitesPackage;CleanWebsitesWPPAllFilesInSingleFolder;CleanWebPublishPipelineIntermediateOutput"
Source:
VS 2010:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets
VS 2012:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.targets
I know this has been answered but I just wanted to add something interesting I found.
I had set the "MvcBuildViews" to false in the project, deleted all bin and obj folders and I was still getting the error. I found that there was a ".csproj.user" file that still had "MvcBuildViews" set to true.
I deleted the ".csproj.user" file and then it all worked.
So make sure if you are changing your csproj file that you either change or delete the ".csproj.user" file also.
I had this problem as well, so I created a Pre-Build Event in the project properties to Clean the output directories(${projectPath}\bin,${projectPath}\obj\${ConfigurationName}). On another project I was also getting this error, even with the cleaning event in place. On the second project I was compiling the views as listed in the project file:
<MvcBuildViews>true</MvcBuildViews>
I changed the true to false, and it no longer complained about that error, but still ran correctly. I won't claim I know exactly what was causing the second error, but at least it got me moving forward for the time being.
The problem has to do with the intermediate files, but there is another solution which consist in cleaning up those intermediate files before builnding the views.
This solution has been included in some version of VS, but I can only say that I had the problem in VS 2013 Update 5. (See the "Beware" below, it could be fixed in this version, but not working only in my particular non-standard case).
I borrowed the soltuion from Error: allowDefinition='MachineToApplication' beyond application level on Visual Studio Connect.
The solution consist in including these lines to the web application project (.csproj file) which handle the deletion of the offedning intermediate files:
<!--Deal with http://connect.microsoft.com/VisualStudio/feedback/details/779737/error-allowdefinition-machinetoapplication-beyond-application-level,
we will need to clean up our temp folder before MVC project starts the pre-compile-->
<PropertyGroup>
<_EnableCleanOnBuildForMvcViews Condition=" '$(_EnableCleanOnBuildForMvcViews)'=='' ">true</_EnableCleanOnBuildForMvcViews>
</PropertyGroup>
<Target Name="CleanupForBuildMvcViews" Condition=" '$(_EnableCleanOnBuildForMvcViews)'=='true' and '$(MVCBuildViews)'=='true' " BeforeTargets="MvcBuildViews">
<ItemGroup>
<_PublishTempFolderNamesToCleanup Include="Database;TransformWebConfig;CSAutoParameterize;InsertAdditionalCS;ProfileTransformWebConfig;Package;AspnetCompileMerge" />
</ItemGroup>
<!--Force msbuild to expand all the wildcard characters so to get real file paths-->
<CreateItem Include="#(_PublishTempFolderNamesToCleanup->'$(BaseIntermediateOutputPath)**\%(identity)\**\*')">
<Output TaskParameter="Include" ItemName="_EvaluatedPublishTempFolderNamesToCleanup" />
</CreateItem>
<Delete Files="#(_EvaluatedPublishTempFolderNamesToCleanup)" />
</Target>
Beware: for some reason, probably because I included it myself in the project, my build target for building the views was named "BuildViews", instead of "MvcBuildViews", so I had to modify the BeforeTargets attribute accordingly. I also simplified the target, by removing the PropertyGroup and simplifying the condition, like this:
<Target Name="CleanupForBuildMvcViews" Condition="'$(MVCBuildViews)'=='true' " BeforeTargets="BuildViews">
<ItemGroup>
<_PublishTempFolderNamesToCleanup Include="Database;TransformWebConfig;CSAutoParameterize;InsertAdditionalCS;ProfileTransformWebConfig;Package;AspnetCompileMerge" />
</ItemGroup>
<!--Force msbuild to expand all the wildcard characters so to get real file paths-->
<CreateItem Include="#(_PublishTempFolderNamesToCleanup->'$(BaseIntermediateOutputPath)**\%(identity)\**\*')">
<Output TaskParameter="Include" ItemName="_EvaluatedPublishTempFolderNamesToCleanup" />
</CreateItem>
<Delete Files="#(_EvaluatedPublishTempFolderNamesToCleanup)" />
</Target>
In my case i saw that when i have MvcBuildViews and PrecompileDuringPublish as both true - was what was causing this issue.
So i removed the PrecompileDuringPublish and that solution worked for me and i have not faced this problem since.

Out-of-place builds with C#

I just finished setting up an out-of-place build system for our existing C++ code using inherited property sheets, a feature that seems to be specific to the Visual C++ product. Building out-of-place requires that many of the project settings be changed, and the inherited property sheets allowed me to change all the necessary settings just by attaching a property sheet to the project. I am migrating our team from C++/MFC for UI to C# and WPF, but I need to provide the same out-of-place build functionality, hopefully with the same convenience. I cannot seem to find a way to do this with C# projects - I first looked to see if I could reference an MsBuild targets file, but could not find a way to do this. I know I could just use MsBuild for the whole thing, but that seems more complicated than necessary. Is there a way I can define a macro for a directory and use it in the output path, for example?
I'm not quite sure what an "out-of-place" build system is, but if you just need the ability to copy the compiled files (or other resources) to other directories you can do so by tying into the MSBuild build targets.
In our projects we move the compiled dlls into lib folders and put the files into the proper locations after a build is complete. To do this we've created a custom build .target file that creates the Target's, Property's, and ItemGroup's that we then use to populate our external output folder.
Our custom targets file looks a bit like this:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectName>TheProject</ProjectName>
<ProjectDepthPath>..\..\</ProjectDepthPath>
<ProjectsLibFolder>..\..\lib\</ProjectsLibFolder>
<LibFolder>$(ProjectsLibFolder)$(ProjectName)\$(Configuration)\</LibFolder>
</PropertyGroup>
<Target Name="DeleteLibFiles">
<Delete Files="#(LibFiles-> '$(ProjectDepthPath)$(LibFolder)%(filename)%(extension)')" TreatErrorsAsWarnings="true" />
</Target>
<Target Name="CopyLibFiles">
<Copy SourceFiles="#(LibFiles)" DestinationFolder="$(ProjectDepthPath)$(LibFolder)" SkipUnchangedFiles="True" />
</Target>
<ItemGroup>
<LibFiles Include=" ">
<Visible>false</Visible>
</LibFiles>
</ItemGroup>
</Project>
The .csproj file in Visual Studio then integrates with this custom target file:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" ... >
...
<Import Project="..\..\..\..\build\OurBuildTargets.targets" />
<ItemGroup>
<LibFiles Include="$(OutputPath)$(AssemblyName).dll">
<Visible>false</Visible>
</LibFiles>
</ItemGroup>
<Target Name="BeforeClean" DependsOnTargets="DeleteLibFiles" />
<Target Name="AfterBuild" DependsOnTargets="CopyLibFiles" />
</Project>
In a nutshell, this build script first tells MSBuild to load our custom build script, then adds the compiled file to the LibFiles ItemGroup, and lastly ties our custom build targets, DeleteLibFiles and CopyLibFiles, into the build process. We set this up for each project in our solution so only the files that are updated get deleted/copied and each project is responsible for it's own files (dlls, images, etc).
I hope this helps. I apologize if I misunderstood what you mean by out-of-place build system and this is completely useless to you!
Is there a way I can define a macro for a directory and use it in the output path
Have you looked at the pre-build and post-build events of a project?
Actually, pre-build and post-build events seem to be solely a place to add batch-file type commands. This would not help me to set up standard build directories for our projects, unfortunately. And having these events create batch files seems like a very 1980's approach for a modern language like C#, IMO.
After digging some more, and experimenting, I have found that you can add an <Import> directive into your .csproj file. When you do this, the IDE pops up a warning dialog that there is an unsafe entry point in your project - but you can ignore this, and you can make it not appear at all by editing a registry entry, evidently. So this would give me a way to get the variables containing the directory paths I need into the .csproj file.
Now to get the Output Path to refer to it - unfortunately when you add a string like "$(MySpecialPath)/Debug" to the Output Path field, and save the project, the $ and () chars are converted to hex, and your file get's put in a Debug directory under a directory named "$(MySpecialPath)". Arrgghh. If you edit the .csproj file in a text editor, you can set this correctly however, and it seems to work as long as the <Import> tag appears before the <PropertyGroup> containing the Output Path.
So I think the solution for me will be to create a standard OurTeam.targets MsBuild file in a standard location, add an installer for changing the registry so it doesn't flag warnings, and then create custom project templates that <Import> this file, and also set the Output Path to use the properties defined in the OurTeam.targets file. Sadly, this is more work and a less elegant solution than the property sheet inheritance mechanism in C++.

Categories

Resources