-
Notifications
You must be signed in to change notification settings - Fork 60
Visual Studio Extensibility: Setting.StringArray causes IDE to hang when expanding settings category #552
Description
Visual Studio Extensibility: Setting.StringArray causes IDE to hang when expanding settings category
问题描述 | Problem Description
中文
在 Visual Studio Extensibility 扩展开发中,使用 Setting.StringArray 类型定义设置时,当用户尝试在 工具 > 选项 中展开包含 Setting.StringArray 的设置类别时,Visual Studio 会完全卡死并最终崩溃重启。
English
When using Setting.StringArray type to define settings in Visual Studio Extensibility extension development, Visual Studio completely hangs and eventually crashes with a restart when users try to expand a settings category containing Setting.StringArray in Tools > Options.
复现步骤 | Reproduction Steps
步骤 1: 创建测试扩展 | Step 1: Create test extension
Create a minimal extension with Setting.StringArray:
[VisualStudioContribution]
internal static Setting.StringArray TestStringArray { get; } = new(
"testStringArray",
"Test String Array",
TestCategory,
defaultValue: new[] {
"item1",
"item2",
"item3",
"item4",
"item5",
}) {
Description = "A test setting of type StringArray",
};步骤 2: 调试扩展 | Step 2: Debug the extension
- Open the extension project in Visual Studio
- Press F5 to start debugging
- Open Tools > Options in the experimental instance
- Navigate to the extension's settings category
- Try to expand the category
步骤 3: 观察卡死 | Step 3: Observe the hang
- Visual Studio becomes completely unresponsive
- UI freezes
- After ~30 seconds, the process is terminated and restarts
环境信息 | Environment Information
- Visual Studio Version: Visual Studio Community 2022 (Version 18.x)
- .NET SDK: .NET 8.0
- VisualStudio.Extensibility.Sdk Version: 17.14.40608
- OS: Windows
dotnet --list-sdks
# 10.0.102 [C:\Program Files\dotnet\sdk]问题分析 | Problem Analysis
测试项目 | Test Project
已创建一个最小化的测试项目来隔离问题:
A minimal test project has been created to isolate the issue:
项目结构 | Project Structure:
StringArrayTestExtension/
├── StringArrayTestExtension.csproj
├── Extension/
│ ├── ExtensionEntrypoint.cs
│ ├── Commands/
│ │ └── TestCommand.cs
│ └── Settings/
│ └── TestSettings.cs # Contains Setting.StringArray
└── .vsextension/
└── string-resources.json
测试结果 | Test Results
| 设置类型 | Setting Type | 结果 | Result |
|---|---|---|---|
Setting.Boolean |
✅ 正常 | Works normally | |
Setting.String |
✅ 正常 | Works normally | |
Setting.StringArray |
❌ 卡死 | Hangs |
官方文档对比 | Official Documentation Comparison
文档中支持的设置类型 | Supported setting types in documentation
根据 settings.md:
- `Setting.Boolean`
- `Setting.Decimal`
- `Setting.Enum` ✅ (有示例)
- `Setting.FormattedString`
- `Setting.Integer`
- `Setting.String`
- `Setting.EnumArray`
- `Setting.FormattedStringArray`
- `Setting.StringArray` ⚠️ (无示例)
- `Setting.ObjectArray`问题 | Issue
Setting.Enum有官方示例,使用 C# 12 集合表达式语法[...],工作正常Setting.Enumhas official examples using C# 12 collection expression syntax[...], works fine- Setting.StringArray 没有任何使用示例,可能是一个不稳定的实验性功能
- Setting.StringArray has no usage examples, may be an unstable experimental feature
请求 | Request
-
确认问题 | Confirm the issue
- 请确认
Setting.StringArray是否是实验性功能 - Please confirm if
Setting.StringArrayis an experimental feature
- 请确认
-
提供文档示例 | Provide documentation examples
- 如果
Setting.StringArray是稳定的,请提供使用示例 - If
Setting.StringArrayis stable, please provide usage examples
- 如果
-
修复 bug | Fix the bug
- 如果是 bug,请修复
Setting.StringArray的实现 - If it's a bug, please fix the
Setting.StringArrayimplementation
- 如果是 bug,请修复
-
或者确认不支持 | Or confirm it's not supported
- 如果不支持,请从文档中移除或在 API 文档中标记为已弃用
- If not supported, please remove from documentation or mark as deprecated in API docs
附加文件:测试项目关键代码 | Appendix: Critical Test Project Code
1. 项目文件 | Project File (StringArrayTestExtension.csproj)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>StringArrayTestExtension</RootNamespace>
<NoWarn>$(NoWarn);VSEXTPREVIEW_SETTINGS;VSTHRD103</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Extensibility.Sdk" Version="17.14.40608" PrivateAssets="all" Aliases="VSExtensibility" />
<PackageReference Include="Microsoft.VisualStudio.Extensibility.Build" Version="17.14.40608" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<Content Include=".vsextension\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>2. 设置代码 | Settings Code (TestSettings.cs)
文件路径 | File Path: StringArrayTestExtension\Extension\Settings\TestSettings.cs
#pragma warning disable VSEXTPREVIEW_SETTINGS
using Microsoft.VisualStudio.Extensibility;
using Microsoft.VisualStudio.Extensibility.Settings;
using System.Diagnostics;
using System.IO;
using System.Threading;
namespace StringArrayTestExtension.Settings {
internal static partial class TestSettings {
[VisualStudioContribution]
internal static SettingCategory TestCategory { get; } = new("testCategory", "%StringArrayTestExtension.Settings.Category.Test.DisplayName%") {
Description = "%StringArrayTestExtension.Settings.Category.Test.Description%",
GenerateObserverClass = true,
};
[VisualStudioContribution]
internal static Setting.StringArray TestStringArray { get; } = new(
"testStringArray",
"%StringArrayTestExtension.Settings.TestStringArray.DisplayName%",
TestCategory,
defaultValue: new[] {
"item1",
"item2",
"item3",
"item4",
"item5",
}) {
Description = "%StringArrayTestExtension.Settings.TestStringArray.Description%",
};
[VisualStudioContribution]
internal static Setting.Boolean TestBoolean { get; } = new(
"testBoolean",
"%StringArrayTestExtension.Settings.TestBoolean.DisplayName%",
TestCategory,
defaultValue: true) {
Description = "%StringArrayTestExtension.Settings.TestBoolean.Description%",
};
[VisualStudioContribution]
internal static Setting.String TestString { get; } = new(
"testString",
"%StringArrayTestExtension.Settings.TestString.DisplayName%",
TestCategory,
defaultValue: "test value") {
Description = "%StringArrayTestExtension.Settings.TestString.Description%",
};
// 静态构造函数用于记录初始化
static TestSettings() {
var logPath = Path.Combine(Path.GetTempPath(), "StringArrayTestExtension.log");
try {
File.AppendAllText(logPath, $"[{DateTime.Now:HH:mm:ss.fff}] TestSettings static constructor called{Environment.NewLine}");
File.AppendAllText(logPath, $"[{DateTime.Now:HH:mm:ss.fff}] TestStringArray default value length: {TestStringArray?.GetType()?.GetProperty("DefaultValue")?.GetValue(TestStringArray) as string[]?.Length ?? -1}{Environment.NewLine}");
}
catch (Exception ex) {
File.AppendAllText(logPath, $"[{DateTime.Now:HH:mm:ss.fff}] Error: {ex.Message}{Environment.NewLine}");
}
}
}
}3. 关键观察 | Key Observations
- ✅
Setting.Boolean和Setting.String工作正常 - ✅
Setting.BooleanandSetting.Stringwork normally - ❌ 只有
Setting.StringArray导致卡死 - ❌ Only
Setting.StringArraycauses hang ⚠️ 使用 C# 集合表达式语法new[] { ... }⚠️ Using C# collection expression syntaxnew[] { ... }
4. 测试项目完整结构 | Complete Test Project Structure
StringArrayTestExtension/
├── StringArrayTestExtension.csproj # SDK 版本: 17.14.40608
├── Extension/
│ ├── ExtensionEntrypoint.cs # 扩展入口点
│ ├── Commands/
│ │ └── TestCommand.cs # 测试命令
│ └── Settings/
│ └── TestSettings.cs # 设置定义 (包含问题代码)
├── .vsextension/
│ ├── vsixmanifest.json
│ └── string-resources.json # 本地化资源
└── GitHubIssue_SettingStringArray_Hang.md # 此 Issue 文档