diff --git a/src/SingleProject/Resizetizer/src/SkiaSharpTools.cs b/src/SingleProject/Resizetizer/src/SkiaSharpTools.cs
index e81d311351c8..41562c4994a1 100644
--- a/src/SingleProject/Resizetizer/src/SkiaSharpTools.cs
+++ b/src/SingleProject/Resizetizer/src/SkiaSharpTools.cs
@@ -1,12 +1,54 @@
using System;
using System.Diagnostics;
using System.IO;
+using System.Threading;
+using System.Runtime.InteropServices;
using SkiaSharp;
namespace Microsoft.Maui.Resizetizer
{
internal abstract class SkiaSharpTools
{
+ const int ERROR_ACCESS_DENIED = -2147024891;
+ const int ERROR_SHARING_VIOLATION = -2147024864;
+ const int DEFAULT_FILE_WRITE_RETRY_ATTEMPTS = 10;
+ const int DEFAULT_FILE_WRITE_RETRY_DELAY_MS = 1000;
+
+ static int fileWriteRetry = -1;
+ static int fileWriteRetryDelay = -1;
+
+ ///
+ /// Checks for the environment variable DOTNET_ANDROID_FILE_WRITE_RETRY_ATTEMPTS to
+ /// see if a custom value for the number of times to retry writing a file has been
+ /// set.
+ ///
+ /// The value of DOTNET_ANDROID_FILE_WRITE_RETRY_ATTEMPTS or the default of DEFAULT_FILE_WRITE_RETRY_ATTEMPTS
+ public static int GetFileWriteRetryAttempts ()
+ {
+ if (fileWriteRetry == -1) {
+ var retryVariable = Environment.GetEnvironmentVariable ("DOTNET_ANDROID_FILE_WRITE_RETRY_ATTEMPTS");
+ if (string.IsNullOrEmpty (retryVariable) || !int.TryParse (retryVariable, out fileWriteRetry))
+ fileWriteRetry = DEFAULT_FILE_WRITE_RETRY_ATTEMPTS;
+ }
+ return fileWriteRetry;
+ }
+
+ ///
+ /// Checks for the environment variable DOTNET_ANDROID_FILE_WRITE_RETRY_DELAY_MS to
+ /// see if a custom value for the delay between trying to write a file has been
+ /// set.
+ ///
+ /// The value of DOTNET_ANDROID_FILE_WRITE_RETRY_DELAY_MS or the default of DEFAULT_FILE_WRITE_RETRY_DELAY_MS
+ public static int GetFileWriteRetryDelay ()
+ {
+ if (fileWriteRetryDelay == -1) {
+ var delayVariable = Environment.GetEnvironmentVariable ("DOTNET_ANDROID_FILE_WRITE_RETRY_DELAY_MS");
+ if (string.IsNullOrEmpty (delayVariable) || !int.TryParse (delayVariable, out fileWriteRetryDelay))
+ fileWriteRetryDelay = DEFAULT_FILE_WRITE_RETRY_DELAY_MS;
+ }
+ return fileWriteRetryDelay;
+ }
+
static SkiaSharpTools()
{
// DO NOT DELETE!
@@ -150,8 +192,35 @@ void Draw(SKBitmap tempBitmap, double additionalScale, SKSize originalSize, floa
void Save(string destination, SKBitmap tempBitmap)
{
- using var stream = File.Create(destination);
- tempBitmap.Encode(stream, SKEncodedImageFormat.Png, 100);
+ int attempt = 0;
+ int attempts = GetFileWriteRetryAttempts ();
+ int delay = GetFileWriteRetryDelay ();
+ while (attempt <= attempts)
+ {
+ try
+ {
+ using var stream = File.Create(destination);
+ tempBitmap.Encode(stream, SKEncodedImageFormat.Png, 100);
+ }
+ catch (Exception ex)
+ {
+ switch (ex)
+ {
+ case UnauthorizedAccessException:
+ case IOException:
+ var code = Marshal.GetHRForException(ex);
+ if ((code != ERROR_ACCESS_DENIED && code != ERROR_SHARING_VIOLATION) || attempt == attempts)
+ {
+ throw;
+ }
+ break;
+ default:
+ throw;
+ }
+ attempt++;
+ Thread.Sleep(delay);
+ }
+ }
}
public abstract SKSize GetOriginalSize();
diff --git a/src/SingleProject/Resizetizer/src/nuget/buildTransitive/Microsoft.Maui.Resizetizer.After.targets b/src/SingleProject/Resizetizer/src/nuget/buildTransitive/Microsoft.Maui.Resizetizer.After.targets
index 0338df96324b..4a215b116acd 100644
--- a/src/SingleProject/Resizetizer/src/nuget/buildTransitive/Microsoft.Maui.Resizetizer.After.targets
+++ b/src/SingleProject/Resizetizer/src/nuget/buildTransitive/Microsoft.Maui.Resizetizer.After.targets
@@ -59,21 +59,6 @@
_CleanResizetizer;
- <_ResizetizerInputsFile>$(IntermediateOutputPath)mauiimage.inputs
- <_ResizetizerOutputsFile>$(IntermediateOutputPath)mauiimage.outputs
- <_ResizetizerStampFile>$(IntermediateOutputPath)mauiimage.stamp
- <_MauiFontInputsFile>$(IntermediateOutputPath)mauifont.inputs
- <_MauiFontStampFile>$(IntermediateOutputPath)mauifont.stamp
- <_MauiSplashInputsFile>$(IntermediateOutputPath)mauisplash.inputs
- <_MauiSplashStampFile>$(IntermediateOutputPath)mauisplash.stamp
- <_MauiManifestStampFile>$(IntermediateOutputPath)mauimanifest.stamp
-
- <_ResizetizerIntermediateOutputRoot>$(IntermediateOutputPath)resizetizer\
- <_MauiIntermediateImages>$(_ResizetizerIntermediateOutputRoot)r\
- <_MauiIntermediateFonts>$(_ResizetizerIntermediateOutputRoot)f\
- <_MauiIntermediateSplashScreen>$(_ResizetizerIntermediateOutputRoot)sp\
- <_MauiIntermediateManifest>$(_ResizetizerIntermediateOutputRoot)m\
-
<_ResizetizerPlatformIdentifier>$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)'))
<_ResizetizerNoTargetPlatform Condition="'$(_ResizetizerPlatformIdentifier)' == ''">True
<_ResizetizerPlatformIsAndroid Condition="'$(_ResizetizerPlatformIdentifier)' == 'android'">True
@@ -84,6 +69,24 @@
<_ResizetizerPlatformIsWindows Condition="$(_ResizetizerPlatformIdentifier.Contains('windows')) == 'True'">True
<_ResizetizerPlatformIsTizen Condition="'$(_ResizetizerPlatformIdentifier)' == 'tizen'">True
+ <_ResizetizerIntermediateOutputPath Condition=" '$(_ResizetizerIntermediateOutputPath)' == '' And '$(_ResizetizerPlatformIsAndroid)' == 'True' And '$(DesignTimeBuild)' == 'True' ">$(IntermediateOutputPath)designtime
+ <_ResizetizerIntermediateOutputPath Condition=" '$(_ResizetizerIntermediateOutputPath)' == '' " >$(IntermediateOutputPath)
+
+ <_ResizetizerInputsFile>$(_ResizetizerIntermediateOutputPath)mauiimage.inputs
+ <_ResizetizerOutputsFile>$(_ResizetizerIntermediateOutputPath)mauiimage.outputs
+ <_ResizetizerStampFile>$(_ResizetizerIntermediateOutputPath)mauiimage.stamp
+ <_MauiFontInputsFile>$(_ResizetizerIntermediateOutputPath)mauifont.inputs
+ <_MauiFontStampFile>$(_ResizetizerIntermediateOutputPath)mauifont.stamp
+ <_MauiSplashInputsFile>$(_ResizetizerIntermediateOutputPath)mauisplash.inputs
+ <_MauiSplashStampFile>$(_ResizetizerIntermediateOutputPath)mauisplash.stamp
+ <_MauiManifestStampFile>$(_ResizetizerIntermediateOutputPath)mauimanifest.stamp
+
+ <_ResizetizerIntermediateOutputRoot>$(_ResizetizerIntermediateOutputPath)resizetizer\
+ <_MauiIntermediateImages>$(_ResizetizerIntermediateOutputRoot)r\
+ <_MauiIntermediateFonts>$(_ResizetizerIntermediateOutputRoot)f\
+ <_MauiIntermediateSplashScreen>$(_ResizetizerIntermediateOutputRoot)sp\
+ <_MauiIntermediateManifest>$(_ResizetizerIntermediateOutputRoot)m\
+
False
<_ResizetizerDefaultInvalidFilenamesErrorMessage>One or more invalid file names were detected. File names must be lowercase, start and end with a letter character, and contain only alphanumeric characters or underscores:
@@ -504,7 +507,7 @@
-
+