【发布时间】:2022-01-23 16:56:25
【问题描述】:
我有一个 VSCode 扩展,当我运行的程序遇到断点时,它会启动 Python 调试会话。然而,Python 程序目前通过写入由扩展程序监视的文件来与扩展程序通信。
Hacky 但它可以工作,除非我打开了两个 VSCode 实例,它们会竞相开始调试。
从 VSCode 的嵌入式终端运行的程序有什么方法可以确定它在哪个 VSCode 实例中运行,以便扩展程序可以确定它是否连接到同一个实例?
【问题讨论】:
我有一个 VSCode 扩展,当我运行的程序遇到断点时,它会启动 Python 调试会话。然而,Python 程序目前通过写入由扩展程序监视的文件来与扩展程序通信。
Hacky 但它可以工作,除非我打开了两个 VSCode 实例,它们会竞相开始调试。
从 VSCode 的嵌入式终端运行的程序有什么方法可以确定它在哪个 VSCode 实例中运行,以便扩展程序可以确定它是否连接到同一个实例?
【问题讨论】:
你可以做到!官方的 Git 扩展必须为 askpass 支持做类似的事情。基本上在您的扩展程序的 activate() 函数中,您可以这样做:
export function activate(context: ExtensionContext) {
const ipcPath = getIpcPath(context);
context.environmentVariableCollection.replace("MY_EXTENSION_IPC_PATH", ipcPath);
这将在您的程序可以读取的所有集成 shell 中设置一个环境变量。我怀疑如果您的扩展程序按需激活可能会出现问题(我想它只会在您的扩展程序被激活后应用于新终端)所以您可能需要在package.json 中使用您的扩展程序的activationEvents。
要与扩展程序通信,您可以使用 IPC,但您需要一个唯一的 IPC 路径。不幸的是,ExtensionContext 中似乎没有任何唯一标识符,所以我有点像这样破解它:
let extensionInstance = 0;
function getIpcPath(context: ExtensionContext): string {
const hash = crypto.createHash("sha1");
hash.update(`${context.storageUri}${++extensionInstance}${process.pid}`);
const id = hash.digest("hex").slice(0, 10);
if (process.platform === "win32") {
return `\\\\.\\pipe\\my_extension_ipc_${id}`;
}
if (process.env["XDG_RUNTIME_DIR"] !== undefined) {
return path.join(process.env["XDG_RUNTIME_DIR"], `my_extension_ipc_${id}.sock`);
}
return path.join(os.tmpdir(), `my_extension_ipc_${id}.sock`);
}
这与 Git 扩展的功能非常相似。不太一样,但它似乎有效。
最后,我将 IPC 路径作为命令行参数传递给我的扩展程序的语言服务器,以便它可以在该地址开始侦听。
let serverOptions: ServerOptions = {
run: {
command: serverCommand,
args: ["--ipc-path", ipcPath],
},
debug: {
command: serverCommand,
args: ["--ipc-path", ipcPath, "--debug"],
},
};
似乎工作正常!
【讨论】: