Creating .NET MAUI Project sometimes causes error *.png is being used by another process
Steps to reproduce:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)
at Microsoft.Maui.Resizetizer.SkiaSharpAppIconTools.Save(SKBitmap tempBitmap, String destination, Func`1 getStream) in /_/src/SingleProject/Resizetizer/src/SkiaSharpAppIconTools.cs:line 75
at Microsoft.Maui.Resizetizer.SkiaSharpAppIconTools.Resize(DpiPath dpi, String destination, Func`1 getStream) in /_/src/SingleProject/Resizetizer/src/SkiaSharpAppIconTools.cs:line 54
at Microsoft.Maui.Resizetizer.ResizetizeImages.ProcessAppIcon(ResizeImageInfo img, ConcurrentBag`1 resizedImages) in /_/src/SingleProject/Resizetizer/src/ResizetizeImages.cs:line 229
at Microsoft.Maui.Resizetizer.ResizetizeImages.<>c__DisplayClass34_0.<ExecuteAsync>b__0(ResizeImageInfo img) in /_/src/SingleProject/Resizetizer/src/ResizetizeImages.cs:line 65; in file "Microsoft.Maui.Resizetizer.After.targets"14:14:34
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)
at Microsoft.Maui.Resizetizer.SkiaSharpTools.Save(String destination, SKBitmap tempBitmap) in /_/src/SingleProject/Resizetizer/src/SkiaSharpTools.cs:line 153
at Microsoft.Maui.Resizetizer.SkiaSharpTools.Resize(DpiPath dpi, String destination, Double additionalScale, Boolean dpiSizeIsAbsolute) in /_/src/SingleProject/Resizetizer/src/SkiaSharpTools.cs:line 74
at Microsoft.Maui.Resizetizer.Resizer.Resize(DpiPath dpi, String inputsFile) in /_/src/SingleProject/Resizetizer/src/Resizer.cs:line 107
at Microsoft.Maui.Resizetizer.ResizetizeImages.ProcessImageResize(ResizeImageInfo img, DpiPath[] dpis, ConcurrentBag`1 resizedImages) in /_/src/SingleProject/Resizetizer/src/ResizetizeImages.cs:line 238
at Microsoft.Maui.Resizetizer.ResizetizeImages.<>c__DisplayClass34_0.<ExecuteAsync>b__0(ResizeImageInfo img) in /_/src/SingleProject/Resizetizer/src/ResizetizeImages.cs:line 74; in file "Microsoft.Maui.Resizetizer.After.targets"
Thoughts:
- This could be design time build interfering with normal build?
- Do we want to run these tasks at all for design time builds?
- If we do want to run them we could make sure design time build output is a different location than normal (as per @jonpryor )
FYI: @dellis1972 ^
The DTB is only needed soe C# code. I guess because they are drawables they will end up in the R.txt and then the Resource.designer assembly.
Now quite why the same file (in a temp directory!) is locked is very weird. my understanding is that these temp directories are per build, they are not shared... so something else must be locking the file?
@dellis1972 yes i had the thought about the c# resource code generation, but it's not clear to me if these are actually produced early enough in a design time build for instance, that would impact c# resource code generation in a way that's useful to have? hopefully that makes sense?
@Redth in order to be useful in an app they will need to be created before the Aapt2Compile step runs in a usual build. So it will be running early enough to appear in the resource code for a DTB. You can confirm that by checking the Resource.Drawable.appicon field and making sure its there in intellisense.
Now could we somehow side step this in DTB and still have the right entries appear in the designer code... maybe.
More concerning is the fact the temp directories are not unique to a build? If they are unique then its probably something like Anti Virus causing the lock.
It might be worth adding this to the Resizetizer code https://github.com/dotnet/android-tools/blob/ab2165daf27d4fcb29e88bc022e0ab0be33aff69/src/Microsoft.Android.Build.BaseTasks/UnhandledExceptionLogger.cs#L89
https://dev.azure.com/devdiv/DevDiv/_workitems/edit/2136165
https://devdiv.visualstudio.com/DevDiv/_workitems/edit/2136883
This whole design time build thing is a real tricky problem.
On the one hand you want accurate intellisense. On the other it has to be really really fast so it doens't break the main build. It should not write files into the same directory as the main build. reading files is fine, just not writing files.
We could skip a bunch of targets if we are in a DTB context (like calling Resizetizer) and only use the files that are already generated. But then we end up with inaccurate intellisense. Users will end up with red squiggles under code that is perfectly valid..
I'm trying to think of a way around this, but if anyone has any suggestions feel free to mention them
Related https://github.com/dotnet/android/pull/9423
More Context
https://github.com/dotnet/android/pull/9423/ https://github.com/dotnet/maui/pull/25374
I still have this issue, also with 9.0.21. I think something went wrong with this commit: 31bfbcc It says 'All checks have failed'