vs-mcp-server
Visual Studio 2022 MCP server โ control VS via Claude Code (COM/DTE automation)
Ask AI about vs-mcp-server
Powered by Claude ยท Grounded in docs
I know everything about vs-mcp-server. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
vs-mcp-server
Visual Studio 2022๋ฅผ Claude Code(MCP)์์ ์ ์ดํ๋ ์๋ฒ. COM/DTE ์๋ํ๋ฅผ ํตํด ํ์ผ ์ด๊ธฐ, ๋น๋, ๋๋ฒ๊ฑฐ ์ ์ด, ๋ธ๋ ์ดํฌํฌ์ธํธ ๊ด๋ฆฌ ๋ฑ์ MCP ๋๊ตฌ๋ก ์ ๊ณตํ๋ค.
Windows ์ ์ฉ. COM/DTE๋ Windows์์๋ง ๋์ํ๋ค.
๋น ๋ฅธ ์์
1. ํจํค์ง ์ค์น
pip install vs-mcp-server
2. MCP ์๋ฒ ๋ฑ๋ก โ Claude Code CLI
# uvx ๋ฐฉ์ (๊ถ์ฅ, ๊ฐ์ํ๊ฒฝ ์๋ ๊ด๋ฆฌ)
claude mcp add --scope project vs -- uvx vs-mcp-server
# ๋๋ pip install ํ โ ์ง์ ์คํ ๋ฐฉ์
claude mcp add --scope project vs -- vs-mcp-server
๋ฑ๋ก ๋ฐฉ๋ฒ(์ ์ญ, Desktop, ํ๊ฒฝ๋ณ์ ๋ฑ)์ ์ค์น ๋ฐ MCP ์๋ฒ ๋ฑ๋ก ์น์ ์ ์ฐธ๊ณ ํ๋ค.
3. Visual Studio 2022 ์คํ
VS๊ฐ ์ด๋ฏธ ์คํ ์ค์ด๋ฉด ๊ฑด๋๋ด๋ค. ์คํํ์ง ์์๋ค๋ฉด vs_launch ๋๊ตฌ๋ก ์๋ ์คํํ ์ ์๋ค.
4. Claude Code์์ VS ์ฐ๊ฒฐ
vs_connect(session_id="s1", solution_path="C:/MyProject/MyProject.sln")
5. ๋๊ตฌ ์ฌ์ฉ ์์
vs_file_open(session_id="s1", path="C:/MyProject/src/main.cpp")
vs_debug_evaluate(session_id="s1", expression="myVar.Value")
์ํคํ ์ฒ
Claude Code (MCP Client)
โ stdio
โผ
server.py โโ 22๊ฐ ๋๊ตฌ ๋ฑ๋ก, ๋ผ์ฐํ
โ
session_manager.py โโ ์ธ์
โ VS ์ธ์คํด์ค ๋ฐ์ธ๋ฉ
โ
com_bridge.STAThread โโ VS ์ธ์คํด์ค 1๊ฐ๋น STA ์ ์ฉ ์ค๋ ๋
โ immediate / long_running ์ฑ๋
โผ
EnvDTE COM (devenv.exe) โโ out-of-process COM ์๋ฒ
โ ROT (Running Object Table)
โผ
Visual Studio 2022
ํต์ฌ ์ค๊ณ ์์น:
- STA ์ ์ฉ ์ค๋ ๋: EnvDTE COM์ STA(Single-Threaded Apartment)์์๋ง ์์ ์ ์ผ๋ก ๋์. VS ์ธ์คํด์ค 1๊ฐ๋น
STAThread1๊ฐ๋ฅผ ํ ๋น. - ๋์ผ ์ฑ๋:
immediate(์๋ํฐ ์กฐ์ ๋ฑ ๋น ๋ฅธ ๋ช ๋ น) /long_running(๋น๋ ๋ฑ ์ค๋ ๊ฑธ๋ฆฌ๋ ๋ช ๋ น) ์ฑ๋์ ๋ถ๋ฆฌํ์ฌ ๋น๋ ์ค์๋ ์ฆ์ ์ฑ๋ ์ฒ๋ฆฌ ๊ฐ๋ฅ. - ROT ํ์:
Running Object Table์์VisualStudio.DTE.17.0๋ชจ๋์ปค๋ฅผ ๊ฒ์ํ์ฌ ์คํ ์ค์ธ VS ์ธ์คํด์ค์ ์ฐ๊ฒฐ. - ํฌ๋์ ๋ก๊น
:
vs_debug_evaluate๊ฒฐ๊ณผ, COM ์ค๋ฅ, ํ์์์์logs/vs_mcp_crash.jsonl์ ์๋ ๊ธฐ๋ก.
์ฌ์ ์๊ตฌ์ฌํญ
| ํญ๋ชฉ | ๋ฒ์ / ์กฐ๊ฑด |
|---|---|
| OS | Windows 10 / 11 (COM/DTE๋ Windows ์ ์ฉ) |
| Python | 3.11 ์ด์ |
| Visual Studio | 2022 Community / Professional / Enterprise |
| ํจํค์ง | pywin32, mcp |
# Python ๋ฒ์ ํ์ธ
python --version
์ค์น ๋ฐ MCP ์๋ฒ ๋ฑ๋ก
Claude Code CLI์ ๋ฑ๋ก
Claude Code CLI๋ .mcp.json ํ์ผ๋ก MCP ์๋ฒ๋ฅผ ๊ด๋ฆฌํ๋ค.
๋ฐฉ๋ฒ 1 โ uvx ๋ฐฉ์ (๊ถ์ฅ)
๋ณ๋ ์ค์น ์์ด uvx๊ฐ ์๋์ผ๋ก ๊ฐ์ํ๊ฒฝ์ ๋ง๋ค์ด ์คํํ๋ค.
# ํ๋ก์ ํธ๋ณ ๋ฑ๋ก
claude mcp add --scope project vs -- uvx vs-mcp-server
# ์ ์ญ ๋ฑ๋ก
claude mcp add --scope user vs -- uvx vs-mcp-server
๋๋ .mcp.json ์ง์ ์์ฑ:
{
"mcpServers": {
"vs": {
"command": "uvx",
"args": ["vs-mcp-server"]
}
}
}
๋ฐฉ๋ฒ 2 โ pip install ํ ์ง์ ์คํ
# ์ค์น (git clone ๋ถํ์)
pip install vs-mcp-server
# ๋๋ GitHub์์ ์ง์ ์ค์น
pip install git+https://github.com/panninghour/vs-mcp-server
# ๋ฑ๋ก
claude mcp add --scope project vs -- vs-mcp-server
๋๋ ~/.claude.json(%USERPROFILE%\.claude.json)์ ์ง์ ์์ฑ:
{
"mcpServers": {
"vs": {
"command": "vs-mcp-server"
}
}
}
๋ฐฉ๋ฒ 3 โ ๊ฐ๋ฐ์์ฉ (๋ก์ปฌ ํธ์ง ๊ฐ๋ฅ ์ค์น)
์์ค๋ฅผ ์์ ํ๋ฉด์ ์ฌ์ฉํ๋ ค๋ฉด:
git clone https://github.com/panninghour/vs-mcp-server
cd vs-mcp-server
pip install -e .
claude mcp add --scope project vs -- vs-mcp-server
๋ฑ๋ก ํ์ธ
# ๋ฑ๋ก๋ MCP ์๋ฒ ๋ชฉ๋ก ํ์ธ
claude mcp list
Claude Code ์ธ์ ์์์ ์๋ฒ ์ํ์ ๋๊ตฌ ๋ชฉ๋ก์ ํ์ธํ๋ ค๋ฉด:
/mcp
vs ์๋ฒ๊ฐ ์ฐ๊ฒฐ๋จ์ผ๋ก ํ์๋๊ณ , vs_connect, vs_debug_evaluate ๋ฑ 22๊ฐ ๋๊ตฌ๊ฐ ํ์ฑํ๋์ด์ผ ํ๋ค.
Claude Desktop์ ๋ฑ๋ก
claude_desktop_config.json์ ์ด์ด mcpServers์ ์ถ๊ฐํ๋ค.
ํ์ผ ์์น (Windows):
%APPDATA%\Claude\claude_desktop_config.json
์ค์ ์์ (uvx ๋ฐฉ์):
{
"mcpServers": {
"vs": {
"command": "uvx",
"args": ["vs-mcp-server"],
"env": {
"VS_DEVENV_PATH": "C:/Program Files/Microsoft Visual Studio/2022/Professional/Common7/IDE/devenv.exe"
}
}
}
}
Claude Desktop ์ฌ์์ ํ ๋ฐ์๋๋ค.
ํ๊ฒฝ๋ณ์ ์ค์
| ํ๊ฒฝ๋ณ์ | ๊ธฐ๋ณธ๊ฐ | ์ค๋ช |
|---|---|---|
VS_DEVENV_PATH | Community ์ค์น ๊ฒฝ๋ก | devenv.exe ์ ์ฒด ๊ฒฝ๋ก. Professional/Enterprise ์ฌ์ฉ ์ ์ฌ์ ์ ํ์. |
VS_MCP_LOG_DIR | <server.py ์์น>/logs/ | ํฌ๋์ ๋ก๊ทธ ์ ์ฅ ๋๋ ํ ๋ฆฌ |
VS_MCP_LOG_LEVEL | INFO | ๋ก๊ทธ ๋ ๋ฒจ (DEBUG / INFO / WARNING) |
VS ์ค์น ๊ฒฝ๋ก ์์:
# Community (๊ธฐ๋ณธ๊ฐ)
C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\devenv.exe
# Professional
C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE\devenv.exe
# Enterprise
C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\devenv.exe
ํ๊ฒฝ๋ณ์๋ฅผ ์๊ตฌ ์ค์ ํ๋ ค๋ฉด:
[System.Environment]::SetEnvironmentVariable(
"VS_DEVENV_PATH",
"C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE\devenv.exe",
"User"
)
๋๋ .mcp.json์ env ๋ธ๋ก์ผ๋ก ์๋ฒ๋ณ ์ค์ :
"env": {
"VS_DEVENV_PATH": "C:/Program Files/Microsoft Visual Studio/2022/Professional/Common7/IDE/devenv.exe"
}
๋๊ตฌ ๋ชฉ๋ก
์ธ์คํด์ค ๊ด๋ฆฌ
| ๋๊ตฌ | ์ค๋ช |
|---|---|
vs_list_instances | ROT์์ ์คํ ์ค์ธ VS ์ธ์คํด์ค ๋ชฉ๋ก(PID, ์๋ฃจ์ ๊ฒฝ๋ก) ๋ฐํ |
vs_connect | PID ๋๋ ์๋ฃจ์ ๊ฒฝ๋ก๋ก VS ์ธ์คํด์ค์ ์ฐ๊ฒฐ, ์ธ์ ๋ฐ์ธ๋ฉ |
vs_launch | devenv.exe ์คํ ํ ROT ํด๋ง์ผ๋ก ์๋ ์ฐ๊ฒฐ |
vs_close | VS ์ธ์คํด์ค ์ข
๋ฃ (save_all ์ต์
) |
์๋ํฐ โ Claude โ ์ ์
| ๋๊ตฌ | ์ค๋ช |
|---|---|
vs_file_open | ํ์ผ์ VS ์๋ํฐ์ ์ด์ด ์ ์ ์๊ฒ ๋ณด์ฌ์ค |
vs_file_goto | ํน์ ํ์ผ์ ๋ผ์ธ/์ปฌ๋ผ์ผ๋ก ์ปค์ ์ด๋ |
vs_file_highlight | ๋ผ์ธ ๋ฒ์๋ฅผ ์ ํ ์ํ๋ก ๊ฐ์กฐ (add_bookmark ์ต์
) |
vs_file_list_open | ์ด๋ฆฐ ํ์ผ ๋ชฉ๋ก๊ณผ ์ ์ฅ ์ํ ๋ฐํ |
์๋ํฐ โ ์ ์ โ Claude
| ๋๊ตฌ | ์ค๋ช |
|---|---|
vs_file_active | ์ ์ ๊ฐ ํ์ฌ ํฌ์ปค์ค ์ค์ธ ํ์ผ ๊ฒฝ๋ก์ ์ปค์ ์์น(line/column) ๋ฐํ |
vs_file_selection | ์ ์ ๊ฐ ๋๋๊ทธ๋ก ์ ํํ ํ ์คํธ์ ๋ฒ์ ๋ฐํ |
๋น๋
| ๋๊ตฌ | ์ค๋ช |
|---|---|
vs_build_solution | ์๋ฃจ์ ์ ์ฒด ๋น๋๊ธฐ ๋น๋, ๊ฒฐ๊ณผ ๋ฐํ |
vs_build_project | ํน์ ํ๋ก์ ํธ๋ง ๋น๋ |
vs_build_status | ๋ง์ง๋ง ๋น๋ ๊ฒฐ๊ณผ ๋ฐ ํ์ฌ ๋น๋ ์ํ ์กฐํ |
vs_error_list | Build Output์์ ์๋ฌ/๊ฒฝ๊ณ ๋ฅผ ํ์ฑํ์ฌ ํ์ผ ๊ฒฝ๋กยท๋ผ์ธ ๋ฒํธ์ ํจ๊ป ๋ฐํ |
๋๋ฒ๊น
| ๋๊ตฌ | ์ค๋ช |
|---|---|
vs_debug_start | ๋๋ฒ๊น
์์ (Debugger.Go), wait_for_break ์ต์
|
vs_debug_stop | ๋๋ฒ๊น ์ข ๋ฃ, Design ๋ชจ๋๋ก ๋ณต๊ท |
vs_debug_breakpoint | ๋ธ๋ ์ดํฌํฌ์ธํธ ์ถ๊ฐ(add)/์ ๊ฑฐ(remove)/๋ชฉ๋ก ์กฐํ(list) |
vs_debug_step | ์คํ
์คํ (into / over / out) |
vs_debug_locals | Break ๋ชจ๋์์ ํ์ฌ ์คํ ํ๋ ์์ ๋ก์ปฌ ๋ณ์ ๋ฐํ |
vs_debug_evaluate | Break ๋ชจ๋์์ ํํ์ ํ๊ฐ ๋ฐ ๊ฒฐ๊ณผ ๋ฐํ |
vs_debug_callstack | ํ์ฌ ์ค๋ ๋์ ์ฝ์คํ(ํจ์๋ช /ํ์ผ/๋ผ์ธ) ๋ฐํ |
ํ ๊ด๋ฆฌ
| ๋๊ตฌ | ์ค๋ช |
|---|---|
vs_queue_status | ํ์ฌ ์คํ ์ค์ธ ๋ช ๋ น๊ณผ ๋๊ธฐ ํ ๋ชฉ๋ก ๋ฐํ |
vs_queue_cancel | ๋๊ธฐ ํ์ ๋ช
๋ น์ command_id๋ก ์ทจ์ |
vs_queue_history | ์ต๊ทผ N๊ฑด์ ๋ช ๋ น ์ด๋ ฅ(์๋ฃ/์คํจ/์ทจ์) ๋ฐํ |
DTE ๋ฒ์ฉ
| ๋๊ตฌ | ์ค๋ช |
|---|---|
vs_command | dte.ExecuteCommand()๋ก VS ๋ช
๋ น ์คํ. 6000+ ๋ช
๋ น์ ์ ๊ทผ ๊ฐ๋ฅ (Edit.FormatDocument, File.SaveAll ๋ฑ) |
์ฌ์ฉ ์์
# 1. VS ์ธ์คํด์ค ๋ชฉ๋ก ํ์ธ
vs_list_instances()
# โ [{"pid": 12345, "solution": "C:/MyProject/MyProject.sln"}]
# 2. ์ธ์
์ฐ๊ฒฐ
vs_connect(session_id="s1", solution_path="C:/MyProject/MyProject.sln")
# 3. ํ์ผ ์ด๊ธฐ + ํน์ ๋ผ์ธ์ผ๋ก ์ด๋
vs_file_open(session_id="s1", path="C:/MyProject/src/main.cpp")
vs_file_goto(session_id="s1", path="C:/MyProject/src/main.cpp", line=42)
# 4. ์ ์ ๊ฐ ์ ํํ ์ฝ๋ ์ฝ๊ธฐ
vs_file_selection(session_id="s1")
# โ {"text": "int x = foo();", "start_line": 42, "end_line": 42}
# 5. ๋น๋
vs_build_solution(session_id="s1", configuration="Debug")
# โ {"success": true, "failed_projects": 0}
# 6. ๋ธ๋ ์ดํฌํฌ์ธํธ ์ถ๊ฐ ํ ๋๋ฒ๊น
์์
vs_debug_breakpoint(session_id="s1", action="add", file="C:/MyProject/src/main.cpp", line=42)
vs_debug_start(session_id="s1", wait_for_break=False)
# 7. Break ๋ชจ๋ ์ง์
ํ ๋ณ์ ๊ฒ์ฌ
vs_debug_locals(session_id="s1")
vs_debug_evaluate(session_id="s1", expression="myObj.Value")
vs_debug_callstack(session_id="s1")
# 8. ์คํ
์คํ
vs_debug_step(session_id="s1", step_type="over")
# 9. ๋๋ฒ๊น
์ข
๋ฃ
vs_debug_stop(session_id="s1")
# 10. DTE ๋ช
๋ น ์ง์ ์คํ
vs_command(session_id="s1", command="Edit.FormatDocument")
vs_command(session_id="s1", command="File.SaveAll")
ํ ์คํธ
๋จ์ ํ ์คํธ (mock ๊ธฐ๋ฐ)
python -m pytest tests/ -v --ignore=tests/test_integration_vs.py
ํตํฉ ํ ์คํธ (์ค์ VS 2022 ํ์)
VS 2022๊ฐ ์คํ ์ค์ธ ์ํ์์:
python -m pytest tests/test_integration_vs.py -v -s
VS๊ฐ ๋ฏธ์คํ์ด๋ฉด ์๋์ผ๋ก ์คํ ํ ROT ๋ฑ๋ก์ ๋๊ธฐํ๋ค.
ํตํฉ ํ ์คํธ ํญ๋ชฉ (IT ๊ทธ๋ฃน 18๊ฐ, pytest ํจ์ 28๊ฐ):
| ๊ทธ๋ฃน | ID | ๊ฒ์ฆ ๋ด์ฉ |
|---|---|---|
| ROT ๊ฐ์ง | IT-001 | VS ์ธ์คํด์ค ๊ฐ์ง, PID ๊ฒ์ฆ, get_vs_pid() ์ ํ์ฑ, ์คํ
์ผ ํญ๋ชฉ ํํฐ๋ง |
| DTE ์์ฑ | IT-002 | MainWindow, Solution, Version COM ์์ฑ ์ ๊ทผ |
| ํ์ผ ์ด๊ธฐ | IT-003 | vs_file_open ํ ActiveDocument ๋ณ๊ฒฝ ํ์ธ |
| ํ์ผ ๋ชฉ๋ก/ํ์ฑ | IT-004 | vs_file_list_open, vs_file_active round-trip |
| ๋น๋ ์ํ | IT-005 | vs_build_status ๋ฐํ๊ฐ ๊ฒ์ฆ |
| ๋ธ๋ ์ดํฌํฌ์ธํธ | IT-006 | add / list / remove CRUD |
| ๋๋ฒ๊ฑฐ ๋ชจ๋ | IT-007 | Design ๋ชจ๋ ํ์ธ, vs_debug_stop |
| STAThread ํ | IT-008 | ์ค์ ํ ๋ฉ์ปค๋์ฆ ๋ฐ ์ด๋ ฅ ๊ธฐ๋ก ํ์ธ |
| ์ปค์ ์ด๋ | IT-009 | vs_file_goto ํ vs_file_active round-trip |
| ํ์ด๋ผ์ดํธ | IT-010 | vs_file_highlight ๋ฒ์ ์ ํ |
| ์ ํ ํ ์คํธ | IT-011 | vs_file_selection ๋ฐํ๊ฐ |
| ๋๋ฒ๊น ์ธ์ | IT-012 | ์ VS ์ธ์คํด์ค์ DebugTarget.sln ๋ก๋, Debug ๋น๋, BP ์ค์ ํ Break ๋ชจ๋ ์ง์
ํ์ธ |
| ๋๋ฒ๊น ์ธ์ | IT-013 | Break ๋ชจ๋์์ vs_debug_locals โ x=42, y=50, msg ๋ณ์ ํ์ธ |
| ๋๋ฒ๊น ์ธ์ | IT-014 | vs_debug_evaluate("x + y") == "92", msg์ "hello from debugger" ํฌํจ |
| ๋๋ฒ๊น ์ธ์ | IT-015 | vs_debug_callstack โ depth >= 1, .NET 8 CurrentStackFrame ํด๋ฐฑ ๋์ |
| ๋๋ฒ๊น ์ธ์ | IT-016 | vs_debug_step("over") ํ mode == "break", line > BP_LINE, ActiveDocument ํด๋ฐฑ ๋์ |
| ๋๋ฒ๊น ์ธ์ | IT-017 | vs_debug_stop() โ status == "stopped", mode == "design" |
| DTE ๋ฒ์ฉ | IT-018 | vs_command("Edit.LineEnd") ์คํ ํ status == "executed", ์๋ชป๋ ๋ช
๋ น ์ COM ์์ธ ์ ํ |
| Error List | IT-019 | ErrorTarget.sln ๋น๋ ํ vs_error_list โ CS0103 ์๋ฌ, CS1030 ๊ฒฝ๊ณ ํ์ฑ ํ์ธ |
์ค์
ํ๊ฒฝ๋ณ์๋ก ์กฐ์ ๊ฐ๋ฅ. ๊ฐ๋ฐ์์ฉ ์ค์น(pip install -e .)์ ๊ฒฝ์ฐ vs_mcp_server/config.py์์ ์ง์ ์์ ํ ์๋ ์๋ค.
| ์ค์ | ๊ธฐ๋ณธ๊ฐ | ์ค๋ช |
|---|---|---|
timeouts["build"] | 600์ด | ๋น๋ ์ต๋ ๋๊ธฐ ์๊ฐ |
timeouts["launch"] | 120์ด | VS ์คํ ํ ROT ๋ฑ๋ก ๋๊ธฐ |
timeouts["debug_evaluate"] | 10์ด | ํํ์ ํ๊ฐ ํ์์์ |
VS_DEVENV_PATH | Community ๊ฒฝ๋ก | devenv.exe ๊ฒฝ๋ก (ํ๊ฒฝ๋ณ์๋ก ์ฌ์ ์ ๊ฐ๋ฅ) |
QUEUE_HISTORY_MAX | 100 | ๋ช ๋ น ์ด๋ ฅ ์ต๋ ๋ณด์กด ๊ฑด์ |
์๋ ค์ง ์ ์ฝ์ฌํญ
- Windows ์ ์ฉ: COM/DTE๋ Windows์์๋ง ๋์ํ๋ค.
- VS 2022 ์ ์ฉ:
VisualStudio.DTE.17.0๋ชจ๋์ปค๋ง ์ง์ํ๋ค. - Python 3.11+: ํ์ ๋ฒ์ ์์๋ ๋์์ ๋ณด์ฅํ์ง ์๋๋ค.
- STAThread cross-apartment:
STAThread๋ด์์ DTE๋ฅผ ์ฌ์ฉํ ๋๋ ROT์์ ์ง์ DTE๋ฅผ ์ฌํ๋ํด์ผ ํ๋ค. ๋ฉ์ธ ์ค๋ ๋์ DTE ํฌ์ธํฐ๋ฅผ STAThread์ ์ ๋ฌํ๋ฉดRPC_E_WRONG_THREAD๋ฐ์. - Break ๋ชจ๋ ์ ์ฉ ๊ธฐ๋ฅ:
vs_debug_step,vs_debug_locals,vs_debug_evaluate,vs_debug_callstack์ ๋๋ฒ๊ฑฐ๊ฐ Break ๋ชจ๋์ผ ๋๋ง ๋์ํ๋ค. - .NET 8 ๊ด๋ฆฌ ์ฝ๋ ์ ํ:
CurrentThread.StackFramesCOM ์ด๊ฑฐ๊ฐ ๋น ์ปฌ๋ ์ ์ ๋ฐํํ๋ ๊ฒฝ์ฐ๊ฐ ์์.vs_debug_callstack์CurrentStackFrameํด๋ฐฑ์ผ๋ก ์ฒ๋ฆฌํ๊ณ ,vs_debug_step์ActiveDocument.Selectionํด๋ฐฑ์ผ๋ก ์ฒ๋ฆฌํ๋ค. - DTE2 ์ ๊ทผ ๋ถ๊ฐ (Python): ์๋ DTE2 ์ ์ฝ์ฌํญ ์ฐธ๊ณ .
DTE2 ์ ์ฝ์ฌํญ (Python)
๋ฌธ์
Python pywin32๋ EnvDTE80.DTE2 ์ ์ฉ ์์ฑ(ToolWindows ๋ฑ)์ ์ ๊ทผํ ์ ์๋ค. VisualStudio.DTE.17.0 ProgID๋ก ROT์์ ํ๋ํ COM ๊ฐ์ฒด์ ๊ธฐ๋ณธ IDispatch๋ EnvDTE._DTE(v7.0)์ด๋ฉฐ, ToolWindows๋ DTE2 IDispatch vtable์ DispId 300์๋ง ์กด์ฌํ๋ค.
| ์ ๊ทผ ๋ฐฉ์ | DTE2 ์บ์คํธ | ToolWindows | ErrorList |
|---|---|---|---|
| Python pywin32 | ๋ถ๋ถ์ (๋ํ) | FAIL | - |
| PowerShell 5.1/7 | FAIL | FAIL | - |
| C# .NET ์ฝ์์ฑ | SUCCESS | SUCCESS | SUCCESS |
Late-binding ๊ฒ์ฆ์์๋ InvokeMember("ToolWindows")๊ฐ DISP_E_UNKNOWNNAME (0x80020006)์ ๋ฐํํ์ฌ, IDispatch ์์ฒด์ ToolWindows๊ฐ ์์์ด ํ์ธ๋์๋ค. C#๋ง์ด (DTE2)dte ์บ์คํธ ์ COM QueryInterface๋ฅผ ํตํด DTE2 vtable์ ์ง์ ํ๋ํ๋ค.
์๋ํ ์ ๊ทผ๋ฒ
- Python
win32com.client.Dispatch: gen_py ์บ์ ์ ๋ฌด์ ๊ด๊ณ์์ด DTE2 ์์ฑ ์ ๊ทผ ๋ถ๊ฐ - Python
win32com.client.dynamic.Dispatch: late-bound ๊ฐ์ โDISP_E_UNKNOWNNAME(IDispatch์ ์์) - Python
_oleobj_.GetIDsOfNames("ToolWindows"): ๋์ผํ๊ฒDISP_E_UNKNOWNNAME - C# ๋ธ๋ฆฟ์ง (subprocess): DTE2 ์บ์คํธ ์ฑ๊ณต,
ToolWindows.ErrorList์ ๊ทผ ๊ฐ๋ฅ. ๊ทธ๋ฌ๋ErrorList.ErrorItems๊ฐ ์ธ๋ถ COM ํ๋ก์ธ์ค์์ ํญ์ ๋น ์ปฌ๋ ์ ๋ฐํ โ Build Output ํ์ฑ์ผ๋ก ์ฐํ ํ์
ํ์ฌ ํด๊ฒฐ ๋ฐฉ๋ฒ
vs_error_list๋ DTE1์์ ์ ๊ทผ ๊ฐ๋ฅํ OutputWindow์ Build pane ํ
์คํธ๋ฅผ ํ์ฑํ์ฌ ์๋ฌ/๊ฒฝ๊ณ ๋ฅผ ๋ฐํํ๋ค:
# DTE1์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅ (ToolWindows ๋ถํ์)
ow = dte.Windows.Item("{34E76E81-EE4A-11D0-AE2E-00A0C90FFFC3}").Object
pane = ow.OutputWindowPanes.Item("Build")
text = pane.TextDocument.StartPoint.CreateEditPoint().GetText(pane.TextDocument.EndPoint)
# โ MSBuild ์ถ๋ ฅ ํ์ ์ ๊ท์ ํ์ฑ
์ด ๋ฐฉ์์ C# ๋ธ๋ฆฟ์ง๋ ์ถ๊ฐ ๋ฐํ์ ์์ด ์์ Python์ผ๋ก ๋์ํ๋ค.
DTE ์ง์ ์ ๊ทผ (Advanced)
MCP ์๋ฒ๋ฅผ ๊ฑฐ์น์ง ์๊ณ ์ธ๋ถ Python ์คํฌ๋ฆฝํธ์์ ์ง์ DTE COM ๊ฐ์ฒด์ ์ ๊ทผํ ์ ์๋ค. VS ์ธ์คํด์ค๋ Windows ROT(Running Object Table)์ VisualStudio.DTE.17.0 ๋ชจ๋์ปค๋ก ๋ฑ๋ก๋์ด ์๋ค.
๋จ์ผ VS ์ธ์คํด์ค
import pythoncom
import win32com.client
pythoncom.CoInitialize()
dte = win32com.client.GetActiveObject("VisualStudio.DTE.17.0")
# ์์: ์๋ฃจ์
๊ฒฝ๋ก ์ถ๋ ฅ
print(dte.Solution.FullName)
์ฃผ์:
GetActiveObject๋ VS ์ธ์คํด์ค๊ฐ ์ฌ๋ฌ ๊ฐ ์คํ ์ค์ผ ๋ ์ด๋ ์ธ์คํด์ค๋ฅผ ๋ฐํํ ์ง ๋ณด์ฅํ์ง ์๋๋ค. ๋จ์ผ ์ธ์คํด์ค ํ๊ฒฝ์์๋ง ์ฌ์ฉํ ๊ฒ.
๋ณต์ VS ์ธ์คํด์ค โ PID๋ก ํน์ ์ธ์คํด์ค ์ ํ
vs_list_instances ๋๊ตฌ๋ก PID๋ฅผ ํ์ธํ ๋ค, ROT์์ ํด๋น PID์ ์ธ์คํด์ค๋ฅผ ์ง์ ํ๋ํ๋ค.
import pythoncom
import win32com.client
from vs_mcp_server.utils.rot import find_vs_instances, get_vs_pid
pythoncom.CoInitialize()
target_pid = 12345 # vs_list_instances ๋๋ vs_connect ์๋ต์ instance_pid
entries = find_vs_instances()
dte = next(
e["dte"] for e in entries
if get_vs_pid(e["dte"]) == target_pid
)
# ์ดํ dte ๊ฐ์ฒด๋ฅผ ์์ ๋กญ๊ฒ ์ฌ์ฉ
print(dte.Solution.FullName)
์ฐธ๊ณ :
find_vs_instances()๋ ROT๋ฅผ ์ํํ์ฌ ๋ชจ๋VisualStudio.DTE.17.0ํญ๋ชฉ์ ๋ฐํํ๋ค.get_vs_pid(dte)๋ DTE์MainWindow.HWnd์์ PID๋ฅผ ์ถ์ถํ๋ค.
