-
Notifications
You must be signed in to change notification settings - Fork 538
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
Handle aapt2
error "The system cannot find the file specified." slightly better
#7644
Conversation
afd4fae
to
5957515
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Otherwise, the actual code changes look good. 👍
This is generally caused by the path being longer than the Maximum Path | ||
length allowed on windows. | ||
|
||
## Solution |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we suggest enabling long paths as the 1st solution?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As per the docs, two things must be done: the registry must be updated to set HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled
-- and I wonder if that could/would break anything -- and secondly:
- The application manifest must also include the
longPathAware
element.<application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings"> <ws2:longPathAware>true</ws2:longPathAware> </windowsSettings> </application>
We do not currently ship an aapt2.exe.config
manifest file.
Additionally, it may be moot; the next section in docs states:
These are the directory management functions that no longer have MAX_PATH restrictions if you opt-in to long path behavior: CreateDirectoryW, CreateDirectoryExW GetCurrentDirectoryW RemoveDirectoryW SetCurrentDirectoryW.
These are the file management functions that no longer have MAX_PATH restrictions if you opt-in to long path behavior: CopyFileW, CopyFile2, CopyFileExW, CreateFileW, CreateFile2, CreateHardLinkW, CreateSymbolicLinkW, DeleteFileW, FindFirstFileW, FindFirstFileExW, FindNextFileW, GetFileAttributesW, GetFileAttributesExW, SetFileAttributesW, GetFullPathNameW, GetLongPathNameW, MoveFileW, MoveFileExW, MoveFileWithProgressW, ReplaceFileW, SearchPathW, FindFirstFileNameW, FindNextFileNameW, FindFirstStreamW, FindNextStreamW, GetCompressedFileSizeW, GetFinalPathNameByHandleW.
Are these used?
C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Xamarin\Android> dumpbin /imports aapt2.exe | findstr File
File Type: EXECUTABLE IMAGE
8C CreateFileMappingA
90 CreateFileMappingW
1E9 GetFileAttributesA
1EE GetFileAttributesW
1F0 GetFileInformationByHandle
1F5 GetFileSizeEx
1F7 GetFileType
216 GetModuleFileNameA
27E GetSystemTimeAsFileTime
362 MapViewOfFile
3CF ReadFile
43B SetEndOfFile
44D SetFilePointer
4BD UnmapViewOfFile
Odd is GetFileAttributesA
, which presumably has MAX_PATH
limits, but GetFileAttributesW
is also used, so when is GetFileAttributesA
used vs. GetFileAttributesW
? ¯\(ツ)/¯.
GetModuleFileNameA
is also concerning, so it would not surprise me if aapt2.exe
didn't work with long filenames even if we set the registry entry and provided an appropriate aapt2.exe.config
manifest.
This requires testing, but I suspect that there's no point in suggesting the enabling of long paths, as aapt2
won't work with them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aapt2
uses this function to convert UTF-8 file names to Windows Unicode
The android base library also has wrappers around the standard C I/O functions which add support for UTF-8 strings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This strongly implies that if we provide an appropriate aapt2.exe.config
, we can get long file name support if/when the registry setting is enabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So shall I add the aapt2.exe.config
to this PR or do a new one for that specific file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should just check if you need it? My memory in the past, I just changed the registry key and everything worked.
But I don't remember if I was hitting an issue with aapt2
or a .NET process (which would probably opt into long paths).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dellis1972: if this PR were "green" and otherwise ready to merge, I think aapt2.exe.config
could be done as a separate PR. Given that this PR isn't green and ready to merge, might as well test locally and see if that works?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, VS 2022 Preview wont even open a project/solution if the full path is greater than 260 characters even with LongPath enabled... you get a horrible dialog box.
Building with slightly fewer that 260 characters I get this build error
Error | MSB3491 | Could not write lines to file "obj\Debug\net7.0-android\android-arm64\AndroidApp1.GlobalUsings.g.cs". Could not find a part of the path 'C:\Users\dean\Documents\Visual Studio 2022\Some Projects which will have a very very very long file path because we need it to\some other folder which will put this over the limit becuase\App1\AndroidApp1\AndroidApp1\obj\Debug\net7.0-android\android-arm64\AndroidApp1.GlobalUsings.g.cs'. | AndroidApp1 | C:\Program Files\dotnet\sdk\7.0.101\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.GenerateGlobalUsings.targets
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you might have to test an "almost long path", where only aapt2 would get long path errors?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I did some more testing and it seems that aapt2
was able to switch to log paths with only the registry setting change (not aapt2.exe.config file).
I know this because the diagnostic output was putting the \\?\
stuff at the start of the filenames. So I don't think we need the config file. I will update the docs to mention the registry change though.
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
9c27457
to
cb9d1f5
Compare
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
f8073ea
to
dcad261
Compare
dcad261
to
939a741
Compare
@jonpryor This one is good to go I think. |
* main: [Xamarin.Android.Build.Tasks] Improve aapt2+file not found handling (dotnet#7644) [MSBuildDeviceIntegration] Fix duplicated test parameter (dotnet#7809)
* main: [Xamarin.Android.Build.Tasks] Improve aapt2+file not found handling (dotnet#7644) [MSBuildDeviceIntegration] Fix duplicated test parameter (dotnet#7809)
* main: [Xamarin.Android.Build.Tasks] Improve aapt2+file not found handling (dotnet#7644) [MSBuildDeviceIntegration] Fix duplicated test parameter (dotnet#7809)
* main: [build] Only build the latest API level (dotnet#7786) [Xamarin.Android.Build.Tasks] Improve aapt2+file not found handling (dotnet#7644)
* main: Add Unit Test for testOnly apps (dotnet#7637) [build] Only build the latest API level (dotnet#7786) [Xamarin.Android.Build.Tasks] Improve aapt2+file not found handling (dotnet#7644) [MSBuildDeviceIntegration] Fix duplicated test parameter (dotnet#7809)
* main: Add Unit Test for testOnly apps (dotnet#7637) [build] Only build the latest API level (dotnet#7786) [Xamarin.Android.Build.Tasks] Improve aapt2+file not found handling (dotnet#7644) [MSBuildDeviceIntegration] Fix duplicated test parameter (dotnet#7809) [tests] Bump NUnit versions to latest (dotnet#7802) [Microsoft.Android.Sdk.ILLink] target `net7.0` temporarily (dotnet#7803) [tests] `InstallAndroidDependenciesTest` can use `platform-tools` 34.0.0 (dotnet#7800) Bump to xamarin/Java.Interop/main@9e0a469 (dotnet#7797) [Xamarin.Android.Build.Tasks] FileWrites&libraryprojectimports.cache (dotnet#7780) Bump to dotnet/installer@d25a3bb 8.0.100-preview.2.23105.6 (dotnet#7769)
* main: Add Unit Test for testOnly apps (dotnet#7637) [build] Only build the latest API level (dotnet#7786) [Xamarin.Android.Build.Tasks] Improve aapt2+file not found handling (dotnet#7644) [MSBuildDeviceIntegration] Fix duplicated test parameter (dotnet#7809)
* main: Add Unit Test for testOnly apps (dotnet#7637) [build] Only build the latest API level (dotnet#7786) [Xamarin.Android.Build.Tasks] Improve aapt2+file not found handling (dotnet#7644) [MSBuildDeviceIntegration] Fix duplicated test parameter (dotnet#7809) [tests] Bump NUnit versions to latest (dotnet#7802) [Microsoft.Android.Sdk.ILLink] target `net7.0` temporarily (dotnet#7803) [tests] `InstallAndroidDependenciesTest` can use `platform-tools` 34.0.0 (dotnet#7800) Bump to xamarin/Java.Interop/main@9e0a469 (dotnet#7797) [Xamarin.Android.Build.Tasks] FileWrites&libraryprojectimports.cache (dotnet#7780) Bump to dotnet/installer@d25a3bb 8.0.100-preview.2.23105.6 (dotnet#7769) [lgtm] Fix LGTM-reported issues (dotnet#1074) [ci] Report issues in the API docs build log (dotnet#7784)
Context #7639
If a project has a long path name this can cause
aapt2
to raise aThe system cannot find the file specified
error.This is not very helpful since there is no obvious reason to the user as to WHY the build is failing. So we should do better.
So lets catch that specific error message and report a helpful, actionable message instead. In this case we will advise the
user that the path is probably too long and they should consult the documentation on how to resolve it.
As for resolutions the documentation includes a number of options so it should cover all use cases. Generally these
are
$(BaseIntermediateOutputPath)
MSbuild property to move only theobj
folder closer to the root of the drive.Most users can get away with 1. But with Maui and blazor based apps this might not solve the problem as the project itself might have a deep folder structure. So options 2. and 3. are available to cover those senarios.