Neither PackageIcon nor PackageIconUrl work in dotnet build - c#

I'm using visual studio 2017. I have a project for which I would like to generate a nuget with an Icon.
If I use
...
<PackageIconUrl>http://blabla/icon.png</PackageIconUrl>
I get the following error :
error NU5048: The 'PackageIconUrl'/'iconUrl' element is deprecated. Consider using the
'PackageIcon'/'icon' element instead. Learn more at https://aka.ms/deprecateIconUrl
[D:\myproject.csproj]
Fine, So I change my project to be something like :
...
<PackageIcon>core.png</PackageIcon>
...
<Content Include="..\Shared\core.png" Link="core.png" Pack="true" PackagePath="\" >
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
When I build my project now (dotnet build Myproject.csproj) I don't get any compilation errors.
However, when I want to view the generate nupkg in "Nuget Package explorer". I get the error :
The element 'metadata' in namespace 'http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd'
has invalid child elment 'icon' in namespace 'http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd'.
List of possible elements expected : 'contentFiles, desription, licenseUrl, projectUrl, language,
releaseNotes, frameworkAssemblies, summary, iconUrl, packageTypes, dependencies, copyright,
developmentDependency, repositoru, tags, references, title, serviceable' in namespace
'http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd'.
(so it seems the generated embedded nuspec has a wrong xml namespace - I have no idea how I can make it generate the new namespace) This is a Catch-22.
So it seems the only option is to leave the icon out.
(I also have visual studio 2019 and recently installed the .net core 3.0.100 SDK)

The move from <iconUrl>/<PackageIconUrl> to <icon>/<PackageIcon> is fairly new. While nuget.org supports parsing packages which use <icon> rather than <iconUrl>, some other package servers don't yet.
It sounds like you're simply browsing a directory with the NuGet Package Explorer, so the cause is probably that this doesn't yet understand <icon>.
While <iconUrl> is deprecated, I've found that it still works on nuget.org, so you should be able to continue using it until the rest of the tooling catches up. Alternatively if you don't actually care about browsing packages stored in a local directory and just care about nuget.org, then you can start using <icon>.
You might even be able to use both - I haven't checked.

At least I think you can feel free to use the PackageIconUrl for now, as canton7 mentioned above, the move is fairly new. You can consider that as a kind reminder.
For the latest VS2019 release version 16.3.3, its project template still supports PackageIconUrl by default. For .net core and .net standard class library project, if we Right-click project=>Package tab we can see:
And it is equivalent to <PackageIconUrl>http://xxx/icon.png</PackageIconUrl> in xx.csproj, so I think you can just ignore that warning or use <NoWarn>NU5048</NoWarn>.

You need to make sure that the icon is part of the package. You can verify that it's in there by unzipping your nupkg file.
From a Microsoft site:
<PropertyGroup>
...
<PackageIcon>icon.png</PackageIcon>
...
</PropertyGroup>
<ItemGroup>
...
<None Include="images\icon.png" Pack="true" PackagePath="\"/>
...
</ItemGroup>
Also (from here):
PackageIconUrl is deprecated in favor of PackageIcon. However, for the best downlevel experience, you should specify PackageIconUrl in addition to PackageIcon.
There is also an example project with icon: https://github.com/NuGet/Samples/tree/main/PackageIconExample

Related

How to include functionality from one project into another in the same solution?

In my company, we are creating C# client/server applications as follows:
We create three project inside one single Visual Studio solution:
Product.General
Product.Client
Product.Server
The "General" project contains functionality, to be used by both client and server parts.
In order to make this work, we compile the "Product.General" and add the binary as a reference to the "Product.Client" and "Product.Server" projects.
In our source code, this looks as follows:
In the "General" project:
namespace Product.Customer.Configuration
{
public class SettingManager
{
...
}
}
In the "Server" project:
using Product.Customer.Configuration;
...
var settingManager = ...<SettingManager>();
I don't like, because amongst other first you need to get the "General" part compiled before you can even start working on your "Client" or "Server" project.
How can I get such a system to work, without needing to add compiled binaries into projects' references?
Thanks in advance
You should add the reference with Add Project Reference and then select the General Project like this. and whenever you are making changes just do Ctrl+Shift+B to build the solution.
If you're working with Visual Studio, right click on the References menu in the Product.Client or Product.Server project, click Add Reference in the popup select the Projects tab and then add a checkmark where needed (in your case Product.General) (see vivek nuna's answer). I assume it's basically the same in something liked Rider.
If you're not using Visual Studio, but are using the new .NET (not .NET Framework) you can use the dotnet cli tool like so
dotnet add path/to/Product.Client.csproj reference path/to/Product.General.csproj
If the working directory of the shell your using contains a .csproj file, you can omit the first path/to/*.csproj, so doing something like this should work
cd Product.Client
dotnet add ../Product.General/Product.General.csproj
If you're not using Visual Studio or some other IDE and for some reason can't use the dotnet cli tool, then you can manually edit the .csproj files, like so
<ItemGroup>
<ProjectReference Include="path/to/Product.General.csproj" />
</ItemGroup>

Writing a library in a framework [duplicate]

I'm writing a class library for a simple parser in C#. When I first created it, I used .NET standard 2.0, but now I need to migrate it to .NET 4.6 both to conform to the other projects in my solution and in order to use NUnit.
I tried to follow the instructions in the Microsoft documentation, but when I try to select another framework in the properties, I can only find other .NET standard versions.
How can I migrate it? Will I need to manually edit the .csproj file?
Open up the project file (.csproj) and change the TargetFramework to net462
<PropertyGroup>
<TargetFramework>net462</TargetFramework>
</PropertyGroup>
My personal experience in Visual Studio 2017 is that recreating project and adding existent sources is the simplest, safest and most effective way - because .Net Framework based csproj file has extra xml elements (comparing with Standard based), it seems changing "TargetFramework" is not enough.
Below is portion of diffs appeared by default:
If you are publishing your class library as a Nuget package then there is a better way to set this up. Check out this article:
https://weblog.west-wind.com/posts/2017/Jun/22/MultiTargeting-and-Porting-a-NET-Library-to-NET-Core-20
Basically you can setup your class library for multi targeting, allowing it to be imported into .net core projects as well as different versions of .net frameworks.
There are a few steps that I did and worked for me:
git push your code, so you have a back up :)
Unload the project in VS (right click on the project and unload)
Edit the project in VS (right click and edit)
Replace the TargetFramework OR/AND TargetFrameworkVersion with
<TargetFramework>netcoreapp2.0</TargetFramework>
Change the project line, that's usually the first line (after xml root) to:
<Project Sdk="Microsoft.NET.Sdk">
Remove the import that's usually the second line (after the xml root)
Keep your PropertyGroups that describe the build options, if you want (I want mine as are custom)
Remove the references and the file references, they are not needed.
Close the file and reload (right click reload).
Delete the assemblyinfo file (from properties folder) as it is not needed, the assembly version comes now from the proj
Right click on the project and go to properties to see that you don't have any error in proj file. Ensure that you don't have typos or tags that are not close.
Build. If you have dependencies that you are missing then right click and on the project and add them. - I suppose that you don't want to edit them in the proj. Or you can do a dotnet restore or dotnetbulid to add them, as you would like.
Hope this works for you. They seem a lot of steps but they are not that complicated, and this is one time effort.

C# - Code compiler for .NET & CF.NET

I've a same project that need to be compiled with .NET and Compact .NET Framework.
It is possible to create a C#
compiler that will compile my
project with both framework ?
Some feature aren't present in
CF.NET Framework so I created it by
myself (creating classes having
exactly the same name & options that
in .NET Framework. If I decore this
classes with an attribute like
[CF35] it's possible to parse the
project and :
Use this class when compile the
project using CF.NET
Ignore this class when compile the project using
.NET
?
Thanks for all constructive answers.
[EDIT]
I know the solution that consists to create two projects referencing the same files.
Problem is, you should every time compile both manually.
Moreover, when you add a file to one, you need to open the second and reference it too, that it's just borring to do and according that we are many people to work on the same project, I would like to do this part automatically.
Seems to be possible?
[EDIT 2]
All works fine except ... resources files !
So, to resume, I've three project :
the development project (CF.NET)
the release project (CF.NET 3.5), including all files via ""
the release project (NET 3.5), including all files via ""
As said, all works fine, but now my problem is using Resources files.
What's the method to apply to use it?
When I use the development project, Resource file is correctly retrieved
When I use the two other projects, ResourceManager throws MissingManifestResourceException
Any idea?
You'll need to create different build configurations for each and define a custom flag like USE_CF. Then wrap your custom classes with #if USE_CF and #endif so they get ignored when compiling without that flag
The basic idea would be to decorate your code with #if compiler directives for each framework version?
#if CFNET
// .net CF code
#else
// .net code
#endif
From here one you have two options:
A) 1 project file with custom build configurations
If you would like to have everything in 1 csproj file you'll need to modify it manually. Since this is a msbuild file this is more of a msbuild problem. I figure you would need to do the following things:
Use 2 platform names say "NET" and "CF" (instead of the default Any CPU or x86)
Define CF constant (From now on Edit csproj):
<PropertyGroup Condition="'$(Platform)' == 'CF'">
<DefineConstants>CF</DefineConstants>
</PropertyGroup>
Import correct build targets depending on selected platform:
<Import Condition="'$(Platform)' == 'NET'" Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Condition="'$(Platform)' == 'CF'" Project="$(MSBuildToolsPath)\<CFtargets>.targets" />
I don't know the targets file name of CF since I don't have it installed. It sould be somewhere in C:\Windows\Microsoft.NET\**.targets
B) 2 project files each containing the appropriate build configuration
As I initially pointed out, and also some commenter pointed out, the best solution is to have 2 project files, that you keep in sync. You can have the same source files in both project files.
So an idea would be (instead of copying the file list manually each time) to
think about using T4 templates, to keep the source files in sync (and have 2 solutions, so you wouldn't be prompted to reload the whole solution each time) or to
modify the two csproj files and use a wildcard compile tag like this:
<Compile Include="**/*.cs"/>
There's only one C# compiler, it emits the exact same IL for whatever platform. What's different are the reference assemblies, you have to use the CF versions for the project that targets CF, the desktop versions for the project that targets .NET. Which requires two projects. They can reference the same source code files. Adding CF-only source code files is now of course no longer a problem.
Keeping projects in sync is a feature available in VS2010. Intended for Silverlight, pointless for a CF project of course since it no longer supports it.
a better way is to create your normal project class library (.NET) and add all of your code. Then create your second class library project (.NET CF) but reference the code files from the first project (not copy, but reference). Then you end up with 2 DLL's and you don't have to deal with nasty ugly compiler directives. You get the result you want with no extra work to maintain both projects. Obvisouly you would need to be careful with what you put in the code since .NET CF is limited compared to .NET. I don't know how to add file references (shortcuts) using visual studio but I open the proj file in notepad and use relative paths to the files to include. I've used this method for .NET/.NET CF and also .NET/Silverlight
Also, have a look at Portable Library Tool CTP http://visualstudiogallery.msdn.microsoft.com/b0e0b5e9-e138-410b-ad10-00cb3caf4981/?localeName=ko-kr

Using an external tool for C# builds in Visual Studio

When using Visual Stdio 2008, you can make a C++ project build with an internal tool rather than having the IDE invoke MSVC directly. This improves the consistency of builds across platforms if a cross-platform build system is used.
However, I cannot figure out how to do the same as a C# project. It would be possible to simply register it as a native project with C# sources, however, you lose some of the advantages gained through having a C# project. More importantly, it will mean that allowing a project to build both directly and with an external tool (which is sadly necessary) will require two separate projects, rather than merely creating an alternate build configuration to invoke the external tool.
Does anyone know if it's possible to prevent Visual Studio from invoking csc by itself and instead call an external tool?
EDIT: Apparently there has some misunderstanding. The goal here is not to compile anything outside of Visual Studio. Instead, it's to allow Visual Studio to serve as the IDE but not the build system. There is already a (Scons-based) build system capable of compiling the C# and C++ sources, and Visual Studio has been configured to invoke Scons for compilation of C++ projects. I'm trying to configure it so that when you hit the 'Build' button, it will invoke Scons for the C# projects as well as the C++ ones.
Edit: Your question is still answered using MSBuild(if you are simply looking to compile outside the IDE). The IDE(Visual Studios) is simply a "fancy" way of constructing the build files that are built by MSBuild. Visual Studios isn't building the files, it simply is invoking MSBuild which ships with the .NET Framework 2.0 and up which compiles your code based on the project file that you create. If Scons can read and process an MSBuild file then I'm sure you can invoke it to build your project. But considering the fact that C# is a Microsoft language, I think you will be hard-pressed to find a value-add in not using MSBuild since I'd assume both the language and build tool are very tuned to work together. - End Edit
You can use MSBuild to compile your C# project. If you open your .csproj file in a text editor you will see that it is a MSBuild file. If you want to write some C# outside of the IDE you can construct a build file using the .csproj file as a starting point and invoke MSBuild to compile your apps. The IDE is just a way of abstracting the editing of the MSBuild file away for you.
If you are really industrious you can create a set of custom tasks to do things in your custom build process like move files around and versioning. MSBuild Community Tasks are a great example of using custom code to do task for you during MSBuild.
Given all the other answers, what MSBuild does when either VS or MSBuild perform a build can be found in the Targets files that ship with .Net. These can be be found in the FrameWork directory on your system. In my case:
C:\Windows\Microsoft.NET\Framework64\v3.5
Contains Microsoft.Common.targets among others. This file contains the following snippit:
<!--
============================================================
Build
The main build entry point.
============================================================
-->
<PropertyGroup>
<BuildDependsOn>
BeforeBuild;
CoreBuild;
AfterBuild
</BuildDependsOn>
</PropertyGroup>
<Target
Name="Build"
Condition=" '$(_InvalidConfigurationWarning)' != 'true' "
DependsOnTargets="$(BuildDependsOn)"
Outputs="$(TargetPath)"/>
This means that redifining this Target you can make MSBuild an VS do anything you want. The top of the mentioned file contains an important messagge:
Microsoft.Common.targets
WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
created a backup copy. Incorrect changes to this file will make it
impossible to load or build your projects from the command-line or the IDE.
This file defines the steps in the standard build process for .NET projects. It
contains all the steps that are common among the different .NET languages, such as
Visual Basic, C#, and Visual J#.
My suggestion would be to read all you can about MSBuild and it's build file syntax and try redifining the Build target in your project(s). My impression is that after reading up on MSBuild you'll probably find an easier way to meet your requierements. You can find an example of redifining a Target like this in one of the answers of this so question .
Edit:
How to redefine a target?
Redefining is essentially defining the same target 'after' it has been defined. So for instance in your .*proj file(s) define a Build Task after the <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> line that imports all targets needed to in this case build a C# project. An example could be
<Target
Name="Build"
Condition=" '$(_InvalidConfigurationWarning)' != 'true' "
DependsOnTargets="BeforeBuild"
Outputs="$(TargetPath)">
<Exec Command="nmake" />
</Target>
I found a question in the same direction here, where it is suggested to edit the registry. I am pretty sure there is no other way to change the compiler used by Visual Studio because there is no trace of csc.exe in any solution, config, csproj file or whatsoever, nor in the Visual Studio 9.0 folder / subfolders within the Program Files dir.
Registry locations can be found in:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\74ACAA9F1F0087E4882A06A5E18D7D32
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\9055DA7481CC1024CB23A6109FD8FC9B
but those keys may differ dependng on your installation. Conclusion: changing the compiler used by VS seems next to impossible.
Addition: The following MSDN article deals with the same question for an custom C++ compiler, and Ed Dore's answer seems to confirm my theory that there's no way to choose an custom compiler for use within VS.
Under 'Tools' > 'External Tools' you should be able to define an outside tool to do activities for you. The Command should be the path to the executible for your external tool.
Hope this helps some.
You don't have to maintain different project files to build using an external tool. MSBuild is designed to build using the same project files that Visual Studio uses.
Here's an article that describes it.
Customize Your Builds in Visual Studio Using the Standalone MSBuild Tool
It's for VS2005, but should apply to VS2008 as well.
Looking through the answers, it seems clear to me that integrating scons into Visual Studio in a way that is compatible with the debugger and so on is not going to happen...
An option you might to consider, and I understand you don't want to change build systems, but bear with me, is to use a meta-build system, ie 'cmake'. http://www.cmake.org/
Cmake doeesn't actually build the project. What it does is to create build files for you, that you can use to build the project, and on Windows, the build files it creates for you are: Visual Studio project files. You can simply load those directly into your IDE, and compile, and use normally!
CMake is I feel very easy to use, and provides a high level of transparence and maintainability.
The exact same CMakeLists.txt files on linux will causes linux makefiles to be generated.
On mingw, they can generate mingw makefiles.
There are numerous generators available within cmake. The list is here:
http://www.cmake.org/cmake/help/cmake-2-8-docs.html#section_Generators
http://springrts.com is a huge opensource rts game that used to use scons as its cross-platform build system and now uses cmake.
I understand that you don't really want to have to change build systems, so it is a medium to long term solution.
Cmake is in any case one more option, to add to those of using a custom build tool, or using msbuild, or running the scons build from the commandline by hand.
Edit your project file and update the CscToolPath keys to point to the directory containing your tool and add CscToolExe keys that holds the name of the directory:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|.NET 3.5' ">
.
.
.
<CscToolPath>path\to\custom\tool\directory</CscToolPath>
<CscToolExe>exe name</CscToolExe>
.
.
.
</PropertyGroup>
I have not tested this, and the CscToolExe key may cause problems, in which case I would simply rename the external tool executable to "csc.exe".
You can build your solution from the command line like this:
C:\WINDOWS\Microsoft.NET\Framework\v3.5>msbuild.exe "C:\path\Your Solution.sln"

Using Compass on Windows with Visual Studio C# and ASP.NET

Has anyone done any development of Compass for CSS/SASS in a standard C# ASP.NET environment?
Is there a single distribution I can just download that's ready to go for Windows or do I need install every piece of the equation and build compass myself?
Are there any plugins that make developing with Compass friendlier with VS2008 such as automagical handling of Compass/SASS in builds, syntax highlighting, and/or intellisense support?
If there aren't any VS IDE plugins what are the best options for a standalone text editor for handling coding in Compass?
To complete the last answers, you can install Web Workbench, a plugin for Visual Studio 2010 wich add syntax highlighting, intellisence and some other stuff for the SASS language (SCSS syntax only).
If you prefer using Compass and/or some other tools to compile your CSS, you should disable the built-in compiler. I listed some other SASS compilers here: Using SASS with ASP.NET.
To disable the built-in compiler: select the .scss file in Solution Explorer, go to the Properties window and delete the text from the Custom Tool box.
Since Web Workbench 3 you can now manage more easily what you want to compile with this plugin. See the Mindscape > Web Workbench Settings menu item.
Getting started with Compass,
First yes I have to install Ruby and the compass source and compile up my version of compass I followed the instructions on Compass's Wiki Getting Started.
After getting Compass and all it's dependencies installed and built I created my first project.
compass -f blueprint project-name
Which creates a default project with compass for the blueprint css framework, currently there's a bug in compass with the creation of the grid.png file in the images directory for compass so you need to copy the original grid.png from the source folder
C:\Ruby\lib\ruby\gems\1.8\gems\chriseppstein-compass-0.8.10
\frameworks\blueprint\templates\project
Or similarly located file depending on where you installed everything. One of the most important changes IMO for working with compass on asp.net is to change the SASS CACHE directive of compass. The SASS CACHE creates a bunch of temporary folders in your project directory which probably would have poor outcomes if they ended under source control. So open up config.rb and add this line
sass_options = {:cache_location =>
"#{Compass.configuration.project_path}\\tmp\\sass-cache"}
Make sure to note the escaped backslashs.
After this I modified the names of the folders that compass uses for how I wanted them named inside the config.rb and started getting to it with SASS and Compass. I recommend watching the hour long introduction to compass video it's very helpful and I learned alot from it: Watch the screen cast.
One of the things which this showed me was how to set compass to watch for file system changes and automagic compile the sass to css. By using
compass -w
This is working real well for me, just make sure you keep your css files checked out or turn them off read only if they're under source control if your project doesn't support concurrent checkouts.
For editing I'm using SciTE that's included with Ruby by default for the config.rb files or just the editor window in VS2008. For Sass I came across a big list on the HAML website. jEdit with highlighting syntax file for SASS was what I ended up using after trying a few. I'd still like to find a VS plugin for syntax highlighting so I don't need to use another editor but jEdit is definitely getting the job done.
My answer is a bit antiquated. Before following my original answer, I would recommend exploring the Nuget package SassAndCoffee. The full details can be found here.
How does it work?
SassAndCoffee embeds the original
compilers in the DLL as (Sass 3.2.0
and CoffeeScript 1.1.0 as of this
writing) and uses IronRuby and
Jurassic respectively to execute the
compilers against your source.
Why is
this better than [SOMEOTHERPROJECT]?
No external processes are executed
You don’t have to install Ruby or node.js
It’s in NuGet so you don’t have to fiddle with web.config
Files are cached and are rebuilt as-needed.
I wanted to add another alternative here. If you just want to ensure that compass builds the sass files and includes the css files when you build your ASP.net project you can add the following to your project(csproj) file under the project section:
<Target Name="AfterBuild" Condition="'$(Configuration)' == 'Release' ">
<Exec Command="compass compile --output-style compressed --force" />
<ItemGroup>
<Content Include="Styles\*.css" />
</ItemGroup>
</Target>
<Target Name="AfterCompile" Condition=" '$(Configuration)' == 'Debug' ">
<Exec Command="compass compile" />
<ItemGroup>
<Content Include="Styles\*.css" />
</ItemGroup>
</Target>
The first Target is for Release and will also compress the css, the other one is for Debug.
If you want to customize paths add a config.rb to the project root folder:
css_dir = "Content"
sass_dir = "Content/Sass"
This all of course requires compass and ruby to be installed and to be in the path of your machine.

Categories

Resources