python - 如何在启用 visual studio 环境的情况下运行 SublimeText

标签 python windows visual-studio-2015 environment-variables sublimetext3

概述

现在我的 Windows 任务栏上有这两个程序:

  • SublimeText3 目标:

    "D:\software\SublimeText 3_x64\sublime_text.exe"
    
  • VS2015 x64 native 工具命令提示目标:

    %comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"" amd64
    

此处的目标是在启用 vs2015 环境的情况下运行 Sublime Text。

  1. 一个选项是打开 vs 命令提示符,然后从那里运行 sublime text,> sublime_text(这不是很好,我希望它是一个非交互式进程)
  2. 另一种选择是以某种方式修改任务栏中的 sublimetext 符号链接(symbolic link)目标,这样我就可以在启用 vs2015 环境的情况下打开 sublime,只需单击该图标

问题

我怎样才能完成选项 2?

NS:我想让 Sublime Text 3 在启动时正确运行 vcvarsall.bat 一次(而不是在任何构建系统上的构建时)

尝试

我的第一次尝试是试图了解 bat 文件是如何执行的,所以我进行了测试 一些基本的批处理文件:

  • bat1.bat: 成功打开sublime text

    sublime_text
    
  • bat2.bat:成功打开vs命令提示符,等待用户输入命令

    cmd /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"" amd64
    
  • bat3.bat:打开 vs 命令提示符,但它不会打开 ST,除非您在命令提示符显示后键入 exit

    %comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"" amd64
    sublime_text
    
  • bat4.bat:打开 vs 命令提示符但它不打开 ST,与 bat3.bat 相同

    %comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"" amd64 && sublime_text
    
  • bat5.bat:打开 vs 命令提示符但它不打开 ST,与 bat{4,3}.bat 的情况相同

    %comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"" amd64 & sublime_text
    

在这些尝试之后,我决定阅读一些文档,试图找到关于 cmd 的一些提示。但这没有任何区别。

另一个想法是使用 conemu 自定义任务,例如:

{vs2015}: cmd.exe /k "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64 & sublime_text

然后有一个像这样调用 conemu 的 bat 文件:

D:\software\ConEmuPack.151205\ConEmu64.exe /single -cmd {vs2015}

结果是 +/- 我想要的,但是会产生 2 个终端和一个新的 sublime session 。我正在寻找的只是在正确的环境下打开一个 SublimeText session ,所以我认为这不是一个好的解决方案,另外,它需要安装 conemu。

在所有这些尝试之后,我认为也许可以使用 python 打开命令提示符并“神奇地”输入和运行一些命令可能会有帮助,但我不知道该怎么做。

结论:到现在为止问题还没有解决...

最佳答案

除了问题和先前答案中已经提到的方法之外,另一种方法类似于@LinuxDisciple 在他们的答案中提到的方法;在 Sublime 启动时让 Sublime 在内部启动批处理文件以执行您需要执行的操作。

下面的插件就是一个例子。首先,将以下设置添加到您的用户首选项(Preferences > SettingsPreferences > Settings - User)。在这里,我使用的是我自己的本地机器的设置;更新路径以适合您的 Visual Studio 版本:

"vc_vars_cmd": "C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat",
"vc_vars_arch": "amd64",

以下插件需要vc_vars_cmd设置,但是vc_vars_arch设置是可选的;如果未给出,则默认为 amd64

接下来,从菜单中选择 Tools > Developer > New Plugin 并将 stub 插件代码替换为以下代码,并将其保存在 Sublime 默认的默认位置,如 set_vc_vars。 py:

import sublime
import sublime_plugin

from threading import Thread
from subprocess import Popen, PIPE
from os import environ

SENTINEL="SUBL_VC_VARS"

def _get_vc_env():
    """
    Run the batch file specified in the vc_vars_cmd setting (with an
    optional architecture type) and return back a dictionary of the
    environment that the batch file sets up.

    Returns None if the preference is missing or the batch file fails.
    """
    settings = sublime.load_settings("Preferences.sublime-settings")
    vars_cmd = settings.get("vc_vars_cmd")
    vars_arch = settings.get("vc_vars_arch", "amd64")

    if vars_cmd is None:
        print("set_vc_vars: Cannot set Visual Studio Environment")
        print("set_vc_vars: Add 'vc_vars_cmd' setting to settings and restart")
        return None

    try:
        # Run the batch, outputting a sentinel value so we can separate out
        # any error messages the batch might generate.
        shell_cmd = "\"{0}\" {1} && echo {2} && set".format(
            vars_cmd, vars_arch, SENTINEL)

        output = Popen(shell_cmd, stdout=PIPE, shell=True).stdout.read()

        lines = [line.strip() for line in output.decode("utf-8").splitlines()]
        env_lines = lines[lines.index(SENTINEL) + 1:]
    except:
        return None

    # Convert from var=value to dictionary key/value pairs. We upper case the
    # keys, since Python does that to the mapping it stores in environ.
    env = {}
    for env_var in env_lines:
        parts = env_var.split("=", maxsplit=1)
        env[parts[0].upper()] = parts[1]

    return env

def install_vc_env():
    """
    Try to collect the appropriate Visual Studio environment variables and
    set them into the current environment.
    """
    vc_env = _get_vc_env()
    if vc_env is None:
        print("set_vc_vars: Unable to fetch the Visual Studio Environment")
        return sublime.status_message("Error fetching VS Environment")

    # Add newly set environment variables
    for key in vc_env.keys():
        if key not in environ:
            environ[key] = vc_env[key]

    # Update existing variables whose values changed.
    for key in environ:
        if key in vc_env and environ[key] != vc_env[key]:
            environ[key] = vc_env[key]

    # Set a sentinel variable so we know not to try setting up the path again.
    environ[SENTINEL] = "BOOTSTRAPPED"
    sublime.status_message("VS Environment enabled")

def plugin_loaded():
    if sublime.platform() != "windows":
        return sublime.status_message("VS is not supported on this platform")

    # To reload the environment if it changes, restart Sublime.
    if SENTINEL in environ:
        return sublime.status_message("VS Environment already enabled")

    # Update in the background so we don't block the UI
    Thread(target=install_vc_env).start()

保存插件后,Sublime 将加载它并执行 plugin_loaded 函数,这将完成所有工作。您应该看到状态栏显示 VS Environment Enabled 如果有效。

如果您看到 Error Fetching VS Environment,请仔细检查批处理文件的路径是否正确(请注意,您需要将所有路径分隔符加倍以使其符合 JSON 标准)。

这与 Fix Mac Path 非常相似(并且模糊地基于)包,它的作用类似于在 MacOS 上的 Sublime 中更新路径,其中操作系统的变幻莫测导致 GUI 应用程序以不同于终端应用程序的方式设置它们的环境。

大意是批处理文件在子进程中执行,然后在返回之前我们还执行set命令让命令解释器将其整个环境转储到控制台,插件捕获的内容。

一旦我们有了这些数据,我们就可以轻松地将它与当前环境进行比较,以添加批处理文件设置但尚不存在的任何环境变量,并更新任何已更改的环境变量的值(例如 PATH)。

作为这个过程的一部分,我们还设置了一个新的环境变量,告诉插件环境已经设置好,这样如果插件被重新加载,它就不会尝试再次运行该操作。

因此,如果您需要更改批处理文件的路径或要为其设置的架构,则需要更改首选项并重新启动 Sublime。

通过让它在修改之前存储当前环境然后观察首选项以查看该设置是否已更改并采取相应行动,可以使它变得更加健壮,但大概您不需要经常修改这些设置。

出于测试目的,我创建了以下简单的 C 程序:

#include <stdio.h>

int main(int argc, char const *argv[])
{
    printf("Hello VC World!\n");

    return 0;
}

我还创建了以下 sublime-build 文件,它大致基于 Sublime 附带的 C++ Single File.sublime-build:

{
    "shell_cmd": "cl \"${file}\" /Fe\"${file_base_name}\"",
    "working_dir": "${file_path}",
    "selector": "source.c, source.c++",

    "variants":
    [
        {
            "name": "Run",
            "shell_cmd": "cl \"${file}\" /Fe\"${file_base_name}\" && \"${file_base_name}\""
        }
    ]
}

如果你试图在没有插件的情况下构建示例 C 文件,则会生成一个关于无法找到 cl 的错误(除非你已经从开发人员提示启动 Sublime 或者已经设置了小路)。安装好插件后,您将获得类似于以下内容的输出:

Sample C Program being executed

关于python - 如何在启用 visual studio 环境的情况下运行 SublimeText,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39881091/

相关文章:

java - 用 Java 进行 Windows 编程?

c# - 在 Visual Studio 2015 中重命名时导致 "unresolvable conflict(s)"的原因是什么?

c# - 尝试解析标记助手指令 '@addTagHelper' 时遇到意外错误

python - 如何让QTableView在再次加载数据后刷新背景颜色

python - 使用 Python/ElementTree 为 XML 中的元素插入节点

c++ - 在 Linux 和 Windows 上计算相同 --> 不同的结果

windows - 如何在 Windows EC2 实例上运行 Minikube?

c# - Visual Studio 搜索和替换行尾

python - 在 Python 中检查目录是否为空的最快方法是什么

python - Pandas :分类数据的多个直方图