cs-script
cs-script copied to clipboard
Locked NuGet assemblies
This is a rather vague posting. It is driving me nuts since several days and maybe you can give me an idea on what might be the issue.
✅ Scenario 1, everything working correctly
- Having a CMD file "one.cmd".
- "one.cmd" calling
css
4.7.1 (installed as a global .NET tool) on a .CS script file "one.cs". - "one.cs" references a NuGet package "Foo".
- "one.cs" does a
Process.Start
todotnet build example.sln
. The "example.sln" contains a .NET 7 app that also references the NuGet package "Foo".
This works just as expected. The CS script runs, does the compilation and ends successfully.
⛔ Scenario 2, failing with a locked Foo.dll file
Similar to scenario 1 but with one more redirection.
- Having a CMD file "one.cmd".
- "one.cmd" calling
css
4.7.1 (installed as a global .NET tool) on a .CS script file "one.cs". - "one.cs" references a NuGet package "Foo".
- "one.cs" does a
Process.Start
to another CMD file "two.cmd". - "two.cmd" uses
css
4.7.1 to run "two.cs". - "two.cs" references a NuGet package "Foo".
- "two.cs" does a
Process.Start
todotnet build example.sln
. The "example.sln" contains a .NET 7 app that also references the NuGet package "Foo".
In this scenario, the dotnet build
fails with an error message similar to:
C:\Program Files\dotnet\sdk\7.0.300-preview.23179.2\NuGet.targets(156,5): error : Access to the path 'Foo.dll' is denied. [C:\my\example.sln]
This error occurs when dotnet build
is trying to restore the NuGet packages referenced by the "example.sln" project.
In a broader context, this is the log output (manually translated to English by me):
MSBuild version 17.6.0-preview-23179-01+dd5d9f746 for .NET
Projects to be restored are determined...
C:\Program Files\dotnet\sdk\7.0.300-preview.23179.2\NuGet.targets(156,5): warning : The folder "C:\Users\ukeim.nuget\packages\foo\foo.3.3.2" contains an invalid version. [C:\my\example.sln]
C:\Program Files\dotnet\sdk\7.0.300-preview.23179.2\NuGet.targets(156,5): error : Access to the path 'Foo.dll' is denied. [C:\my\example.sln]Error during build.
(The "contains an invalid version" also makes me scratch my head).
What I've tried
I've already tried the use Process Monitor to sniff during the CMD run to see which process is accessing the file, but I still get no real idea what I'm doing wrong here.
My question
Could you throw any wild guesses at me, what might be going on here?
I repeated your experiment and found that two.cmd
process hangs after completion. Meaning that most likely it locked some files (e.g. foo.dll).
There is something interesting about how dotnet handles termination for a child process.
I found that I can fix it by waiting in one.cs for completion of the child two.cmd. This way both parent and child processes exit gracefully:
Process.Start(@"D:\dev\Galos\support\cs-script_#331\two.cmd").WaitForExit();
I have attached the whole sample: cs-script_#331.zip
Thank you very much, Oleg!
In my scripts, I already do call .WaitForExit()
. Confusing to me that it works in your experiment but not in mine.
I'll try to investigate further. Maybe it is because I'm doing more than just a simple Process.Start
; I'm also doing EnableRaisingEvents
, BeginOutputReadLine
, BeginErrorReadLine
and stuff like this. Maybe this hinders my script from waiting until the process exited completely.
Interestingly enough even if the file is locked (e.g. loaded by the hanging script), it should not be a problem. Any other NuGet client (e.g. script, VS, dotnet) simply references this dll, which is OK even for the locked file.
Unless dotnet.exe
it trying to do something mote aggressive.
Mind you it was one difference in my experiment. I was using CSS installed by choco. Though I do not see how it can be different...