The mystery of dotnet watch and 'Microsoft.NETCore.App', version '1.1.0-preview1-001100-00' was not found
WARNING: This post is full of internal technical stuff. I think it's interesting and useful. You may not.
I had an interesting Error/Warning happen when showing some folks .NET Core recently and I thought I'd deconstruct it here for you, Dear Reader, because it's somewhat multi-layered and it'll likely help you. It's not just about Core, but also NuGet, Versioning, Package Management in general, version pinning, "Tools" in .NET Core, as well as how .NET Runtimes work and version. That's a lot! All that from this little warning. Let's see what's up.
First, let's say you have .NET Core installed. You likely got it from http://dot.net and you have either 1.0.0 or the 1.0.1 update.
Then say you have a website, or any app at all. I made one with "dotnet new -t web" in an empty folder.
I added "dotnet watch" as a tool in the project.json like this. NOTE the "1.0.0-*" there.
"tools": {
"Microsoft.DotNet.Watcher.Tools": "1.0.0-*"
}
dotnet watch is nice because it watches the source code underneath it while running your app. If you change your code files, dotnet-watch will notice, and exit out, then launch "dotnet run" (or whatever, even test, etc) and your app will pick up the changes. It's a nice developer convenience.
I tested this out on last weekend and it worked great. I went to show some folks on Monday that same week and got this error when I typed "dotnet watch."
C:\Users\scott\Desktop\foofoo>dotnet watch
The specified framework 'Microsoft.NETCore.App', version '1.1.0-preview1-001100-00' was not found.
- Check application dependencies and target a framework version installed at:
C:\Program Files\dotnet\shared\Microsoft.NETCore.App
- The following versions are installed:
1.0.0
1.0.1
- Alternatively, install the framework version '1.1.0-preview1-001100-00'.
Let's really look at this. It says "the specified framework...1.1.0" was not found. That's weird, I'm not using that one. I check my project.json and I see:
"Microsoft.NETCore.App": {
"version": "1.0.1",
"type": "platform"
},
So who wants 1.1.0? I typed "dotnet watch." Can I "dotnet run?"
C:\Users\scott\Desktop\foofoo>dotnet run
Project foofoo (.NETCoreApp,Version=v1.0) will be compiled because expected outputs are missing
Compiling foofoo for .NETCoreApp,Version=v1.0
Hosting environment: Production
Content root path: C:\Users\scott\Desktop\foofoo
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
Hey, my app runs fine. But if I "dotnet watch" I get an error.
Remember that dotnet watch and other "tools" like it are not dependencies per se, but helpful sidecar apps. Tools can watch, squish css and js, precompile views, and do general administrivia that isn't appropriate at runtime.
It seems it's dotnet watch that wants something I don't have.
Now, I could go install the framework 1.1.0 that it's asking for, and the error would disappear, but would I know why? That would mean dotnet watch would use .NET Core 1.1.0 but my app (dotnet run) would use 1.0.1. That's likely fine, but is it intentional? Is it deterministic and what I wanted?
I'll open my generated project.lock.json. That's the calculated tree of what we ended up with after dotnet restore. It's a big calculated file but I can easily search it. I see two things. The internal details aren't interesting but version strings are.
First, I search for "dotnet.watcher" and I see this:
"projectFileToolGroups": {
".NETCoreApp,Version=v1.0": [
"Microsoft.AspNetCore.Razor.Tools >= 1.0.0-preview2-final",
"Microsoft.AspNetCore.Server.IISIntegration.Tools >= 1.0.0-preview2-final",
"Microsoft.DotNet.Watcher.Tools >= 1.0.0-*",
"Microsoft.EntityFrameworkCore.Tools >= 1.0.0-preview2-final",
"Microsoft.Extensions.SecretManager.Tools >= 1.0.0-preview2-final",
"Microsoft.VisualStudio.Web.CodeGeneration.Tools >= 1.0.0-preview2-final"
]
Ah, that's a reminder that I asked for 1.0.0-*. I asked for STAR for dotnet-watch but everything else was very clear. They were specific versions. I said "I don't care about the stuff after 1.0.0 for watch, gimme whatever's good."
It seems that a new version of dotnet-watch and other tools came out between the weekend and my demo.
Search more in project.lock.json and I can see what all it asked for...I can see my dotnet-watch's dependency tree.
"tools": {
".NETCoreApp,Version=v1.0": {
"Microsoft.DotNet.Watcher.Tools/1.0.0-preview3-final": {
"type": "package",
"dependencies": {
"Microsoft.DotNet.Cli.Utils": "1.0.0-preview2-003121",
"Microsoft.Extensions.CommandLineUtils": "1.1.0-preview1-final",
"Microsoft.Extensions.Logging": "1.1.0-preview1-final",
"Microsoft.Extensions.Logging.Console": "1.1.0-preview1-final",
"Microsoft.NETCore.App": "1.1.0-preview1-001100-00"
},
Hey now. I said "1.0.0-*" and I ended up with "1.0.0-preview3-final"
Looks like dotnet-watch is trying to bring in a whole new .NET Core. It wants 1.1.0. This new dotnet-watch is part of the wave of new preview stuff from 1.1.0.
But I want to stay on the released and supported "LTS" (long term support) stuff, not the new fancy builds.
I shouldn't have used 1.0.0-* as it was ambiguous. That might be great for my local versions or when I intend to chase the latest but not in this case.
I updated my version in my project.json to this and did a restore.
"Microsoft.DotNet.Watcher.Tools": "1.0.0-preview2-final",
Now I can reliably run dotnet restore and get what I want, and both dotnet watch and dotnet run use the same underlying runtime.
Sponsor: Big thanks to Telerik! They recently launched their UI toolset for ASP.NET Core so feel free to check it out or learn more about ASP.NET Core development in their recent whitepaper.
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter
One thing I've missed in project.json is the ability to specify version ranges. I can see various scenarios:
- I want to pin to a specific version, and only that version. If I end up with anything else, make that an error.
- I want to track point releases only. So if my project.json knows about 1.1.0, I'm happy to take 1.1.1, but not 1.2.0, 1.1.1-beta01 or 2.0.0.
- I want to track non-beta releases, up to minor versions. So if my project.json knows about 1.1.0, I'm happy to take 1.1.1 or 1.2.0, but not 1.2.0-beta01 or 2.0.0.
- I want to track latest point releases, including betas. So if my project.json knows about 1.1.0-beta01, I'm happy to take 1.1.0, 1.1.1, 1.2.0, 1.1.0-beta02, 1.2.0-beta01, but not 2.0.0.
- I want to track latest anything, because I like living on the edge.
Any idea whether the new msbuild format will cover all those scenarios?
(As an aside, I keep meaning to write a blog post about this mysterious thing called backward compatibility, and how it's not as binary as we all seem to pretend.)
that way they would give the preview build the version of "1.1.0~preview3-final" which would not match your 1.0.0-* but would still be lower than "1.1.0" when "1.1.0" gets actually released
https://www.debian.org/doc/manuals/maint-guide/first.en.html#namever
There are special rules for period (.), plus (+), and tilde (~) characters, as follows:0.0 < 0.5 < 0.10 < 0.99 < 1 < 1.0~rc1 < 1.0 < 1.0+b1 < 1.0+nmu1 < 1.1 < 2.0
Assuming this expectation is false, how am I supposed to know/discover that a version of something (e.g. dotnet watch) requires a version of .NET Core that is not the one I have installed?
I do remember, too to look into the compiled .json file to find out which dependencies were required by what.
Hopefully, the whole thing will change for the better with the new project system that's based on Visual Studio files again.
Though once I was accustomed to the .json files, I liked them a lot more than the project files from VS. As a developer, I like using text files more than a UI. In a text file with auto complete, you can always start typing the required library names and you'll get a good result. With the UI, you'll have to scroll through hundreds of lines in a sub dialog, click, then browse again.
cannot find preview2-final but ended up with Microsoft.DotNet.Watcher.Tools 1.0.0-preview3-final.
I assume this got messed up somewhere between me successfully trying it on Windows and then having problems on Mac. [I am assuming that nuget does not have different behaviour or sources for different target platforms].
A subsequent dotnet restore on Mac yesterday correctly pulled in the preview2-final version.
Dependencies is such a mess in .NET Core. Between NETCore.App, platform and standard I just got lost. The documentation on MSDN is quite esoteric and seems to celebrate the complexity and ingenuity of the whole system, without any empathy for the poor developer trying to understand how it all works.
Reading posts takes me back to the DLL hell of the past.
Also I am glad we have come full circle and can edit stuff on the fly just like in the days of ASP. ha! ;-)
I was just about to try to set up a private NuGet feed/server for our internal assemblies but this makes me think my straight forward view of versioning is not the same as NuGets. Any pointers would be appreciated.
PS I like the live preview, I could type here for hours :)
In this case it would make so much more sense to me to bump the minor version of "Microsoft.DotNet.Watcher.Tools" when changing the "NETCoreApp" version. Why break something if you can avoid it AND follow good practices at the same time?
To convert :
cd -Path "F:\Desktop App Converter" then
.\DesktopAppConverter.ps1 -MakeAppx -Verbose –Installer "C:\Microsoft Store Builds\Corvette Ads\setup.exe" -InstallerArguments "/S" -Destination "C:\Microsoft Store Builds\Corvette Ads" -PackageDisplayName “Corvette Ads 1953-2017” -AppDescription "Corvette Ads 1953-2017" -PackageName “CorvetteAds” -Publisher “CN=HI-Tech Software" -Version 0.0.0.0 -AppDisplayName "Corvette Ads 1953-2017" -PackagePublisherDisplayName "HI-Tech Software"
To sign: In an Admin command prompt window:
cd "C:\Program Files (x86)\Windows Kits\10\bin\x64" then
signtool.exe sign -f my.pfx -fd SHA256 -v "C:\Microsoft Store Builds\Corvette Ads\CorvetteAds\CorvetteAds.appx"
I decided to keep using pinned versions and DotNetOutdated tool to keep them up-to-date. Working good so far. I'm open for feedback.
Warm Greetings from India.
I was a .NET programmer earlier, but thanks to you and your undying developer spirit,
I am a proud full-stack developer.
I am writing this to get a clear picture about TFS when used over VPN.
Is it possible for Visual Studio to remember project's metadata?
What is the difference between TFS access from Web browser and TFS access from VS, especially with respect to network connection?
Please take care of your health.
Thanks,
Nishant
My problem was similar, but I wasn't using 1.0.0-*. I was just explicitly using 1.0.0-preview3-final.
I am following along with your MVA video Introduction to ASP.NET Core 1.0. In it, you visit the dotnet-watch GitHub page and copy the code under How to Install. At this point in time, that documentation shows 1.0.0-preview4-final. Blindly following the video (and not thinking), I pasted this in my project.json, causing dotnet restore to report error: Unable to resolve 'Microsoft.DotNet.Watcher.Tools (>= 1.0.0-preview4-final)' for '.NETCoreApp,Version=v1.0'.
Of course it doesn't work. As of today, the version in the documentation isn't on NuGet.org. The latest version on NuGet.org is 1.0.0-preview3-final. So I changed it to that. That's when I got the error that you pointed to in this article: The specified framework 'Microsoft.NETCore.App', version '1.1.0-preview1-001100-00' was not found. Once I changed to 1.0.0-preview2-final, everything works. Thanks again!
But later I was interested in something else and i left it behind. Its good to see such a passion and good information about .net...
Comments are closed.
https://docs.microsoft.com/en-us/dotnet/articles/core/versions/