基于c++的vscodec++环境自动部署

328 阅读6分钟

自动配置VSCode C++环境的工具:豆包Marscode使用体验

项目简介

我开发了一个可以自动配置VSCode C++环境的工具,这个工具是用豆包Marscode的工具编写的。通过这个工具,用户可以轻松地在VSCode中搭建起一个完整的C++开发环境,无需手动配置复杂的编译、调试和IntelliSense设置。

MarsCode是什么?

MarsCode对话框官方回答:MarsCode是一个在线的集成开发环境(IDE),它专注于提供一个高效、便捷的编程环境,特别是在教育领域。MarsCode支持多种编程语言,包括Python、Java、C++等,并且提供了实时的代码编辑、调试和运行功能。

MarsCode的特点包括:

  1. 实时协作:支持多人实时协作编程,适用于团队项目或教学场景。
  2. 代码自动补全:提供智能的代码自动补全功能,帮助开发者提高编码效率。
  3. 语法高亮:支持多种编程语言的语法高亮,使代码更加易读。
  4. 调试工具:内置调试工具,方便开发者进行代码调试。
  5. 版本控制:集成了Git版本控制系统,方便管理代码版本。
  6. 云端存储:所有代码和项目都存储在云端,用户可以随时随地访问和编辑。

MarsCode的目标是为开发者和学习者提供一个简单、易用且功能强大的编程环境,帮助他们更高效地编写代码。

为什么要写这个程序

相信不少新手都被安装环境这一步卡了很久,本程序旨在解决广大新手的烦恼。

自动化配置,省时省力

在使用这个工具之前,每次配置一个新的VSCode C++项目都需要花费大量时间进行环境搭建。而现在,只需运行这个工具,几分钟内即可完成所有配置,大大节省了时间和精力。

一键生成,简单易用

工具的界面简洁明了,用户只需按照提示选择需要的编译器和构建系统,然后点击“一键生成”按钮,即可自动生成所需的配置文件。即使是初学者也能轻松上手,无需了解复杂的VSCode配置细节。

兼容性差,仅支持1种编译器

工具目前仅支持MINGW编译器,其他编译器我们会在后续跟进

持续更新,紧跟VSCode发展

随着VSCode的不断更新,C++插件的配置方式也可能发生变化。我们会根据情况兼容最新的VSCode版本。

编写过程

  1. 首先我向豆包提问,要想达到这个目的需要做什么

屏幕截图 2024-12-10 200101.png

屏幕截图 2024-12-10 200748.png 豆包解答了我的疑惑,由于在在线ide部署qt环境难度过大,所以接下来的过程皆为在线生成代码,本地测试 2.而后我向豆包描述了我的要求

屏幕截图 2024-12-10 201746.png 3.这给予了我一个框架,随后我把框架置于本地,在ai的建议下又完善了许多功能

屏幕截图 2024-12-10 202043.png 4.最后大功告成,附上源码

#include "SetupManager.h"
#include <QMessageBox>
#include <QFile>
#include <QDir>
#include <QSettings>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <iostream>
#include <locale>

SetupManager::SetupManager(QObject *parent) : QObject(parent)
{
    connect(&manager, &QNetworkAccessManager::finished, this, &SetupManager::onDownloadFinished);
    connect(&process, &QProcess::finished, this, &SetupManager::onProcessFinished);
}

void SetupManager::startSetup()
{
    if (!requestAdminRights()) {
        std::cerr << "Error: This application requires administrator privileges." << std::endl;
        return;
    }
    // 先在桌面创建 vscode 文件夹,再在其内部创建.vscode 文件夹
    createVSCodeFolders();
    // Output the prompt message that MinGW download is starting to the command line
    std::cout << "Current step: Start downloading MinGW" << std::endl;
    downloadMinGW();
}

bool SetupManager::requestAdminRights()
{
    process.start("net session");
    process.waitForFinished();
    return process.exitCode() == 0;
}

// 函数用于创建桌面的 vscode 文件夹以及其内部的.vscode 文件夹
void SetupManager::createVSCodeFolders()
{
    QDir desktopDir = QDir::home();
    desktopDir.cd("Desktop");
    if (!desktopDir.exists("vscode")) {
        desktopDir.mkdir("vscode");
    }
    QDir vscodeDir(desktopDir.absoluteFilePath("vscode"));
    if (!vscodeDir.exists(".vscode")) {
        vscodeDir.mkpath(".vscode");
    }
}

void SetupManager::downloadMinGW()
{
    QUrl url("https://nchc.dl.sourceforge.net/project/mingw/Installer/mingw-get-setup.exe?viasf=1");
    manager.get(QNetworkRequest(url));
}

void SetupManager::onDownloadFinished(QNetworkReply *reply)
{
    if (reply->error()) {
        std::cerr << "Download error: " << reply->errorString().toStdString() << std::endl;
        return;
    }
    QFile file("mingw-get-setup.exe");
    if (file.open(QIODevice::WriteOnly)) {
        file.write(reply->readAll());
        file.close();
        // Output the prompt message that MinGW download is completed and extraction and configuration are starting to the command line
        std::cout << "Current step: MinGW download completed, start extracting and configuring" << std::endl;
        extractAndConfigureMinGW();
    }
}

void SetupManager::extractAndConfigureMinGW()
{
    // Output the prompt message that MinGW is being extracted and configured to the command line
    std::cout << "Current step: Extracting and configuring MinGW" << std::endl;
    process.start("mingw-get-setup.exe", QStringList() << "/S");
    process.waitForFinished();
    QSettings settings("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", QSettings::NativeFormat);
    QString path = settings.value("Path", "").toString();
    path += ";C:\\MinGW\\bin";
    settings.setValue("Path", path);
    // Output the prompt message that MinGW configuration is completed and VSCode download is starting to the command line
    std::cout << "Current step: MinGW configuration completed, start downloading VSCode" << std::endl;
    downloadVSCode();
}

void SetupManager::downloadVSCode()
{
    // Output the prompt message that VSCode download is starting to the command line
    std::cout << "Current step: Start downloading VSCode" << std::endl;
    QUrl url("https://update.code.visualstudio.com/latest/win32-x64-user/stable");
    QNetworkRequest request(url);
    QNetworkReply *reply = manager.get(request);
    // Use lambda expression to connect the signal and slot
    connect(reply, &QNetworkReply::finished, [this, reply]() {
        if (reply->error()) {
            std::cerr << "Download error: " << reply->errorString().toStdString() << std::endl;
            return;
        }
        QFile file("VSCodeSetup.exe");
        if (file.open(QIODevice::WriteOnly)) {
            file.write(reply->readAll());
            file.close();
            // Output the prompt message that VSCode download is completed and installation is starting to the command line
            std::cout << "Current step: VSCode download completed, start installing" << std::endl;
            installVSCode();
        }
    });
}

void SetupManager::onVSCodeDownloadFinished(QNetworkReply *reply)
{
    if (reply->error()) {
        std::cerr << "Download error: " << reply->errorString().toStdString() << std::endl;
        return;
    }
    QFile file("VSCodeSetup.exe");
    if (file.open(QIODevice::WriteOnly)) {
        file.write(reply->readAll());
        file.close();
        installVSCode();
    }
}

void SetupManager::installVSCode()
{
    // Output the prompt message that VSCode is being installed to the command line
    std::cout << "Current step: Installing VSCode" << std::endl;
    process.start("VSCodeSetup.exe", QStringList() << "/S");
    process.waitForFinished();
    // Output the prompt message that VSCode installation is completed and configuration is starting to the command line
    std::cout << "Current step: VSCode installation completed, start configuring" << std::endl;
    configureVSCode();
}

void SetupManager::configureVSCode()
{
    // Output the prompt message that VSCode is being configured to the command line
    std::cout << "Current step: Configuring VSCode" << std::endl;
    process.start("code", QStringList() << "--install-extension" << "ms-vscode.cpptools");
    process.waitForFinished();

    // 写入 settings.json 文件配置内容
    writeSettingsJsonConfig();

    // 写入 tasks.json 文件配置内容
    writeTasksJsonConfig();

    // 写入 launch.json 文件配置内容
    writeLaunchJsonConfig();

    // 写入 c_cpp_properties.json 文件配置内容
    writeCppPropertiesJsonConfig();

    // 配置完成后清理临时文件
    cleanTempFiles();

    // 配置完成后输出提示信息给用户
    std::cout << "Your desktop will have a 'vscode' folder. Please open this folder in VSCode and create your first project in the top-level directory." << std::endl;

    // Output the prompt message that all configurations are completed to the command line
    std::cout << "Current step: All configurations completed, setup is finished" << std::endl;
    std::cout << "Setup Complete: You can now use VSCode for C++ development." << std::endl;
}

// 用于写入 c_cpp_properties.json 配置内容的函数,按照之前要求的配置内容设置
void SetupManager::writeCppPropertiesJsonConfig()
{
    QDir vscodeDir(QDir::home().absoluteFilePath("Desktop/vscode/.vscode"));
    QFile file(vscodeDir.absoluteFilePath("c_cpp_properties.json"));
    if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QString config = R"({
    "configurations": [
      {
        "name": "Win64",
        "includePath": ["${workspaceFolder}/**"],
        "defines": ["_DEBUG", "UNICODE", "_UNICODE"],
        "windowsSdkVersion": "10.0.18362.0",
        "compilerPath": "C:/MinGW/bin/g++.exe",
        "cStandard": "c17",
        "cppStandard": "c++17",
        "intelliSenseMode": "gcc-x64"
      }
    ],
    "version": 4
  })";
        file.write(config.toUtf8());
        file.close();
    }
}

// 用于写入 settings.json 配置内容的函数,仅为示意,实际需完善逻辑,比如创建文件夹、处理文件写入错误等情况
void SetupManager::writeSettingsJsonConfig()
{
    QDir vscodeDir(QDir::home().absoluteFilePath("Desktop/vscode/.vscode"));
    QFile file(vscodeDir.absoluteFilePath("settings.json"));
    if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QString config = R"({
    "files.defaultLanguage": "c",
    "editor.formatOnType": true,
    "editor.suggest.snippetsPreventQuickSuggestions": false,
    "editor.acceptSuggestionOnEnter": "off",
    "code-runner.runInTerminal": true,
    "code-runner.executorMap": {
        "c": "gcc '$fileName' -o '$fileNameWithoutExt.exe' -Wall -O2 -m64 -lm -static-libgcc -fexec-charset=GBK -D__USE_MINGW_ANSI_STDIO && &'./$fileNameWithoutExt.exe'",
        "cpp": "g++ '$fileName' -o '$fileNameWithoutExt.exe' -Wall -O2 -m64 -static-libgcc -fexec-charset=GBK && &'./$fileNameWithoutExt.exe'"
    },
    "code-runner.saveFileBeforeRun": true,
    "code-runner.preserveFocus": true,
    "code-runner.clearPreviousOutput": false,
    "code-runner.ignoreSelection": true,
    "code-runner.fileDirectoryAsCwd": true,
    "C_Cpp.clang_format_sortIncludes": true
})";
        file.write(config.toUtf8());
        file.close();
    }
}

// 用于写入 tasks.json 配置内容的函数,仅为示意,实际需完善逻辑,比如创建文件夹、处理文件写入错误等情况
void SetupManager::writeTasksJsonConfig()
{
    QDir vscodeDir(QDir::home().absoluteFilePath("Desktop/vscode/.vscode"));
    QFile file(vscodeDir.absoluteFilePath("tasks.json"));
    if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QString config = R"({
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++.exe 生成活动文件",
            "command": "g++.exe",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                "-static-libgcc",
                "-o",
                "${fileDirname}\\debug\\${fileBasenameNoExtension}.exe",
                "-fexec-charset=GBK"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "调试器生成的任务。"
        }
    ],
    "version": "2.0.0"
})";
        file.write(config.toUtf8());
        file.close();
    }
}

// 用于写入 launch.json 配置内容的函数,仅为示意,实际需完善逻辑,比如创建文件夹、处理文件写入错误等情况
void SetupManager::writeLaunchJsonConfig()
{
    QDir vscodeDir(QDir::home().absoluteFilePath("Desktop/vscode/.vscode"));
    QFile file(vscodeDir.absoluteFilePath("launch.json"));
    if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QString config = R"({
    "version": "0.2.0",
    "configurations": [
        {
            "name": "g++.exe - 生成和调试活动文件",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}\\debug\\${fileBasenameNoExtension}.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": true,
            "MIMode": "gdb",
            "miDebuggerPath": "D:\\Aizo\\Tools\\mingw64\\bin\\gdb.exe",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "将反汇编风格设置为 Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "C/C++: g++.exe 生成活动文件"
        }
    ]
})";
        file.write(config.toUtf8());
        file.close();
    }
}

void SetupManager::onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
    if (exitStatus == QProcess::CrashExit) {
        std::cerr << "Process error: Process crashed" << std::endl;
    } else if (exitCode!= 0) {
        std::cerr << "Process error: Process exited with error code " << exitCode << std::endl;
    }
}

// 清理临时文件的函数,删除下载的安装包文件等临时文件
void SetupManager::cleanTempFiles()
{
    QFile::remove("mingw-get-setup.exe");
    QFile::remove("VSCodeSetup.exe");
    // 这里还可以添加代码来删除其他可能产生的临时文件或文件夹等,根据实际情况扩展
}

剩余项目文件已上传至GitHub,如有需要请访问,此处因篇幅问题仅展示主程序

你可以通过以下链接查看这个自动配置VSCode C++环境的工具的详细信息,并获取源代码:

[github.com/Dexter637/c…]

希望这个工具能够帮助更多的开发者快速搭建起VSCode C++开发环境,提升开发效率。如果你在使用过程中有任何问题或建议,欢迎在GitHub上提出。