Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating .NET MAUI Project sometimes causes error *.png is being used by another process #25207

Closed
samhouts opened this issue Oct 11, 2024 · 9 comments · Fixed by #25374
Closed
Assignees
Labels
area-setup Installation, setup, requirements, maui-check, workloads, platform support area-single-project Splash Screen, Multi-Targeting, MauiFont, MauiImage, MauiAsset, Resizetizer delighter-sc external fixed-in-9.0.21 p/0 Work that we can't release without partner/android Issues for the Android SDK platform/android 🤖 t/bug Something isn't working
Milestone

Comments

@samhouts
Copy link
Member

Affected Branch: main
Affected Build: 17.12 Preview 2 (35212.216 main)

Steps to reproduce:

JoPryo might have a fix for Android concurrency errors

1. Create new .NET MAUI Project

 →  [Visual Studio Host (17232):ErrorListService] Error list item: There was an exception processing the image 'C:\school\ApexSolutions\TestCase95\Prj_OOb72RB3aqiqIPq\Resources\AppIcon\appicon.svg': System.IO.IOException: The process cannot access the file 'C:\school\ApexSolutions\TestCase95\Prj_OOb72RB3aqiqIPq\obj\Debug\net8.0-android\resizetizer\r\mipmap-xxhdpi\appicon.png' because it is being used by another process.
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
 →  [Visual Studio Host (17232):ToolWindowTestExtension] Showing window 'Error List' without activating the window.





[Visual Studio Host (13920):ErrorListService] Expect empty but still show items within timeout 15 seconds.15:45:09
[Visual Studio Host (13920):ErrorListService] + Top 10 Error List items:15:45:09
 →  [Visual Studio Host (13920):ErrorListService] Error list item: There was an exception processing the image 'C:\school\ApexSolutions\TestCase180\Prj__ilCNxfwu9U\Resources\Images\dotnet_bot.png': System.IO.IOException: The process cannot access the file 'C:\school\ApexSolutions\TestCase180\Prj__ilCNxfwu9U\obj\Debug\net8.0-android\resizetizer\r\drawable-xxhdpi\dotnet_bot.png' because it is being used by another process.
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"





View on AzDO

@dotnet-policy-service dotnet-policy-service bot added the s/triaged Issue has been reviewed label Oct 11, 2024
@Redth
Copy link
Member

Redth commented Oct 11, 2024

Thoughts:

  1. This could be design time build interfering with normal build?
  2. Do we want to run these tasks at all for design time builds?
  3. 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 ^

@dellis1972
Copy link
Contributor

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?

@Redth
Copy link
Member

Redth commented Oct 11, 2024

@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?

@dellis1972
Copy link
Contributor

@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

@samhouts
Copy link
Member Author

@samhouts
Copy link
Member Author

@samhouts samhouts added t/bug Something isn't working area-setup Installation, setup, requirements, maui-check, workloads, platform support and removed s/triaged Issue has been reviewed labels Oct 11, 2024
@dellis1972
Copy link
Contributor

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

@StephaneDelcroix StephaneDelcroix added platform/android 🤖 area-image Image loading, sources, caching labels Oct 15, 2024
@samhouts samhouts added partner/android Issues for the Android SDK external area-single-project Splash Screen, Multi-Targeting, MauiFont, MauiImage, MauiAsset, Resizetizer delighter-sc and removed area-image Image loading, sources, caching labels Oct 17, 2024
@dellis1972
Copy link
Contributor

Related dotnet/android#9423

dellis1972 added a commit to dellis1972/maui that referenced this issue Oct 18, 2024
… by another process

Fixes dotnet#25207
Context
dotnet/android-tools#245
dotnet/android#9409

So there is a problem where the design time builds (DTB) of android sometimes
lock files. This can happen when two processes try to write to the same
file. This is not a great experience for our users as it just fails the build.

So lets try a few things to fix this.

1. Move the Resizetizer output for a DTB into the android
`$(IntermediateOutputPath)designtime` folder. This will keep the DTB files
completely separate. This should prevent clashes.
2. Add some retry code to the `SkiaSharpTools.Save` method. This will catch
`UnauthorizedAccessException` exceptions as well as specific `IOException` types
(Access Denied and Sharing Violation). This will allow us to catch when this happens
and retry the write. There is a small delay before attempting to write the file
again.

Note these code uses the Identical code as we are going to use in Android.
We have introduced two new environment variables which can be used to
control the new behavior.

1. `DOTNET_ANDROID_FILE_WRITE_RETRY_ATTEMPTS`. Integer, controls the number of times
we try to write the file. The default is 10.
2. `DOTNET_ANDROID_FILE_WRITE_RETRY_DELAY_MS`. Integer, controls the delay in
milliseconds between retry attempts.  Default is 1000ms (or 1 second).
dellis1972 added a commit to dellis1972/maui that referenced this issue Oct 22, 2024
… by another process

Fixes dotnet#25207
Context
dotnet/android-tools#245
dotnet/android#9409

So there is a problem where the design time builds (DTB) of android sometimes
lock files. This can happen when two processes try to write to the same
file. This is not a great experience for our users as it just fails the build.

So lets try a few things to fix this.

1. Move the Resizetizer output for a DTB into the android
`$(IntermediateOutputPath)designtime` folder. This will keep the DTB files
completely separate. This should prevent clashes.
2. Add some retry code to the `SkiaSharpTools.Save` method. This will catch
`UnauthorizedAccessException` exceptions as well as specific `IOException` types
(Access Denied and Sharing Violation). This will allow us to catch when this happens
and retry the write. There is a small delay before attempting to write the file
again.

Note these code uses the Identical code as we are going to use in Android.
We have introduced two new environment variables which can be used to
control the new behavior.

1. `DOTNET_ANDROID_FILE_WRITE_RETRY_ATTEMPTS`. Integer, controls the number of times
we try to write the file. The default is 10.
2. `DOTNET_ANDROID_FILE_WRITE_RETRY_DELAY_MS`. Integer, controls the delay in
milliseconds between retry attempts.  Default is 1000ms (or 1 second).
dellis1972 added a commit to dellis1972/maui that referenced this issue Oct 23, 2024
… by another process

Fixes dotnet#25207
Context
dotnet/android-tools#245
dotnet/android#9409

So there is a problem where the design time builds (DTB) of android sometimes
lock files. This can happen when two processes try to write to the same
file. This is not a great experience for our users as it just fails the build.

So lets try a few things to fix this.

1. Move the Resizetizer output for a DTB into the android
`$(IntermediateOutputPath)designtime` folder. This will keep the DTB files
completely separate. This should prevent clashes.
2. Add some retry code to the `SkiaSharpTools.Save` method. This will catch
`UnauthorizedAccessException` exceptions as well as specific `IOException` types
(Access Denied and Sharing Violation). This will allow us to catch when this happens
and retry the write. There is a small delay before attempting to write the file
again.

Note these code uses the Identical code as we are going to use in Android.
We have introduced two new environment variables which can be used to
control the new behavior.

1. `DOTNET_ANDROID_FILE_WRITE_RETRY_ATTEMPTS`. Integer, controls the number of times
we try to write the file. The default is 10.
2. `DOTNET_ANDROID_FILE_WRITE_RETRY_DELAY_MS`. Integer, controls the delay in
milliseconds between retry attempts.  Default is 1000ms (or 1 second).
@dellis1972
Copy link
Contributor

More Context

dotnet/android#9423
#25374

dellis1972 added a commit to dellis1972/maui that referenced this issue Oct 29, 2024
… by another process

Fixes dotnet#25207
Context
dotnet/android-tools#245
dotnet/android#9409

So there is a problem where the design time builds (DTB) of android sometimes
lock files. This can happen when two processes try to write to the same
file. This is not a great experience for our users as it just fails the build.

So lets try a few things to fix this.

1. Move the Resizetizer output for a DTB into the android
`$(IntermediateOutputPath)designtime` folder. This will keep the DTB files
completely separate. This should prevent clashes.
2. Add some retry code to the `SkiaSharpTools.Save` method. This will catch
`UnauthorizedAccessException` exceptions as well as specific `IOException` types
(Access Denied and Sharing Violation). This will allow us to catch when this happens
and retry the write. There is a small delay before attempting to write the file
again.

Note these code uses the Identical code as we are going to use in Android.
We have introduced two new environment variables which can be used to
control the new behavior.

1. `DOTNET_ANDROID_FILE_WRITE_RETRY_ATTEMPTS`. Integer, controls the number of times
we try to write the file. The default is 10.
2. `DOTNET_ANDROID_FILE_WRITE_RETRY_DELAY_MS`. Integer, controls the delay in
milliseconds between retry attempts.  Default is 1000ms (or 1 second).
dellis1972 added a commit to dellis1972/maui that referenced this issue Nov 7, 2024
… by another process

Fixes dotnet#25207
Context
dotnet/android-tools#245
dotnet/android#9409

So there is a problem where the design time builds (DTB) of android sometimes
lock files. This can happen when two processes try to write to the same
file. This is not a great experience for our users as it just fails the build.

So lets try a few things to fix this.

1. Move the Resizetizer output for a DTB into the android
`$(IntermediateOutputPath)designtime` folder. This will keep the DTB files
completely separate. This should prevent clashes.
2. Add some retry code to the `SkiaSharpTools.Save` method. This will catch
`UnauthorizedAccessException` exceptions as well as specific `IOException` types
(Access Denied and Sharing Violation). This will allow us to catch when this happens
and retry the write. There is a small delay before attempting to write the file
again.

Note these code uses the Identical code as we are going to use in Android.
We have introduced two new environment variables which can be used to
control the new behavior.

1. `DOTNET_ANDROID_FILE_WRITE_RETRY_ATTEMPTS`. Integer, controls the number of times
we try to write the file. The default is 10.
2. `DOTNET_ANDROID_FILE_WRITE_RETRY_DELAY_MS`. Integer, controls the delay in
milliseconds between retry attempts.  Default is 1000ms (or 1 second).
dellis1972 added a commit to dellis1972/maui that referenced this issue Nov 24, 2024
… by another process

Fixes dotnet#25207
Context
dotnet/android-tools#245
dotnet/android#9409

So there is a problem where the design time builds (DTB) of android sometimes
lock files. This can happen when two processes try to write to the same
file. This is not a great experience for our users as it just fails the build.

So lets try a few things to fix this.

1. Move the Resizetizer output for a DTB into the android
`$(IntermediateOutputPath)designtime` folder. This will keep the DTB files
completely separate. This should prevent clashes.
2. Add some retry code to the `SkiaSharpTools.Save` method. This will catch
`UnauthorizedAccessException` exceptions as well as specific `IOException` types
(Access Denied and Sharing Violation). This will allow us to catch when this happens
and retry the write. There is a small delay before attempting to write the file
again.

Note these code uses the Identical code as we are going to use in Android.
We have introduced two new environment variables which can be used to
control the new behavior.

1. `DOTNET_ANDROID_FILE_WRITE_RETRY_ATTEMPTS`. Integer, controls the number of times
we try to write the file. The default is 10.
2. `DOTNET_ANDROID_FILE_WRITE_RETRY_DELAY_MS`. Integer, controls the delay in
milliseconds between retry attempts.  Default is 1000ms (or 1 second).
dellis1972 added a commit to dellis1972/maui that referenced this issue Nov 29, 2024
… by another process

Fixes dotnet#25207
Context
dotnet/android-tools#245
dotnet/android#9409

So there is a problem where the design time builds (DTB) of android sometimes
lock files. This can happen when two processes try to write to the same
file. This is not a great experience for our users as it just fails the build.

So lets try a few things to fix this.

1. Move the Resizetizer output for a DTB into the android
`$(IntermediateOutputPath)designtime` folder. This will keep the DTB files
completely separate. This should prevent clashes.
2. Add some retry code to the `SkiaSharpTools.Save` method. This will catch
`UnauthorizedAccessException` exceptions as well as specific `IOException` types
(Access Denied and Sharing Violation). This will allow us to catch when this happens
and retry the write. There is a small delay before attempting to write the file
again.

Note these code uses the Identical code as we are going to use in Android.
We have introduced two new environment variables which can be used to
control the new behavior.

1. `DOTNET_ANDROID_FILE_WRITE_RETRY_ATTEMPTS`. Integer, controls the number of times
we try to write the file. The default is 10.
2. `DOTNET_ANDROID_FILE_WRITE_RETRY_DELAY_MS`. Integer, controls the delay in
milliseconds between retry attempts.  Default is 1000ms (or 1 second).
dellis1972 added a commit to dellis1972/maui that referenced this issue Dec 4, 2024
… by another process

Fixes dotnet#25207
Context
dotnet/android-tools#245
dotnet/android#9409

So there is a problem where the design time builds (DTB) of android sometimes
lock files. This can happen when two processes try to write to the same
file. This is not a great experience for our users as it just fails the build.

So lets try a few things to fix this.

1. Move the Resizetizer output for a DTB into the android
`$(IntermediateOutputPath)designtime` folder. This will keep the DTB files
completely separate. This should prevent clashes.
2. Add some retry code to the `SkiaSharpTools.Save` method. This will catch
`UnauthorizedAccessException` exceptions as well as specific `IOException` types
(Access Denied and Sharing Violation). This will allow us to catch when this happens
and retry the write. There is a small delay before attempting to write the file
again.

Note these code uses the Identical code as we are going to use in Android.
We have introduced two new environment variables which can be used to
control the new behavior.

1. `DOTNET_ANDROID_FILE_WRITE_RETRY_ATTEMPTS`. Integer, controls the number of times
we try to write the file. The default is 10.
2. `DOTNET_ANDROID_FILE_WRITE_RETRY_DELAY_MS`. Integer, controls the delay in
milliseconds between retry attempts.  Default is 1000ms (or 1 second).
github-actions bot pushed a commit to dellis1972/maui that referenced this issue Dec 4, 2024
… by another process

Fixes dotnet#25207
Context
dotnet/android-tools#245
dotnet/android#9409

So there is a problem where the design time builds (DTB) of android sometimes
lock files. This can happen when two processes try to write to the same
file. This is not a great experience for our users as it just fails the build.

So lets try a few things to fix this.

1. Move the Resizetizer output for a DTB into the android
`$(IntermediateOutputPath)designtime` folder. This will keep the DTB files
completely separate. This should prevent clashes.
2. Add some retry code to the `SkiaSharpTools.Save` method. This will catch
`UnauthorizedAccessException` exceptions as well as specific `IOException` types
(Access Denied and Sharing Violation). This will allow us to catch when this happens
and retry the write. There is a small delay before attempting to write the file
again.

Note these code uses the Identical code as we are going to use in Android.
We have introduced two new environment variables which can be used to
control the new behavior.

1. `DOTNET_ANDROID_FILE_WRITE_RETRY_ATTEMPTS`. Integer, controls the number of times
we try to write the file. The default is 10.
2. `DOTNET_ANDROID_FILE_WRITE_RETRY_DELAY_MS`. Integer, controls the delay in
milliseconds between retry attempts.  Default is 1000ms (or 1 second).
@PureWeen PureWeen added this to the .NET 9 SR2 milestone Dec 4, 2024
@PureWeen PureWeen added the p/0 Work that we can't release without label Dec 4, 2024
dellis1972 added a commit to dellis1972/maui that referenced this issue Dec 5, 2024
… by another process

Fixes dotnet#25207
Context
dotnet/android-tools#245
dotnet/android#9409

So there is a problem where the design time builds (DTB) of android sometimes
lock files. This can happen when two processes try to write to the same
file. This is not a great experience for our users as it just fails the build.

So lets try a few things to fix this.

1. Move the Resizetizer output for a DTB into the android
`$(IntermediateOutputPath)designtime` folder. This will keep the DTB files
completely separate. This should prevent clashes.
2. Add some retry code to the `SkiaSharpTools.Save` method. This will catch
`UnauthorizedAccessException` exceptions as well as specific `IOException` types
(Access Denied and Sharing Violation). This will allow us to catch when this happens
and retry the write. There is a small delay before attempting to write the file
again.

Note these code uses the Identical code as we are going to use in Android.
We have introduced two new environment variables which can be used to
control the new behavior.

1. `DOTNET_ANDROID_FILE_WRITE_RETRY_ATTEMPTS`. Integer, controls the number of times
we try to write the file. The default is 10.
2. `DOTNET_ANDROID_FILE_WRITE_RETRY_DELAY_MS`. Integer, controls the delay in
milliseconds between retry attempts.  Default is 1000ms (or 1 second).
@github-project-automation github-project-automation bot moved this from Todo to Done in MAUI SDK Ongoing Dec 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-setup Installation, setup, requirements, maui-check, workloads, platform support area-single-project Splash Screen, Multi-Targeting, MauiFont, MauiImage, MauiAsset, Resizetizer delighter-sc external fixed-in-9.0.21 p/0 Work that we can't release without partner/android Issues for the Android SDK platform/android 🤖 t/bug Something isn't working
Projects
Status: Done
5 participants