diff --git a/packages/cli-doctor/src/tools/healthchecks/__tests__/androidStudio.test.ts b/packages/cli-doctor/src/tools/healthchecks/__tests__/androidStudio.test.ts index 801a44a42..e3fb99368 100644 --- a/packages/cli-doctor/src/tools/healthchecks/__tests__/androidStudio.test.ts +++ b/packages/cli-doctor/src/tools/healthchecks/__tests__/androidStudio.test.ts @@ -74,4 +74,45 @@ describe('androidStudio', () => { }".`, ); }); + + it('detects Android Studio in the fallback Windows installation path', async () => { + // Make CLI think Android Studio was not found + environmentInfo.IDEs['Android Studio'] = 'Not Found'; + // Force the platform to win32 for the test + const platformSpy = jest + .spyOn(process, 'platform', 'get') + .mockReturnValue('win32'); + + // First WMIC (primary) returns empty, second (fallback) returns version + (execa as jest.Mock) + .mockResolvedValueOnce({stdout: ''}) + .mockResolvedValueOnce({stdout: '4.2.1.0'}); + + const diagnostics = await androidStudio.getDiagnostics(environmentInfo); + + expect(diagnostics.needsToBeFixed).toBe(false); + expect(diagnostics.version).toBe('4.2.1.0'); + + platformSpy.mockRestore(); + }); + + it('detects when Android Studio is also not in fallback installation path', async () => { + // Make CLI think Android Studio was not found + environmentInfo.IDEs['Android Studio'] = 'Not Found'; + // Force the platform to win32 for the test + const platformSpy = jest + .spyOn(process, 'platform', 'get') + .mockReturnValue('win32'); + + // First WMIC (primary) returns empty, second (fallback) returns version + (execa as jest.Mock) + .mockResolvedValueOnce({stdout: ''}) + .mockResolvedValueOnce({stdout: ''}); + + const diagnostics = await androidStudio.getDiagnostics(environmentInfo); + + expect(diagnostics.needsToBeFixed).toBe(true); + + platformSpy.mockRestore(); + }); }); diff --git a/packages/cli-doctor/src/tools/healthchecks/androidStudio.ts b/packages/cli-doctor/src/tools/healthchecks/androidStudio.ts index 0e174c062..51bb5336c 100644 --- a/packages/cli-doctor/src/tools/healthchecks/androidStudio.ts +++ b/packages/cli-doctor/src/tools/healthchecks/androidStudio.ts @@ -24,16 +24,43 @@ export default { if (needsToBeFixed && process.platform === 'win32') { const archSuffix = process.arch === 'x64' ? '64' : ''; - const androidStudioPath = join( + // Check if Android Studio is installed in one of its default locations + const primaryAndroidStudioPath = join( getUserAndroidPath(), 'android-studio', 'bin', `studio${archSuffix}.exe`, ).replace(/\\/g, '\\\\'); const {stdout} = await executeCommand( - `wmic datafile where name="${androidStudioPath}" get Version`, + `wmic datafile where name="${primaryAndroidStudioPath}" get Version`, ); - const version = stdout.replace(/(\r\n|\n|\r)/gm, '').trim(); + let version = stdout.replace(/(\r\n|\n|\r)/gm, '').trim(); + + if (version !== '') { + return { + needsToBeFixed: false, + version, + }; + } + + // 2) fallback path under %LOCALAPPDATA%\Programs\Android Studio + // This is the path used by the JetBrains Toolbox / Android Studio installer + const altBase = process.env.LOCALAPPDATA || ''; + const fallbackPath = join( + altBase, + 'Programs', + 'Android Studio', + 'bin', + `studio${archSuffix}.exe`, + ).replace(/\\/g, '\\\\'); + try { + const {stdout} = await executeCommand( + `wmic datafile where name="${fallbackPath}" get Version`, + ); + version = stdout.replace(/(\r\n|\n|\r)/gm, '').trim(); + } catch { + version = ''; + } if (version === '') { return missing;