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 #25374

Merged
merged 4 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 71 additions & 2 deletions src/SingleProject/Resizetizer/src/SkiaSharpTools.cs
Original file line number Diff line number Diff line change
@@ -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;

/// <summary>
/// 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.
/// </summary>
/// <returns>The value of DOTNET_ANDROID_FILE_WRITE_RETRY_ATTEMPTS or the default of DEFAULT_FILE_WRITE_RETRY_ATTEMPTS</returns>
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;
}

/// <summary>
/// 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.
/// </summary>
/// <returns>The value of DOTNET_ANDROID_FILE_WRITE_RETRY_DELAY_MS or the default of DEFAULT_FILE_WRITE_RETRY_DELAY_MS</returns>
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!
Expand Down Expand Up @@ -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);
}
dellis1972 marked this conversation as resolved.
Show resolved Hide resolved
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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,6 @@
_CleanResizetizer;
</CleanDependsOn>

<_ResizetizerInputsFile>$(IntermediateOutputPath)mauiimage.inputs</_ResizetizerInputsFile>
<_ResizetizerOutputsFile>$(IntermediateOutputPath)mauiimage.outputs</_ResizetizerOutputsFile>
<_ResizetizerStampFile>$(IntermediateOutputPath)mauiimage.stamp</_ResizetizerStampFile>
<_MauiFontInputsFile>$(IntermediateOutputPath)mauifont.inputs</_MauiFontInputsFile>
<_MauiFontStampFile>$(IntermediateOutputPath)mauifont.stamp</_MauiFontStampFile>
<_MauiSplashInputsFile>$(IntermediateOutputPath)mauisplash.inputs</_MauiSplashInputsFile>
<_MauiSplashStampFile>$(IntermediateOutputPath)mauisplash.stamp</_MauiSplashStampFile>
<_MauiManifestStampFile>$(IntermediateOutputPath)mauimanifest.stamp</_MauiManifestStampFile>

<_ResizetizerIntermediateOutputRoot>$(IntermediateOutputPath)resizetizer\</_ResizetizerIntermediateOutputRoot>
<_MauiIntermediateImages>$(_ResizetizerIntermediateOutputRoot)r\</_MauiIntermediateImages>
<_MauiIntermediateFonts>$(_ResizetizerIntermediateOutputRoot)f\</_MauiIntermediateFonts>
<_MauiIntermediateSplashScreen>$(_ResizetizerIntermediateOutputRoot)sp\</_MauiIntermediateSplashScreen>
<_MauiIntermediateManifest>$(_ResizetizerIntermediateOutputRoot)m\</_MauiIntermediateManifest>

<_ResizetizerPlatformIdentifier>$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)'))</_ResizetizerPlatformIdentifier>
<_ResizetizerNoTargetPlatform Condition="'$(_ResizetizerPlatformIdentifier)' == ''">True</_ResizetizerNoTargetPlatform>
<_ResizetizerPlatformIsAndroid Condition="'$(_ResizetizerPlatformIdentifier)' == 'android'">True</_ResizetizerPlatformIsAndroid>
Expand All @@ -84,6 +69,23 @@
<_ResizetizerPlatformIsWindows Condition="$(_ResizetizerPlatformIdentifier.Contains('windows')) == 'True'">True</_ResizetizerPlatformIsWindows>
<_ResizetizerPlatformIsTizen Condition="'$(_ResizetizerPlatformIdentifier)' == 'tizen'">True</_ResizetizerPlatformIsTizen>

<_ResizetizerIntermediateOutputPath Condition=" '$(_ResizetizerIntermediateOutputPath)' == '' " >$(IntermediateOutputPath)</_ResizetizerIntermediateOutputPath>

<_ResizetizerInputsFile>$(_ResizetizerIntermediateOutputPath)mauiimage.inputs</_ResizetizerInputsFile>
<_ResizetizerOutputsFile>$(_ResizetizerIntermediateOutputPath)mauiimage.outputs</_ResizetizerOutputsFile>
<_ResizetizerStampFile>$(_ResizetizerIntermediateOutputPath)mauiimage.stamp</_ResizetizerStampFile>
<_MauiFontInputsFile>$(_ResizetizerIntermediateOutputPath)mauifont.inputs</_MauiFontInputsFile>
<_MauiFontStampFile>$(_ResizetizerIntermediateOutputPath)mauifont.stamp</_MauiFontStampFile>
<_MauiSplashInputsFile>$(_ResizetizerIntermediateOutputPath)mauisplash.inputs</_MauiSplashInputsFile>
<_MauiSplashStampFile>$(_ResizetizerIntermediateOutputPath)mauisplash.stamp</_MauiSplashStampFile>
<_MauiManifestStampFile>$(_ResizetizerIntermediateOutputPath)mauimanifest.stamp</_MauiManifestStampFile>

<_ResizetizerIntermediateOutputRoot>$(_ResizetizerIntermediateOutputPath)resizetizer\</_ResizetizerIntermediateOutputRoot>
<_MauiIntermediateImages>$(_ResizetizerIntermediateOutputRoot)r\</_MauiIntermediateImages>
<_MauiIntermediateFonts>$(_ResizetizerIntermediateOutputRoot)f\</_MauiIntermediateFonts>
<_MauiIntermediateSplashScreen>$(_ResizetizerIntermediateOutputRoot)sp\</_MauiIntermediateSplashScreen>
<_MauiIntermediateManifest>$(_ResizetizerIntermediateOutputRoot)m\</_MauiIntermediateManifest>

<ResizetizerIncludeSelfProject Condition="'$(ResizetizerIncludeSelfProject)' == ''">False</ResizetizerIncludeSelfProject>

<_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: </_ResizetizerDefaultInvalidFilenamesErrorMessage>
Expand Down Expand Up @@ -504,7 +506,7 @@
</ItemGroup>

<!-- Stamp file for Outputs -->
<MakeDir Directories="$(IntermediateOutputPath)"/>
<MakeDir Directories="$(_ResizetizerIntermediateOutputPath)"/>
<Touch Files="$(_MauiSplashStampFile)" AlwaysCreate="True" />

<ItemGroup>
Expand Down
Loading