The project (netcore3.1) is being packaged with a Windows Application Packaging Project (.wapproj + .appxmanifest) and published for sideloading using:
right click packaging project->Publish->Create App Packages
The error is:
"It is not supported to build or publish a self-contained application without specifying a RuntimeIdentifier, Please either specify a RuntimeIdentifier or set SelfContained to false."
Other answers describe workarounds and methods to get the publishing system to recognise a RuntimeIdentifier, but none explains how to disable self-contained packaging. Surely there is a flag or property that can be set to create a package without the runtime libraries.
Try to play with SelfContained=True or DesktopBridgeSelfContained params of your *.wapproj
<ItemGroup>
<ProjectReference Include="..\WpfApp1\WpfApp.csproj">
<DesktopBridgeSelfContained>False</DesktopBridgeSelfContained>
<DesktopBridgeIdentifiers>win-x64;win-x86</DesktopBridgeIdentifiers>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
<Properties>SelfContained=True;RuntimeIdentifier=win-x64;PublishReadyToRun=true</Properties>
<SkipGetTargetFrameworkProperties>True</SkipGetTargetFrameworkProperties>
</ProjectReference>
</ItemGroup>
Related
When I publish my ABP project I get the following error:
C:\Program Files\dotnet\sdk\6.0.100-rc.1.21458.32\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.ConflictResolution.targets(112,5): error NETSDK1152: Found multiple publish output files with the same relative path:
D:\Github\volo\abp\lepton-theme\src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Lepton\compilerconfig.json,
D:\Github\volo\abp\bookstore\src\Acme.BookStore.Theme\compilerconfig.json,
D:\Github\volo\abp\lepton-theme\src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Lepton\package.json,
D:\Github\volo\abp\bookstore\src\Acme.BookStore.Web\package.json.
D:\Github\volo\abp\bookstore\src\Acme.BookStore.Web\Acme.BookStore.Web.csproj
Issue:
The issue raises after .NET 6 migration.
There's a new feature that blocks multiple files from being copied to the same target directory with the same file name.
See https://learn.microsoft.com/en-us/dotnet/core/compatibility/sdk/6.0/duplicate-files-in-output
Solution #1 (workaround):
You can add the following build property to all your publishable (*.Web) projects' *.csproj files.
This property will bypass this check and works as previously, in .NET5.
<PropertyGroup>
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
</PropertyGroup>
Solution #2:
Exclude the problematic files to be copied to the output folder.
In this example we'll exclude these files: compilerconfig.json and package.json.
Add the following lines to your common.props (located in the root directory of your solution):
<Content Remove="compilerconfig.json;package.json"/>
<None Include="compilerconfig.json;package.json">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
The above answers led me to my solution. My case is a self-building Entity Framework library project that was now copying over its appsettings.json when building the website that used it.
My solution was to let it copy to output folder (when I am doing migration actions in VS**) but prevent it from publishing using the "Never" value because it is only ever published as a library under a website or web service.
<ItemGroup>
<Content Include="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</Content>
</ItemGroup>
** My EF library project builds itself according to the pattern in this data-seeding article.
Thus do I eat my cake and keep it.
If you are getting this in a azure devops pipleline you can add the following task to specify the SDK version for your build
- task: UseDotNet#2
displayName: 'Install .Net SDK version'
inputs:
packageType: sdk
version: x.x.xxx //example (3.1.416)
installationPath: $(Agent.ToolsDirectory)/dotnet
https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/tool/dotnet-core-tool-installer?view=azure-devops
I ran into this with a Blazor WebAssembly project and an associated integration test project which both had appsettings.json files while I was dotnet publish'ing out via a GitHub action. I found two additional ways that worked for me (along with the accepted answer):
Add <IsPublishable>false</IsPublishable > to the test project
In the dotnet publish commands, specify the .csproj directly via arguments
I ran into this issue with a web application that had a Razor Class Library. The culprit file was LIBMAN.JSON.
Right click on the file and change the properties of the file to:
Build Action: NONE
Copy to Output Directory: DO NOT COPY
Other files that are used for tooling only could possibly be changes the same way.
This is caused by a breaking change in the .NET 6 SDK, and is independent of the .NET version your projects target. For example if you install Visual Studio 2022 it will install the .NET 6 SDK and use that for builds and deploys.
You can force VS to use an older SDK toolchain by generating a global.json file by running dotnet new globaljson in your solution root, then replacing the "version" property value with the desired SDK version (use dotnet --list-sdks to list installed versions).
I guess this means if you have a project dependency A->B where A and B are both executable and have their own appsettings.json, it would be preferable to split project B into B1 as a shell project with the appsettings.json and B2 as a library with all of B's functionality. Then dependencies A->B2 and B1->B2 would avoid the "multiple publish output files" issue.
I have also used compilerconfig.json for compiling scss to css.
And the easiest fix through UI is to:
Open Solution Explorer->compilerconfig.json->right click->properties
and there set:
Build Action: None
Copy to Output Directory: Do not copy
Do this for all compiler.config files (in my case on client project as well as on the server)
The reason behind this is that this compiler config is only used locally in building process but it is not required later on while app is running.
If your projects (All part of the same solution) uses a different version of the same nuget pacage, you will see this error. Now you can either find a workaround as others mentioned in the answers if for some reason you have to keep both versions (which is not a good practice).
Or do the right thing and make sure all project using same version of the package. to do that just open Visual studio's NuGet package manager for solution as shown in the screenshot
A window opens which will have a consolidate tab at the top, click on the consolidate tab. if you have a version conflict, you will be able to see lisr=t of NuGet packages on the left side. If that is the case it means you have conflicts. Click on any package and you will be able to see the list of your solution's projects on the right side just like the following screenshot
in my example (screenshot), I have 2 versions of Microsoft.Net.Sdk.Functions
one with 3.0.13 and 3.0.11.
All you need to do is to select your preferred version and click install and both projects will be updated to the same version.
Push the changes and devops build again and enjoy
I have two projects, API and Hangfire.
The duplication was in publishing hangfire since it uses both API and Hangfire projects and I solved it by removing appsettings files before the publish step.
COPY . .
RUN find ${API} -iname "appsettings*.json" -exec rm {} \;
RUN dotnet publish ${HANGFIRE}/*.csproj --configuration Release --output out --no-restore
I was able to resolve it by setting the Microsoft.NET.ConflictResolution.targets file under the <NETSdkError Condition="'$(_ResolvedFileToPublishContainsDuplicates)' == 'false'" <= this was originally true.
This file is located in "\Program Files\dotnet\sdk\6.0.100\Sdks\Microsoft.NET.Sdk\targets"
I'm trying to publish my C# project to an executable in order to distribute it. However, I've referenced 'Interop.IWshRuntimeLibrary' and since including it, my project publishes but then crashes on execution with:
An assembly specified in the application dependencies manifest was not found:
package: 'Interop.IWshRuntimeLibrary', version: '1.0.0.0'
path: 'Interop.IWshRuntimeLibrary.dll'
So far I have tried:
Setting the Copy Local and Embed Interlop Types properties for Interop.IWshRuntimeLibrary to every combination of true/false.
Setting the below tag to true/false in the .csproj file.
<PublishWithAspNetCoreTargetManifest>
Installing the System.Runtime.InteropServices NuGet package.
My .csproj file currently looks like this:
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>Project</RootNamespace>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<ItemGroup>
<COMReference Include="IWshRuntimeLibrary.dll">
<Guid>f935dc20-1cf0-11d0-adb9-00c04fd58a0b</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<WrapperTool>tlbimp</WrapperTool>
<Lcid>0</Lcid>
<Isolated>false</Isolated>
</COMReference>
</ItemGroup>
Other references in the project, like to Newtonsoft work fine. I've consulted every thread I can find across the web pertaining to this. The closest I came to another thread describing my problem was Could not load file or assembly Interop.IWshRuntimeLibrary? but I found no useful info there either.
Ideally, I want to just click publish and publish to a folder on my desktop - preferably as the single .exe but the whole folder is fine if it works. I am unaware if I am perhaps missing a step somewhere as I've never used the publish function before. I'm at a loss for what to try next. Thanks.
How are you publishing at the moment?
You should be able to run the publish command with a flag to tell it to publish as a single file :
dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true
More info here : https://dotnetcoretutorials.com/2019/06/20/publishing-a-single-exe-file-in-net-core-3-0/
But as for your particular issue. When publishing as a single file (Which you may already be doing), there is some level of treeshaking involved to try and limit which dependencies it's publishing. In some cases, if you are referencing a library that is loaded using reflection or similar, then ILLinker doesn't know that it's actually being referenced and used.
To get around this, you can add to your csproj file the following :
<ItemGroup>
<TrimmerRootAssembly Include="Interop.IWshRuntimeLibrary" />
</ItemGroup>
Then publish your project like so :
dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true /p:PublishTrimmed=true
More info on how ILLinker works here : https://dotnetcoretutorials.com/2019/06/27/the-publishtrimmed-flag-with-il-linker/
I'm trying to put together a web-scraping app, using Selenium and .NET Core, but I'm having trouble getting my WebDriver exes to be found.
I have one .csproj that will run the API for the project, which calls out to (amongst others) another .csproj that will handle the webscraping.
All are in a single .sln, and all are running .NET Core 2.1
In the scraping proj, I've nuget-installed Selenium.WebDriver and Selenium.WebDriver.ChromeDriver.
I've created an endpoint in the API, which calls out to the scraping project, and runs a method that attempts to invoke new ChromeDriver(). It doesn't work :( Specifically, I get:
The chromedriver.exe file does not exist in the current directory or in a directory on the PATH environment variable. The driver can be downloaded at ... <url>
Seems fairly clear (although it dissappointingly doesn't tell you what "current directory" means. I'll be submitting a PR for that imminently)
By observing changes during a rebuild, and other research online, I see that:
All the dlls and exes from the nuget packages are stored in the Global Nuget cache, rather than a nuget packages folder in the solution directory.
This appears to be expected behaviour: "Bug" raised in dotnet Std; MSDN migration docs.
The chromedriver.exe appears to get copied to <solutionFolder>\<ScrapingProjectFolder>\bin\Debug\chromeDriver.exe.
I assume that this is what the ChromeDriver Nuget package does; certainly I haven't configured it myself.
This superficially feels like a reasonable thing for that ChromeDriver package to be doing as an attempt at "install this to make new ChromeDriver() JustWork."
Digging into the WebDriver codebase, reveals that the "currentDirectory" that it's looking at is "the location of WebDriver.dll".
In my case, that's "<globalNugetPackagesCache>\selenium.webdriver\3.141.0\lib\netstandard2.0"
It doesn't seem like I should be trying to get the chromedriver.exe to end up in this folder - copying it into a different package's global cache seems wrong? (Do people agree?)
This article seems to have reached broadly the same conclusion and says that the solution is to invoke the driver as:
new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))
Unfortunately, that path takes me to <solutionFolder>\<APIProjectFolder>\bin\Debug\<ScrapingProjectFolder>.dll, because the dll gets copied over the the API project's folder.
A couple of solutions occur to me, none of which really appeal:
I could install Selenium.WebDriver.ChromeDriver into the API project.
Eww... the API project doesn't know about WebDriver or Selenium, and now the Scraping project doesn't have the driver exe.
I could manually explictly copy the exe into the right place.
Doesn't really feel right, and feels fragile. I suspect this will make deployment painful.
I could manually point the ChromeDriver constructor to a hard-coded path, that I just happen to know contains the current exe.
Seems similar to the above; though not quite as bad.
??? Is there some way to make all the DLLs etc. of a project get compiled into a single common folder? ???
Is there a good, non-hacky way to solve this problem. Which will result in a git repo that JustWorks, and is going to be relatively painless to deploy to a server in the future?
Are any of the things I've described above wrong, or mis-configured?
From what I understand you have an API project that depends on a Scraping project.
Scraping.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>7.2</LangVersion>
<PublishChromeDriver>true</PublishChromeDriver>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Selenium.WebDriver" Version="3.141.0" />
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="2.46.0" />
</ItemGroup>
</Project>
API.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Scraping\Scraping.csproj" />
</ItemGroup>
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>7.2</LangVersion>
</PropertyGroup>
</Project>
The trick is adding <PublishChromeDriver>true</PublishChromeDriver> to the transitive project to make it publish the chromedriver when running dotnet publish API.csproj The ChromeDriver package has custom build targets in the NuGet package so it is custom.
You can now use
new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
and dotnet run API.csproj
Please correct me if I'm wrong. You have some kind of Class Library that has reference to Selenium and you would like to use ChromeDriver.exe but you are getting an error that it cannot be found under the following location. This is fairly simple.
Currently you are referencing Class Library lets say Foo to API. Your Assembly Location will point to API bin location, whereas chromedriver.exe is located under Class library bin.
If this is the case the only thing you would have to do is copy following chromedriver.exe to final bin directory which is API.
Add following Post Build Event to your API project to copy chromedriver:
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="copy $(SolutionDir)\ClassLibrary\bin\Debug\netstandard2.0\chromedriver.exe $(TargetDir)" />
</Target>
This will copy your chromedriver.exe to API bin. Later while initializing ChromeDriver use:
var options = new ChromeOptions();
var service = ChromeDriverService.CreateDefaultService(AppDomain.CurrentDomain.BaseDirectory);
WebDriver = new ChromeDriver(service, options);
While AppDomain.CurrentDomain.BaseDirectory will point to your API bin directory.
I have a MonoAndroid10 project and it has a lot of dependencies(NuGet packages too). I would like to be able to copy all of the DLL dependencies to the output folder.
Normally in a .Net Standard 2.0 project the following
<PropertyGroup>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
would make that possible. But in the MonoAndroid project, nothing happens.
If what I posted above doesn't work for a MonoAndroid project, how could I copy everything that I need in some folder, preferably in a post-build action?
I'm trying to do this because after copying all of the required DLLs in one folder I can merge them together with ILRepack.
I've come across this today, solved by adding
<CopyNuGetImplementations>true</CopyNuGetImplementations>
to android project .csproj file (under the desired PropertyGroup section).
Note: there is no need to set CopyLocalLockFileAssemblies to ture neither in android project nor in any of the dependencies.
I'm having a heck of a time getting my tests to run against my SQLite Data Provider.
I've looked at the suggested links here on stackoverflow, but none of them seem to get me going down the right path.
I've downloaded the Windows Precompiled Binaries for sqlite3.dll
I've copied the sqlite3.dll into both my Sqlite\bin directory as well as my Tests\bin directory
Unfortunately when I run my tests, I get the following error
Is there a clear cut way to get this working both in my Windows dev environment (primary goal right now) as well as running in Android and IOS (required in the near future)?
Also, if it matters, here are my Sqlite project references.
So the answer for me was quite simple. I wired up a Pre-Build event that checks the architecture of the machine, and copies the appropriate dll into the output bin directory.
Now anyone on our team can simply run REBUILD, and the proper dll will be available to run against SQLite.
if '$(PROCESSOR_ARCHITECTURE)'=='AMD64' (xcopy /y "$(ProjectDir)x64\sqlite3.dll" ".\")
if '$(PROCESSOR_ARCHITECTURE)'=='x86' (xcopy /y "$(ProjectDir)x86\sqlite3.dll" ".\")
if '$(PROCESSOR_ARCHITEW6432)'=='AMD64' (xcopy /y "$(ProjectDir)x64\sqlite3.dll" ".\")
When I add the following libraries the error went away
Microsoft Visual C++ Runtime Package (V11.0)
SQLite for Windows Runtime (V3.8.7.1)
Can't put this in comments, so here's what I got:
Also, have a look at Similar problem.
Last, but not least, did you try to add a reference to the SQLite.Inetrop.dll (in the references)?
References -> add -> just browse to where your SQLite is, select view all, and add a reference to the Interop.dll as well)
I am using VS2017 and solved the issue by adding the following task to copy the assembly.
<Target Name="Ensure SQLite assemblies copied" AfterTargets="Build" Condition=" '$(Platform)' == 'x64' ">
<Copy SourceFiles="$(OutDir)x64\SQLite.Interop.dll" DestinationFolder="$(OutDir)" />
</Target>