OVERVIEW
概述
Right now I got these 2 programs on my windows taskbar:
现在我的windows任务栏上有两个程序:
-
SublimeText3 target:
SublimeText3目标:
"D:\software\SublimeText 3_x64\sublime_text.exe"
-
VS2015 x64 Native Tools Command Prompt target:
VS2015 x64本机工具命令提示目标:
%comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"" amd64
Goal here is running Sublime Text with vs2015 environment enabled.
这里的目标是使用vs2015环境运行崇高的文本。
- One option would be open the vs command prompt and then run sublime text from there,
> sublime_text
(this is not good one, I want it to be a non-interactive process) - 一个选项是打开vs命令提示符,然后从那里运行崇高的文本> sublime_text(这不是很好,我希望它是一个非交互式进程)
- Another option would be modifying somehow the sublimetext symlink target from the taskbar so I could open sublime with vs2015 environment enabled just clicking the icon
- 另一个选项是修改任务栏中的sublimetext symlink目标,这样我就可以使用vs2015环境打开sublime,只需点击图标
QUESTION
问题
How could I acomplish option 2?
我怎么能选择2呢?
NS: I want to get Sublime Text 3 to run vcvarsall.bat properly only once at startup (not at build time on any build system)
我想获得崇高的文本3来运行vcvarsall。bat仅在启动时正确执行一次(不是在任何构建系统的构建时)
ATTEMPTS
尝试
My first attempt was trying to understand how bat files executed so I tested some basic batch files:
我的第一次尝试是尝试理解bat文件是如何执行的,所以我测试了一些基本的批处理文件:
-
bat1.bat: It opens sublime text succesfully
bat1。蝙蝠:它成功地开启了崇高的文本。
sublime_text
-
bat2.bat: It opens vs command prompt succesfully and it waits for user to type commands
bat2。bat:它成功地打开vs命令提示符,并等待用户输入命令
cmd /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"" amd64
-
bat3.bat: Open vs command prompt but it won't open ST, unless you type exit once the command prompt is shown
bat3。bat:打开vs命令提示符,但它不会打开ST,除非在显示命令提示符时输入exit
%comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"" amd64 sublime_text
-
bat4.bat: Open vs command prompt but it doesn't open ST, same case than bat3.bat
bat4。bat: Open vs命令提示符,但它不打开ST,同样的情况也不打开。
%comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"" amd64 && sublime_text
-
bat5.bat: Open vs command prompt but it doesn't open ST, same case than bat{4,3}.bat
bat5。bat: Open vs命令提示符,但它不打开ST,与bat{4,3}.bat相同
%comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"" amd64 & sublime_text
After these attempts I've decided to read some docs trying to find some hints about cmd but it didn't make any difference.
在这些尝试之后,我决定读一些医生试图找到一些关于cmd的提示,但这没有什么区别。
Another idea was using conemu customized tasks, something like:
另一个想法是使用conemu定制的任务,比如:
{vs2015}: cmd.exe /k "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64 & sublime_text
and then having a bat file calling conemu like this:
然后有一个蝙蝠文件像这样调用conemu
D:\software\ConEmuPack.151205\ConEmu64.exe /single -cmd {vs2015}
the result was +/- what I wanted, but 2 terminals and a new sublime session would be spawned. What I'm looking for is just opening a SublimeText session with the right environment, so I consider this not a good solution, plus, it requires to have conemu installed.
结果是+/-我想要的,但是会产生两个终端和一个新的崇高会话。我想要的是打开一个带有适当环境的SublimeText会话,所以我认为这不是一个好的解决方案,而且,它需要安装conemu。
After all those attempts I thought maybe using python to open a command prompt and typing&running "magically" some commands could be helpful but I don't know how to do it.
在所有这些尝试之后,我认为也许可以用python来打开命令提示符,并“神奇地”运行一些命令,但是我不知道怎么做。
Conclusion: Till the date the problem remains unsolved...
结论:直到问题尚未解决……
2 个解决方案
#1
4
Aside of the ways that have already been mentioned in the question and the previous answer, another way to go is something akin to what @LinuxDisciple mentioned in their answer; have Sublime internally fire up the batch file once at Sublime start up to do what you need to do.
除了问题中已经提到的方法和之前的答案,另一种方法类似于@ linux门徒在他们的回答中提到的;让崇高的内部点燃一次批处理文件崇高开始做你需要做的。
An example of this in action is the following plugin. To start with, add the following settings to your user preferences (Preferences > Settings
or Preferences > Settings - User
). Here I'm using the setup for my own local machine; update the path to suit for your version of Visual Studio:
下面的插件就是一个例子。首先,将以下设置添加到您的用户首选项(首选项>设置或首选项>设置- user)。这里我用的是本地机器的设置;更新适合您版本的Visual Studio的路径:
"vc_vars_cmd": "C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat",
"vc_vars_arch": "amd64",
The vc_vars_cmd
setting is required by the following plugin, but the vc_vars_arch
setting is optional; if it is not given, it defaults to amd64
.
以下插件需要vc_vars_cmd设置,但是vc_vars_arch设置是可选的;如果没有给定,则默认为amd64。
Next, select Tools > Developer > New Plugin
from the menu and replace the stub plugin code with the following and save it in the default location that Sublime defaults to as something like set_vc_vars.py
:
接下来,从菜单中选择Tools > Developer > New Plugin,并用以下代码替换存根Plugin代码,并将其保存到默认位置,崇高的默认值为set_vc_var .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()
Once you save the plugin, Sublime will load it and execute the plugin_loaded
function, which will do all of the work.You should see the status bar say VS Environment Enabled
if it worked.
保存插件之后,Sublime将加载它并执行plugin_loaded函数,这将完成所有的工作。如果工作,您应该看到状态栏say VS环境启用。
If you see Error Fetching VS Environment
double check that the path to the batch file is correct (note that you need to double all path separators to make them JSON compliant).
如果您看到错误抓取VS环境,请再次检查到批处理文件的路径是否正确(注意,您需要将所有路径分隔符加倍以使它们与JSON兼容)。
This operates very similarly to (and is vaguely based on) the Fix Mac Path package, which does something similar to update the path in Sublime on MacOS, where the vagaries of the OS cause GUI applications to have their environment set in a way different than terminal applications.
这与Fix Mac Path包的操作非常相似(并且模糊地基于这个包),它在MacOS上做了一些类似于升级路径的事情,操作系统的变幻莫测导致GUI应用程序的环境设置与终端应用程序不同。
The general idea is that the batch file is executed in a sub-process, and then before returning we also execute the set
command to get the command interpreter to dump its entire environment to the console, which the plugin captures.
一般的想法是,批处理文件在子进程中执行,然后在返回之前,我们还执行set命令,使命令解释器将其整个环境转储到控制台,插件捕获控制台。
Once we have that data, we can easily compare it with the current environment to add in any environment variables that the batch file set up but which didn't already exist, and update the values of any environment variables that were changed (e.g. the PATH
).
一旦有了这些数据,我们就可以轻松地将其与当前环境进行比较,添加批处理文件设置但尚未存在的任何环境变量,并更新已更改的任何环境变量(例如路径)的值。
As a part of this process we also set a new environment variable that tells the plugin that the environment has already been set up, so that if the plugin gets reloaded it doesn't try to run the operation again.
作为这个过程的一部分,我们还设置了一个新的环境变量,该变量告诉插件环境已经设置好了,所以如果插件重新加载,它就不会再尝试运行这个操作。
As such, if you need to change the path to the batch file or the architecture that you want to be set up for, you need to change the preference and restart Sublime.
因此,如果需要更改要设置的批处理文件或体系结构的路径,则需要更改首选项并重新启动Sublime。
This could be made more robust by having it do something like store the current environment before modifying it and then watching the preferences to see if that setting is changed and act accordingly, but presumably it's not often that you would need to modify these settings.
通过让它在修改当前环境之前存储当前环境,然后查看首选项以查看该设置是否已更改并相应地进行操作,可以使其更加健壮,但您可能并不经常需要修改这些设置。
For testing purposes, I created the following simple C program:
为了测试目的,我创建了以下简单的C程序:
#include <stdio.h>
int main(int argc, char const *argv[])
{
printf("Hello VC World!\n");
return 0;
}
I also created the following sublime-build
file, based loosely off of the C++ Single File.sublime-build
that ships with Sublime:
我还创建了下面的sublime-build文件,松散地基于c++单个文件。亚石灰-建造船与崇高:
{
"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}\""
}
]
}
If you attempt to build the sample C file without the plugin, an error is generated about not being able to find cl
(unless you have started Sublime from a developer prompt or otherwise already set up the path). With the plugin in place, you get output similar to the following:
如果您试图在不使用插件的情况下构建示例C文件,就会产生无法找到cl的错误(除非您已经从开发人员提示符或已经设置了路径)。插件就位后,您会得到如下输出:
#2
4
- exactly as stated is not possible directly but Sublime Text has options for running other programs.
- 确切地说,不可能直接实现,但是崇高的文本有运行其他程序的选项。
Make a batch file that goes to the directory that vcvarsall.bat wants (it looks at the directory it was run from, so it needs to be started from the proper dir) and runs vcvarsall.bat:
创建一个批处理文件,该文件将进入vcvarsall目录。bat需要(它查看它运行的目录,因此需要从适当的dir开始)并运行vcvarsall.bat:
@ECHO OFF
REM vcdir is the directory where you should be
set vcdir="c:\program files (x86)\Microsoft Visual Studio 14.0\VC"
REM go into that directory
push "%vcdir%"
REM Run vcvarsall.bat to set the env vars
call vcvarsall.bat amd64
REM Get back to the directory we were in initially
popd
If you're ok running this batch file during build (if you only need it for the build process and you don't mind rerunning it every time) then follow these instructions to add that batch file to your build settings in sublime text 3
如果您可以在构建过程中运行这个批处理文件(如果您只是在构建过程中需要它,并且您不介意每次都重新运行它),那么请按照下面的说明将该批处理文件添加到崇高的文本3中的构建设置中
A more elegant approach would be to find out how to get Sublime Text 3 to run a program just once on startup (rather than at build time). I'd bet money that's possible, but I need to get back to work now...
一种更优雅的方法是找到如何在启动时(而不是在构建时)只运行一次程序的崇高文本3。我敢打赌那是可能的,但我现在得回去工作了……
#1
4
Aside of the ways that have already been mentioned in the question and the previous answer, another way to go is something akin to what @LinuxDisciple mentioned in their answer; have Sublime internally fire up the batch file once at Sublime start up to do what you need to do.
除了问题中已经提到的方法和之前的答案,另一种方法类似于@ linux门徒在他们的回答中提到的;让崇高的内部点燃一次批处理文件崇高开始做你需要做的。
An example of this in action is the following plugin. To start with, add the following settings to your user preferences (Preferences > Settings
or Preferences > Settings - User
). Here I'm using the setup for my own local machine; update the path to suit for your version of Visual Studio:
下面的插件就是一个例子。首先,将以下设置添加到您的用户首选项(首选项>设置或首选项>设置- user)。这里我用的是本地机器的设置;更新适合您版本的Visual Studio的路径:
"vc_vars_cmd": "C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat",
"vc_vars_arch": "amd64",
The vc_vars_cmd
setting is required by the following plugin, but the vc_vars_arch
setting is optional; if it is not given, it defaults to amd64
.
以下插件需要vc_vars_cmd设置,但是vc_vars_arch设置是可选的;如果没有给定,则默认为amd64。
Next, select Tools > Developer > New Plugin
from the menu and replace the stub plugin code with the following and save it in the default location that Sublime defaults to as something like set_vc_vars.py
:
接下来,从菜单中选择Tools > Developer > New Plugin,并用以下代码替换存根Plugin代码,并将其保存到默认位置,崇高的默认值为set_vc_var .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()
Once you save the plugin, Sublime will load it and execute the plugin_loaded
function, which will do all of the work.You should see the status bar say VS Environment Enabled
if it worked.
保存插件之后,Sublime将加载它并执行plugin_loaded函数,这将完成所有的工作。如果工作,您应该看到状态栏say VS环境启用。
If you see Error Fetching VS Environment
double check that the path to the batch file is correct (note that you need to double all path separators to make them JSON compliant).
如果您看到错误抓取VS环境,请再次检查到批处理文件的路径是否正确(注意,您需要将所有路径分隔符加倍以使它们与JSON兼容)。
This operates very similarly to (and is vaguely based on) the Fix Mac Path package, which does something similar to update the path in Sublime on MacOS, where the vagaries of the OS cause GUI applications to have their environment set in a way different than terminal applications.
这与Fix Mac Path包的操作非常相似(并且模糊地基于这个包),它在MacOS上做了一些类似于升级路径的事情,操作系统的变幻莫测导致GUI应用程序的环境设置与终端应用程序不同。
The general idea is that the batch file is executed in a sub-process, and then before returning we also execute the set
command to get the command interpreter to dump its entire environment to the console, which the plugin captures.
一般的想法是,批处理文件在子进程中执行,然后在返回之前,我们还执行set命令,使命令解释器将其整个环境转储到控制台,插件捕获控制台。
Once we have that data, we can easily compare it with the current environment to add in any environment variables that the batch file set up but which didn't already exist, and update the values of any environment variables that were changed (e.g. the PATH
).
一旦有了这些数据,我们就可以轻松地将其与当前环境进行比较,添加批处理文件设置但尚未存在的任何环境变量,并更新已更改的任何环境变量(例如路径)的值。
As a part of this process we also set a new environment variable that tells the plugin that the environment has already been set up, so that if the plugin gets reloaded it doesn't try to run the operation again.
作为这个过程的一部分,我们还设置了一个新的环境变量,该变量告诉插件环境已经设置好了,所以如果插件重新加载,它就不会再尝试运行这个操作。
As such, if you need to change the path to the batch file or the architecture that you want to be set up for, you need to change the preference and restart Sublime.
因此,如果需要更改要设置的批处理文件或体系结构的路径,则需要更改首选项并重新启动Sublime。
This could be made more robust by having it do something like store the current environment before modifying it and then watching the preferences to see if that setting is changed and act accordingly, but presumably it's not often that you would need to modify these settings.
通过让它在修改当前环境之前存储当前环境,然后查看首选项以查看该设置是否已更改并相应地进行操作,可以使其更加健壮,但您可能并不经常需要修改这些设置。
For testing purposes, I created the following simple C program:
为了测试目的,我创建了以下简单的C程序:
#include <stdio.h>
int main(int argc, char const *argv[])
{
printf("Hello VC World!\n");
return 0;
}
I also created the following sublime-build
file, based loosely off of the C++ Single File.sublime-build
that ships with Sublime:
我还创建了下面的sublime-build文件,松散地基于c++单个文件。亚石灰-建造船与崇高:
{
"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}\""
}
]
}
If you attempt to build the sample C file without the plugin, an error is generated about not being able to find cl
(unless you have started Sublime from a developer prompt or otherwise already set up the path). With the plugin in place, you get output similar to the following:
如果您试图在不使用插件的情况下构建示例C文件,就会产生无法找到cl的错误(除非您已经从开发人员提示符或已经设置了路径)。插件就位后,您会得到如下输出:
#2
4
- exactly as stated is not possible directly but Sublime Text has options for running other programs.
- 确切地说,不可能直接实现,但是崇高的文本有运行其他程序的选项。
Make a batch file that goes to the directory that vcvarsall.bat wants (it looks at the directory it was run from, so it needs to be started from the proper dir) and runs vcvarsall.bat:
创建一个批处理文件,该文件将进入vcvarsall目录。bat需要(它查看它运行的目录,因此需要从适当的dir开始)并运行vcvarsall.bat:
@ECHO OFF
REM vcdir is the directory where you should be
set vcdir="c:\program files (x86)\Microsoft Visual Studio 14.0\VC"
REM go into that directory
push "%vcdir%"
REM Run vcvarsall.bat to set the env vars
call vcvarsall.bat amd64
REM Get back to the directory we were in initially
popd
If you're ok running this batch file during build (if you only need it for the build process and you don't mind rerunning it every time) then follow these instructions to add that batch file to your build settings in sublime text 3
如果您可以在构建过程中运行这个批处理文件(如果您只是在构建过程中需要它,并且您不介意每次都重新运行它),那么请按照下面的说明将该批处理文件添加到崇高的文本3中的构建设置中
A more elegant approach would be to find out how to get Sublime Text 3 to run a program just once on startup (rather than at build time). I'd bet money that's possible, but I need to get back to work now...
一种更优雅的方法是找到如何在启动时(而不是在构建时)只运行一次程序的崇高文本3。我敢打赌那是可能的,但我现在得回去工作了……