Is NuGet suitable for pulling down assemblies which are not required for compilation, but are at runtime? I have a Visual Studio solution which contains a number of NuGet packages required for compilation - these packages are not kept in source control. At runtime there are a couple of extra dll's which are required. Would it be bad practice to create a VS post-build step which calls NuGet.exe to download these packages and then copies the binaries to the required location? It doesn't look like the intended use of NuGet, but I don't see any obvious flaws with this approach.
I not sure if this would be a good way to do it, but it might solve your problem:
Create a NuGet-package with the DLL's in question as content. You should have the following in your nuspec-file:
<files>
<file src="path\to\dll\one.dll" target="content\dlls\one.dll" />
<file src="path\to\dll\two.dll" target="content\dlls\two.dll" />
</files>
When installing this NuGet package in your project, you'll get a folder dlls added to the project root. You can then go to the property tab of all the included files and set Always for Copy to Output Directory.
Related
I created a small executable that is used to run and debug specific libraries from other solutions. The executable is given the path to a library as a command line argument which the executable loads at runtime.
I want to put my executable in a Nuget package, and have consuming libraries just add the Nuget package to be able to run and debug, using a launchSettings.json.
Because the executable is in the tools/ directory of the Nuget package, its path is put into the PATH environment variable by the Package Manger Console. Therefore the launchSettings can simply just call the executable.
I create my Nuget package with nuget.exe pack my.nuspec -Version 1.0.0, with my.nuspec containing:
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>DebugHost</id>
<version>$version$</version>
<title>DebugHost</title>
<authors>Some company</authors>
<owners>Some company</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>DebugHost</description>
<summary>DebugHost</summary>
<copyright>2020, Some company</copyright>
</metadata>
<files>
<file src="bin\Debug\netcoreapp3.1\*" target="tools" />
</files>
</package>
From consuming library projects I put in Properties\launchSettings.json containting:
{
"profiles": {
"DebugHost": {
"commandName": "Executable",
"executablePath": "my.exe",
"commandLineArgs": "$(ProjectDir)$(OutDir)$(TargetName)$(TargetExt)"
}
}
}
I have three different questions that are somewhat related, as any might answer another:
This setup only works as long as I keep the Package Manager Console opened. If I try to Debug / Launch the library without first opening the Package Manager Console, the launch fails because it cannot find the executable. Unable to start program 'my.exe'. The system cannot fint the file specified.
Can I for example add a targets file in the Nuget package that will hint its path during build/launch, which in turn I can use as a variable in the launchSettings.json? (If so, how?)
This setup requires that a Properties\launchSettings.json is used in the consuming project. Can I make my Nuget package create that file?
Can the file be an asset in the Nuget that gets copied to the correct place?
Or can I even have an install.ps1 script that creates the json, with the correct absolute path to the executable in it? This would make question 1 answered as well.
The above situation only works with nuget.exe pack and a .nuspec.
Can I instead move stuff into my (new style) .csproj and get this to work with just dotnet.exe pack and the .csproj? (or msbuild.exe -t:pack and the .csproj?) So ultimately I can also just create the package by simply right clicking the project in Visual Studio and selecting Pack from the context menu?
When using dotnet core 2.0-preview1 in vs2017. I got an error about project reference.
I hava a solution with two projects.
This is Common.Bll Project
The Common.Web referenced the project Common.Bll. But the ide told me cannot find Common.Bll with error Using directive is not required by the code and can be safely removed. Cannot resolve symbol 'Bll'
This is Common.Web project
Common.Bll.csproj
Common.Web.csproj
But it can be build succeed and run normally.
Have any way to solve this?
update:
It's working follow the #Svek to change the Common.Bll from netstandard2.0 to netcoreapp2.0.
Your csproj file
Visual Studio doesn't like to behave quite right when the TargetFramework does not totally match up.
Common.Bll.csproj
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
Common.Web.csproj
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
Make both of them the same, and you should be good to go.
the error:
cannot resolve symbol '< >'
The simple solution is to reinstall all your packages, and make sure all your dependencies are properly showing up in Visual Studio under each project. (Dependencies --> Projects | or | Dependencies --> Assemblies).
In Package Manager
Update-Package -reinstall
More details can be found here to reinstall your packages.
Reference to an unused library
- Update: You can ignore this. Your updated question makes this section no longer apply. -
Until you are actually using a library, Visual Studio will inform you that the referenced library is not required.
using directive is not required by the code and can be safely removed.
You can do one of two things:
1.) Use the library that you are referencing
In your case:
var obj = new Common.Bll.<Your Class>;
2.) Remove library that you are referencing
This can be done quickly by right-clicking and selecting Remove Unused Usings.
The alternative is to use the keyboard shortcut Ctrl+R, Ctrl+G.
I have a project which has a NuGet package called MSBuildTasks installed. It installs two files: MSBuild.Community.Tasks.targets and MSBuild.Community.Tasks.dll to the .build directory within the solution directory. This package reference has been added to the packages.config file in that project directory so that when I build the project (and with the NuGet package restore settings enabled) it will restore the package which is great because then I can distribute the source to other developers and build it on our build server without any missing files...
However, the problem is that when NuGet restores the package, it doesn't restore these two files to the expected location it was originally in when I first installed it with the Install-Package MSBuildTasks command, which was in to the $(SolutionDir)\.build directory. Instead, it has installed it to the $(SolutionDir)\packages\MSBuildTasks.1.4.0.78\tools directory, so now if I wish to include the MSBuild.Community.Tasks.targets file, I must reference this path absolutely in my .csproj or other .targets file. This presents a problem since the version number will undoubtedly change, requiring manual work to correct.
Is there some way that I can restore the MSBuildTasks .targets and .dll files to the original location of $(SolutionDir)\.build where it first installs to? The current behaviour of restoring in to the packages directory, while it makes sense for other packages, seems like a bug for this particular package since I will not be able to know the version number of the directory to include in my other .targets or .csproj files.
NuGet restore will only download files to the packages directory. It will not make any other modifications.
Looking at the MSBuildTasks NuGet package the files added to the $(SolutionDir)\.build are added by a PowerShell script. This PowerShell script will not be run when restoring the NuGet package.
You should add the $(SolutionDir)\.build to your source control repository.
With the newer versions 1.5+ the Nuget package doesn't install itself in the solution directory; this worked for me though:
<PropertyGroup>
<MSBuildCommunityTasksPath>$(USERPROFILE)\.nuget\packages\msbuildtasks\1.5.0.235\tools</MSBuildCommunityTasksPath>
</PropertyGroup>
It does involved adding the version, but if someone knows a way to remove having to update the version on the path when you update the package that would be awesome.
I have a library with a pretty verbose configuration section. I've created an XSD and would like to distribute that with my package so that when a user installs the package, Visual Studio knows about the XSD without the user needing to do anything extra. How do I do this?
You can include any files you want in a nuget package by placing them in the content directory. These will then be installed into the root of your target project when the package is installed. If you're using a nuspec file to build your package you would add the following element under the element.
<files>
<file src="Configuration\MyXsd.xsd" target="content\TargetFolderName" />
</files>
This will create the following file in the target project
\TargetFolderName\MyXsd.xsd
Once the xsd is in the target project visual studio should pick it up automatically for validating your config section.
This has recently become more complicated with SDK style projects and the different ways of referencing nuget packages.
Note the end of this section.
Basically, if a nuget project is referenced by package.config file, the files from the content folder of the nuget package will be copied to the referencing project. If the nuget package is referenced by PackageReference in the project file, the files from the contentFiles folder within the package will be used. It is recommended to include both.
Now if you are using a .nuspec file to configure your nuget package, you can use SynXsiS answer to include the file to both directories:
<files>
<file src="Configuration\MyXsd.xsd" target="content\TargetFolderName" />
<file src="Configuration\MyXsd.xsd" target="contentFiles\any\any\TargetFolderName" />
</files>
However, if you want to configure it in the .csproj file of SDK projects, you have to add the file you want to include in the nuget package into the project file with the following properties:
<ItemGroup>
<None Include="MyXsd.xsd">
<Pack>true</Pack>
<PackagePath>contentFiles\any\any\TargetFolderName;content\TargetFolderName</PackagePath>
</None>
</ItemGroup>
The any\any\ part of the path for the contentFiles specifies for which language (cs, vb, ...) and target framework the file is meant.
Note, that the item not necessarily has to be of type "None" it could also be "Content" and others as described here.
You can find all information for this structure here, general information of the folder structure can be found here and help for the SDK style projects here.
My company recently forced us to use Wix Toolset (v.4.0.12), because we upgraded to Visual Studio 2012 which unfortunately no longer contains installer projects.
My problems are the following. I have a big solution with many projects which all in all result in an exe file, and several dlls.
I then create a Wix setup project in the solution, and add a reference to the project that produces the exe file. In the properties of that project reference I set Harvest: true and Project Output Groups: Binaries.
I would expect a build of my WiX project to harvest the dependencies from the referenced project, so that I do not need to manually add the references, as that would give me more maintenance.
Moreover, if I run heat.exe on the referenced project file, I only get the exe output of the file, and not the dlls which the project depends on.
I assume that the above is quite standard, and wix tools should be able to gather that information for me. And I really wonder why after an extensive search on the net, cannot find anyone with similar issues.
If anyone knows why the above, please try to send me a basic tutorial of how to do stuff with WiX. It seems impossible for me find an appropriate one.
WiX v3.6 and later support VS2012. WiX v4.0 is barely even started and not recommended for use at this time. Lots of breaking changes coming in v4.0 so stick with the v3.x line for now.
The auto-harvesting feature in Votive is not fully functional. That is why it is disabled by default. Found many project types were breaking it. As you found, the harvesting does not walk through multiple project references. All things that need more work before they work properly.
In the meantime, you can list the File elements in Component elements.
Not sure how you are using v4.0.12 when it's not even out yet! :) Wix v3.8 is the latest version: http://wixtoolset.org/releases.
There are plenty of guides in the official documentation and you can also find quite a lot of information in the tutorial.
However for your specific case you will need to manually include the outputs of each project and their dependancies into the installer as automatic harvesting isn't supported yet:
<Component>
<File Id="ProjectA.Output"
Name="$(var.ProjectA.TargetFileName)"
Source="$(var.ProjectA.TargetPath)"
KeyPath="yes" />
</Component>
<Component>
<File Id="ProjectA.NlogDependancy"
Name="NLog.dll"
Source="$(var.ProjectA.TargetDir)\Nlog.dll"
KeyPath="yes" />
</Component>
<Component>
<File Id="ProjectB.Output"
Name="$(var.ProjectB.TargetFileName)"
Source="$(var.ProjectB.TargetPath)"
KeyPath="yes" />
</Component>
<Component>
<File Id="ProjectB.AutofacDependancy"
Name="Autofac.dll"
Source="$(var.ProjectB.TargetDir)\Autofac.dll"
KeyPath="yes" />
</Component>
This isn't really that hard to do and unless you have several hundred binaries won't take you too long.
I had a similar issue when i tried to create a .msi installation of my solution.
To overcome this problem and to make it long lasting over time even when I insert new .dll and other dependencies to my project and to make it automatic I did the following.
In my Product.wxs I have this "Directory"
<!--Here We Install Our Main App-->
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="MyAppDir"/>
</Directory>
...
</Directory>
and in my Wix project-> properties -> Build events -> Pre build event command line, I added this command:
"%wix%\bin\heat" dir "$(SolutionDir)MainProject\bin\Debug" -dr INSTALLFOLDER -scom -frag -srd -sreg -gg -cg Components -var var.MainProject.TargetDir -o $(SolutionDir)MainProject\Includedheat.wxs
Once I build my wix project it will create a Includedheat.wxs file in my MainProject directory that lists all the files from my MainProject\bin\Debug directory.
Next step - add the Includedheat.wxs into the wix project , than in my feature section I added:
<!--Add Component-->
<Feature Id="MainApplication" Title="Main Application" Level="1">
...
<ComponentGroupRef Id="Components" />
</Feature>
now once I rebuild and install the .msi all of the content that resided in my MainProject\bin\Debug directory will also be included in the MyAppDir dir on the target location.
For some more information:
I followed this guides :
Create a working Wix project.
Easy way heat.exe.
Also recomending to read for detrming what flags to use in your command.