mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 14:23:28 +07:00
Fix RIDER-123585: detect VS on Windows
(cherry picked from commit 44eac219488fe51de076b8907f2956d9442211fa) GitOrigin-RevId: 51c0ef9644fe5016f6c28d3c6081c6bf7793ed2b
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d85b962378
commit
9479c974fa
@@ -31,5 +31,6 @@
|
||||
<orderEntry type="library" name="gson" level="project" />
|
||||
<orderEntry type="library" name="kotlinx-serialization-core" level="project" />
|
||||
<orderEntry type="library" name="kotlin-reflect" level="project" />
|
||||
<orderEntry type="library" name="jna" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.internal.statistic.collectors.fus.environment
|
||||
|
||||
import com.intellij.internal.statistic.beans.MetricEvent
|
||||
@@ -17,9 +17,10 @@ private const val CURSOR_ID = ".cursor"
|
||||
private const val WINDSURF_ID = ".windsurf"
|
||||
private const val ECLIPSE_ID = ".eclipse"
|
||||
private const val ZED_ID = ".zed"
|
||||
private const val VISUAL_STUDIO_ID = "VisualStudio"
|
||||
|
||||
internal class EditorsCollector : ApplicationUsagesCollector() {
|
||||
private val EDITORS_GROUP: EventLogGroup = EventLogGroup("editors", 4)
|
||||
private val EDITORS_GROUP: EventLogGroup = EventLogGroup("editors", 5)
|
||||
|
||||
override fun getGroup(): EventLogGroup = EDITORS_GROUP
|
||||
|
||||
@@ -46,6 +47,11 @@ internal class EditorsCollector : ApplicationUsagesCollector() {
|
||||
EventFields.StringList("extension_ids", emptyList())
|
||||
)
|
||||
|
||||
private val VISUAL_STUDIO_VERSIONS_INSTALLED: EventId1<List<String>> = EDITORS_GROUP.registerEvent(
|
||||
"visual.studio.versions.installed",
|
||||
EventFields.StringList("versions", emptyList())
|
||||
)
|
||||
|
||||
override suspend fun getMetricsAsync(): Set<MetricEvent> {
|
||||
val homeDir = System.getProperty("user.home")
|
||||
return withContext(Dispatchers.IO) {
|
||||
@@ -87,6 +93,12 @@ internal class EditorsCollector : ApplicationUsagesCollector() {
|
||||
if (zedCollectionDataProvider.isZedDetected()) {
|
||||
add(CONFIG_EXISTS.metric(ZED_ID))
|
||||
}
|
||||
|
||||
val vsVersions = VisualStudioCollectionDataProvider().getInstalledVersions()
|
||||
if (vsVersions.any()) {
|
||||
add(CONFIG_EXISTS.metric(VISUAL_STUDIO_ID))
|
||||
VISUAL_STUDIO_VERSIONS_INSTALLED.metric(vsVersions)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.internal.statistic.collectors.fus.environment
|
||||
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.diagnostic.runAndLogException
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.sun.jna.platform.win32.Advapi32Util
|
||||
import com.sun.jna.platform.win32.WinReg
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlin.io.path.Path
|
||||
import kotlin.io.path.listDirectoryEntries
|
||||
import kotlin.io.path.name
|
||||
|
||||
private val logger = logger<VisualStudioCollectionDataProvider>()
|
||||
|
||||
/**
|
||||
* Collects anonymous data about the presense of Visual Studio to improve the "Import settings from external editor" feature and prioritize
|
||||
* support for popular editors.
|
||||
*
|
||||
* This includes:
|
||||
* - detecting if Visual Studio is installed on Windows via %LOCALAPPDATA%,
|
||||
* - detecting if Visual Studio is installed on Windows via registry (legacy detection).
|
||||
*
|
||||
* The data is completely anonymized and no personally identifiable information is captured.
|
||||
*/
|
||||
internal class VisualStudioCollectionDataProvider : ExternalEditorCollectionDataProvider() {
|
||||
|
||||
suspend fun getInstalledVersions(): List<String> {
|
||||
if (!SystemInfo.isWindows) return emptyList()
|
||||
return (readVersionsFromAppData() + readVersionsFromRegistry()).distinct().sorted().toList()
|
||||
}
|
||||
|
||||
private data class VsVersion(val major: Int, val minor: Int, val instanceId: String?) {
|
||||
override fun toString(): String {
|
||||
return "$major.$minor"
|
||||
}
|
||||
}
|
||||
// Example: "15.0_a0848a47Exp", where VS version = "15.0", Instance Id = "a0848a47", Root Suffix = "Exp".
|
||||
private val vsVersionWithHiveRegex = Regex("\\b([0-9]{1,2})\\.([0-9]{1,2})(?:_([a-fA-F0-9]{8}))?[a-zA-Z0-9]*\\b")
|
||||
private fun matchVersion(hive: String): VsVersion? {
|
||||
val match = vsVersionWithHiveRegex.find(hive) ?: return null
|
||||
return VsVersion(
|
||||
major = match.groupValues[1].toIntOrNull() ?: return null,
|
||||
minor = match.groupValues[2].toIntOrNull() ?: return null,
|
||||
instanceId = match.groupValues.elementAtOrNull(3)
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun readVersionsFromAppData(): Sequence<String> =
|
||||
withContext(Dispatchers.IO) {
|
||||
logger.runAndLogException {
|
||||
val appData = System.getenv("LOCALAPPDATA") ?: return@withContext emptySequence()
|
||||
val visualStudioHomeDir = Path(appData, "Microsoft", "VisualStudio")
|
||||
visualStudioHomeDir.listDirectoryEntries().asSequence()
|
||||
.mapNotNull { matchVersion(it.name) }
|
||||
.filter { it.instanceId?.length == 8 }
|
||||
.map { it.toString() }
|
||||
} ?: emptySequence()
|
||||
}
|
||||
|
||||
private fun readVersionsFromRegistry(): Sequence<String> = logger.runAndLogException {
|
||||
val registry = Advapi32Util.registryGetKeys(WinReg.HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\VisualStudio")
|
||||
registry.asSequence()
|
||||
.mapNotNull { matchVersion(it) }
|
||||
.filter { it.major == 11 || it.major == 12 || it.major == 14 }
|
||||
.map { it.toString() }
|
||||
} ?: emptySequence()
|
||||
}
|
||||
Reference in New Issue
Block a user