Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
41c02aa8
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
41c02aa8
编写于
11月 05, 2018
作者:
D
Dirk Baeumer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fixes #62594: Resolving process task doesn't take task system into account
上级
fb9e1da1
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
162 addition
and
84 deletion
+162
-84
src/vs/base/node/processes.ts
src/vs/base/node/processes.ts
+49
-0
src/vs/workbench/api/electron-browser/mainThreadTask.ts
src/vs/workbench/api/electron-browser/mainThreadTask.ts
+12
-5
src/vs/workbench/api/node/extHost.protocol.ts
src/vs/workbench/api/node/extHost.protocol.ts
+1
-1
src/vs/workbench/api/node/extHostTask.ts
src/vs/workbench/api/node/extHostTask.ts
+25
-5
src/vs/workbench/parts/tasks/common/taskSystem.ts
src/vs/workbench/parts/tasks/common/taskSystem.ts
+15
-1
src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts
...kbench/parts/tasks/electron-browser/terminalTaskSystem.ts
+60
-72
未找到文件。
src/vs/base/node/processes.ts
浏览文件 @
41c02aa8
...
...
@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import
*
as
path
from
'
path
'
;
import
*
as
fs
from
'
fs
'
;
import
*
as
cp
from
'
child_process
'
;
import
*
as
nls
from
'
vs/nls
'
;
import
{
TPromise
,
TValueCallback
,
ErrorCallback
}
from
'
vs/base/common/winjs.base
'
;
...
...
@@ -400,3 +401,51 @@ export function createQueuedSender(childProcess: cp.ChildProcess): IQueuedSender
return
{
send
};
}
export
namespace
win32
{
export
function
findExecutable
(
command
:
string
,
cwd
?:
string
,
paths
?:
string
[]):
string
{
// If we have an absolute path then we take it.
if
(
path
.
isAbsolute
(
command
))
{
return
command
;
}
if
(
cwd
===
void
0
)
{
cwd
=
process
.
cwd
();
}
let
dir
=
path
.
dirname
(
command
);
if
(
dir
!==
'
.
'
)
{
// We have a directory and the directory is relative (see above). Make the path absolute
// to the current working directory.
return
path
.
join
(
cwd
,
command
);
}
if
(
paths
===
void
0
&&
Types
.
isString
(
process
.
env
.
PATH
))
{
paths
=
process
.
env
.
PATH
.
split
(
path
.
delimiter
);
}
// No PATH environment. Make path absolute to the cwd.
if
(
paths
===
void
0
||
paths
.
length
===
0
)
{
return
path
.
join
(
cwd
,
command
);
}
// We have a simple file name. We get the path variable from the env
// and try to find the executable on the path.
for
(
let
pathEntry
of
paths
)
{
// The path entry is absolute.
let
fullPath
:
string
;
if
(
path
.
isAbsolute
(
pathEntry
))
{
fullPath
=
path
.
join
(
pathEntry
,
command
);
}
else
{
fullPath
=
path
.
join
(
cwd
,
pathEntry
,
command
);
}
if
(
fs
.
existsSync
(
fullPath
))
{
return
fullPath
;
}
let
withExtension
=
fullPath
+
'
.com
'
;
if
(
fs
.
existsSync
(
withExtension
))
{
return
withExtension
;
}
withExtension
=
fullPath
+
'
.exe
'
;
if
(
fs
.
existsSync
(
withExtension
))
{
return
withExtension
;
}
}
return
path
.
join
(
cwd
,
command
);
}
}
\ No newline at end of file
src/vs/workbench/api/electron-browser/mainThreadTask.ts
浏览文件 @
41c02aa8
...
...
@@ -29,6 +29,7 @@ import {
TaskDefinitionDTO
,
TaskExecutionDTO
,
ProcessExecutionOptionsDTO
,
TaskPresentationOptionsDTO
,
ProcessExecutionDTO
,
ShellExecutionDTO
,
ShellExecutionOptionsDTO
,
TaskDTO
,
TaskSourceDTO
,
TaskHandleDTO
,
TaskFilterDTO
,
TaskProcessStartedDTO
,
TaskProcessEndedDTO
,
TaskSystemInfoDTO
}
from
'
vs/workbench/api/shared/tasks
'
;
import
{
ResolveSet
,
ResolvedVariables
}
from
'
vs/workbench/parts/tasks/common/taskSystem
'
;
namespace
TaskExecutionDTO
{
export
function
from
(
value
:
TaskExecution
):
TaskExecutionDTO
{
...
...
@@ -505,12 +506,18 @@ export class MainThreadTask implements MainThreadTaskShape {
return
URI
.
parse
(
`
${
info
.
scheme
}
://
${
info
.
authority
}${
path
}
`
);
},
context
:
this
.
_extHostContext
,
resolveVariables
:
(
workspaceFolder
:
IWorkspaceFolder
,
variables
:
Set
<
string
>
):
Promise
<
Map
<
string
,
string
>
>
=>
{
resolveVariables
:
(
workspaceFolder
:
IWorkspaceFolder
,
toResolve
:
ResolveSet
):
TPromise
<
ResolvedVariables
>
=>
{
let
vars
:
string
[]
=
[];
variables
.
forEach
(
item
=>
vars
.
push
(
item
));
return
Promise
.
resolve
(
this
.
_proxy
.
$resolveVariables
(
workspaceFolder
.
uri
,
vars
)).
then
(
values
=>
{
let
result
=
new
Map
<
string
,
string
>
();
Object
.
keys
(
values
).
forEach
(
key
=>
result
.
set
(
key
,
values
[
key
]));
toResolve
.
variables
.
forEach
(
item
=>
vars
.
push
(
item
));
return
Promise
.
resolve
(
this
.
_proxy
.
$resolveVariables
(
workspaceFolder
.
uri
,
{
process
:
toResolve
.
process
,
variables
:
vars
})).
then
(
values
=>
{
let
result
=
{
process
:
undefined
as
string
,
variables
:
new
Map
<
string
,
string
>
()
};
Object
.
keys
(
values
.
variables
).
forEach
(
key
=>
result
.
variables
.
set
(
key
,
values
[
key
]));
if
(
Types
.
isString
(
values
.
process
))
{
result
.
process
=
values
.
process
;
}
return
result
;
});
}
...
...
src/vs/workbench/api/node/extHost.protocol.ts
浏览文件 @
41c02aa8
...
...
@@ -914,7 +914,7 @@ export interface ExtHostTaskShape {
$onDidStartTaskProcess
(
value
:
TaskProcessStartedDTO
):
void
;
$onDidEndTaskProcess
(
value
:
TaskProcessEndedDTO
):
void
;
$OnDidEndTask
(
execution
:
TaskExecutionDTO
):
void
;
$resolveVariables
(
workspaceFolder
:
UriComponents
,
variables
:
string
[]):
Thenable
<
any
>
;
$resolveVariables
(
workspaceFolder
:
UriComponents
,
toResolve
:
{
process
?:
{
name
:
string
;
cwd
?:
string
},
variables
:
string
[]
}):
Thenable
<
{
process
?:
string
;
variables
:
{
[
key
:
string
]:
string
}
}
>
;
}
export
interface
IBreakpointDto
{
...
...
src/vs/workbench/api/node/extHostTask.ts
浏览文件 @
41c02aa8
...
...
@@ -3,11 +3,14 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
*
as
path
from
'
path
'
;
import
{
URI
,
UriComponents
}
from
'
vs/base/common/uri
'
;
import
*
as
nls
from
'
vs/nls
'
;
import
*
as
Objects
from
'
vs/base/common/objects
'
;
import
{
asThenable
}
from
'
vs/base/common/async
'
;
import
{
Event
,
Emitter
}
from
'
vs/base/common/event
'
;
import
{
win32
}
from
'
vs/base/node/processes
'
;
import
{
IExtensionDescription
}
from
'
vs/workbench/services/extensions/common/extensions
'
;
import
*
as
tasks
from
'
vs/workbench/parts/tasks/common/tasks
'
;
...
...
@@ -883,9 +886,12 @@ export class ExtHostTask implements ExtHostTaskShape {
});
}
public
$resolveVariables
(
uriComponents
:
UriComponents
,
variables
:
string
[]):
any
{
public
$resolveVariables
(
uriComponents
:
UriComponents
,
toResolve
:
{
process
?:
{
name
:
string
;
cwd
?:
string
;
path
?:
string
},
variables
:
string
[]
}):
Thenable
<
{
process
?:
string
,
variables
:
{
[
key
:
string
]:
string
;
}
}
>
{
let
uri
:
URI
=
URI
.
revive
(
uriComponents
);
let
result
:
{
[
key
:
string
]:
string
;
}
=
Object
.
create
(
null
);
let
result
=
{
process
:
undefined
as
string
,
variables
:
Object
.
create
(
null
)
};
let
workspaceFolder
=
this
.
_workspaceService
.
resolveWorkspaceFolder
(
uri
);
let
resolver
=
new
ExtHostVariableResolverService
(
this
.
_workspaceService
,
this
.
_editorService
,
this
.
_configurationService
);
let
ws
:
IWorkspaceFolder
=
{
...
...
@@ -896,10 +902,24 @@ export class ExtHostTask implements ExtHostTaskShape {
throw
new
Error
(
'
Not implemented
'
);
}
};
for
(
let
variable
of
variables
)
{
result
[
variable
]
=
resolver
.
resolve
(
ws
,
variable
);
for
(
let
variable
of
toResolve
.
variables
)
{
result
.
variables
[
variable
]
=
resolver
.
resolve
(
ws
,
variable
);
}
if
(
toResolve
.
process
!==
void
0
)
{
let
paths
:
string
[]
|
undefined
=
undefined
;
if
(
toResolve
.
process
.
path
!==
void
0
)
{
paths
=
toResolve
.
process
.
path
.
split
(
path
.
delimiter
);
for
(
let
i
=
0
;
i
<
paths
.
length
;
i
++
)
{
paths
[
i
]
=
resolver
.
resolve
(
ws
,
paths
[
i
]);
}
}
result
.
process
=
win32
.
findExecutable
(
resolver
.
resolve
(
ws
,
toResolve
.
process
.
name
),
toResolve
.
process
.
cwd
!==
void
0
?
resolver
.
resolve
(
ws
,
toResolve
.
process
.
cwd
)
:
undefined
,
paths
);
}
return
result
;
return
Promise
.
resolve
(
result
)
;
}
private
nextHandle
():
number
{
...
...
src/vs/workbench/parts/tasks/common/taskSystem.ts
浏览文件 @
41c02aa8
...
...
@@ -102,11 +102,25 @@ export interface TaskTerminateResponse extends TerminateResponse {
task
:
Task
|
undefined
;
}
export
interface
ResolveSet
{
process
?:
{
name
:
string
;
cwd
?:
string
;
path
?:
string
;
};
variables
:
Set
<
string
>
;
}
export
interface
ResolvedVariables
{
process
?:
string
;
variables
:
Map
<
string
,
string
>
;
}
export
interface
TaskSystemInfo
{
platform
:
Platform
;
context
:
any
;
uriProvider
:
(
this
:
void
,
path
:
string
)
=>
URI
;
resolveVariables
(
workspaceFolder
:
IWorkspaceFolder
,
variables
:
Set
<
string
>
):
TPromise
<
Map
<
string
,
string
>
>
;
resolveVariables
(
workspaceFolder
:
IWorkspaceFolder
,
toResolve
:
ResolveSet
):
TPromise
<
ResolvedVariables
>
;
}
export
interface
TaskSystemInfoResovler
{
...
...
src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts
浏览文件 @
41c02aa8
...
...
@@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
*
as
fs
from
'
fs
'
;
import
*
as
path
from
'
path
'
;
import
*
as
nls
from
'
vs/nls
'
;
...
...
@@ -19,6 +18,8 @@ import { Event, Emitter } from 'vs/base/common/event';
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
*
as
TPath
from
'
vs/base/common/paths
'
;
import
{
win32
}
from
'
vs/base/node/processes
'
;
import
{
IMarkerService
,
MarkerSeverity
}
from
'
vs/platform/markers/common/markers
'
;
import
{
IWorkspaceContextService
,
WorkbenchState
,
IWorkspaceFolder
}
from
'
vs/platform/workspace/common/workspace
'
;
import
{
IModelService
}
from
'
vs/editor/common/services/modelService
'
;
...
...
@@ -36,7 +37,7 @@ import {
}
from
'
vs/workbench/parts/tasks/common/tasks
'
;
import
{
ITaskSystem
,
ITaskSummary
,
ITaskExecuteResult
,
TaskExecuteKind
,
TaskError
,
TaskErrors
,
ITaskResolver
,
TelemetryEvent
,
Triggers
,
TaskTerminateResponse
,
TaskSystemInfoResovler
,
TaskSystemInfo
TelemetryEvent
,
Triggers
,
TaskTerminateResponse
,
TaskSystemInfoResovler
,
TaskSystemInfo
,
ResolveSet
}
from
'
vs/workbench/parts/tasks/common/taskSystem
'
;
interface
TerminalData
{
...
...
@@ -72,6 +73,8 @@ export class TerminalTaskSystem implements ITaskSystem {
public
static
TelemetryEventName
:
string
=
'
taskService
'
;
private
static
ProcessVarName
=
'
${__process__}
'
;
private
static
shellQuotes
:
IStringDictionary
<
ShellQuotingOptions
>
=
{
'
cmd
'
:
{
strong
:
'
"
'
...
...
@@ -304,18 +307,60 @@ export class TerminalTaskSystem implements ITaskSystem {
if
(
workspaceFolder
)
{
taskSystemInfo
=
this
.
taskSystemInfoResolver
(
workspaceFolder
);
}
let
resolvedVariables
:
TPromise
<
Map
<
string
,
string
>>
;
let
variableResolver
:
TPromise
<
VariableResolver
>
;
let
isProcess
=
task
.
command
&&
task
.
command
.
runtime
===
RuntimeType
.
Process
;
let
options
=
task
.
command
&&
task
.
command
.
options
?
task
.
command
.
options
:
undefined
;
let
cwd
=
options
?
options
.
cwd
:
undefined
;
let
envPath
:
string
|
undefined
=
undefined
;
if
(
options
&&
options
.
env
)
{
for
(
let
key
of
Object
.
keys
(
options
.
env
))
{
if
(
key
.
toLowerCase
()
===
'
path
'
)
{
if
(
Types
.
isString
(
options
.
env
[
key
]))
{
envPath
=
options
.
env
[
key
];
}
break
;
}
}
}
if
(
taskSystemInfo
)
{
resolvedVariables
=
taskSystemInfo
.
resolveVariables
(
workspaceFolder
,
variables
);
let
resolveSet
:
ResolveSet
=
{
variables
};
if
(
taskSystemInfo
.
platform
===
Platform
.
Platform
.
Windows
&&
isProcess
)
{
resolveSet
.
process
=
{
name
:
CommandString
.
value
(
task
.
command
.
name
)
};
if
(
cwd
)
{
resolveSet
.
process
.
cwd
=
cwd
;
}
if
(
envPath
)
{
resolveSet
.
process
.
path
=
envPath
;
}
}
variableResolver
=
taskSystemInfo
.
resolveVariables
(
workspaceFolder
,
resolveSet
).
then
((
resolved
)
=>
{
let
result
=
new
Map
<
string
,
string
>
();
resolved
.
variables
.
forEach
(
variable
=>
{
result
.
set
(
variable
,
this
.
configurationResolverService
.
resolve
(
workspaceFolder
,
variable
));
});
if
(
resolved
.
process
!==
void
0
)
{
result
.
set
(
TerminalTaskSystem
.
ProcessVarName
,
resolved
.
process
);
}
return
new
VariableResolver
(
workspaceFolder
,
taskSystemInfo
,
result
,
undefined
);
});
}
else
{
let
result
=
new
Map
<
string
,
string
>
();
variables
.
forEach
(
variable
=>
{
result
.
set
(
variable
,
this
.
configurationResolverService
.
resolve
(
workspaceFolder
,
variable
));
});
resolvedVariables
=
TPromise
.
as
(
result
);
if
(
Platform
.
isWindows
&&
isProcess
)
{
result
.
set
(
TerminalTaskSystem
.
ProcessVarName
,
win32
.
findExecutable
(
this
.
configurationResolverService
.
resolve
(
workspaceFolder
,
CommandString
.
value
(
task
.
command
.
name
)),
cwd
?
this
.
configurationResolverService
.
resolve
(
workspaceFolder
,
cwd
)
:
undefined
,
envPath
?
envPath
.
split
(
path
.
delimiter
).
map
(
p
=>
this
.
configurationResolverService
.
resolve
(
workspaceFolder
,
p
))
:
undefined
));
}
variableResolver
=
TPromise
.
as
(
new
VariableResolver
(
workspaceFolder
,
taskSystemInfo
,
result
,
this
.
configurationResolverService
));
}
return
resolvedVariables
.
then
((
variables
)
=>
{
return
this
.
executeInTerminal
(
task
,
trigger
,
new
VariableResolver
(
workspaceFolder
,
taskSystemInfo
,
variables
,
this
.
configurationResolverService
)
);
return
variableResolver
.
then
((
resolver
)
=>
{
return
this
.
executeInTerminal
(
task
,
trigger
,
resolver
);
});
}
...
...
@@ -563,7 +608,7 @@ export class TerminalTaskSystem implements ITaskSystem {
}
let
shellArgs
=
<
string
[]
>
shellLaunchConfig
.
args
.
slice
(
0
);
let
toAdd
:
string
[]
=
[];
let
commandLine
=
this
.
buildShellCommandLine
(
shellLaunchConfig
.
executable
,
shellOptions
,
command
,
originalCommand
,
args
);
let
commandLine
=
this
.
buildShellCommandLine
(
platform
,
shellLaunchConfig
.
executable
,
shellOptions
,
command
,
originalCommand
,
args
);
let
windowsShellArgs
:
boolean
=
false
;
if
(
platform
===
Platform
.
Platform
.
Windows
)
{
// Change Sysnative to System32 if the OS is Windows but NOT WoW64. It's
...
...
@@ -597,7 +642,7 @@ export class TerminalTaskSystem implements ITaskSystem {
}
else
{
if
(
!
shellSpecified
)
{
// Under Mac remove -l to not start it as a login shell.
if
(
Platform
.
isMacintosh
)
{
if
(
platform
===
Platform
.
Platform
.
Mac
)
{
let
index
=
shellArgs
.
indexOf
(
'
-l
'
);
if
(
index
!==
-
1
)
{
shellArgs
.
splice
(
index
,
1
);
...
...
@@ -621,10 +666,9 @@ export class TerminalTaskSystem implements ITaskSystem {
}
}
}
else
{
let
cwd
=
options
&&
options
.
cwd
?
options
.
cwd
:
process
.
cwd
();
// On Windows executed process must be described absolute. Since we allowed command without an
// absolute path (e.g. "command": "node") we need to find the executable in the CWD or PATH.
let
executable
=
Platform
.
isWindows
&&
!
isShellCommand
?
this
.
findExecutable
(
commandExecutable
,
cwd
,
options
)
:
commandExecutable
;
let
executable
=
!
isShellCommand
?
this
.
resolveVariable
(
resolver
,
TerminalTaskSystem
.
ProcessVarName
)
:
commandExecutable
;
// When we have a process task there is no need to quote arguments. So we go ahead and take the string value.
shellLaunchConfig
=
{
...
...
@@ -717,7 +761,7 @@ export class TerminalTaskSystem implements ITaskSystem {
return
[
result
,
commandExecutable
,
undefined
];
}
private
buildShellCommandLine
(
shellExecutable
:
string
,
shellOptions
:
ShellConfiguration
,
command
:
CommandString
,
originalCommand
:
CommandString
,
args
:
CommandString
[]):
string
{
private
buildShellCommandLine
(
platform
:
Platform
.
Platform
,
shellExecutable
:
string
,
shellOptions
:
ShellConfiguration
,
command
:
CommandString
,
originalCommand
:
CommandString
,
args
:
CommandString
[]):
string
{
let
basename
=
path
.
parse
(
shellExecutable
).
name
.
toLowerCase
();
let
shellQuoteOptions
=
this
.
getQuotingOptions
(
basename
,
shellOptions
);
...
...
@@ -805,7 +849,7 @@ export class TerminalTaskSystem implements ITaskSystem {
let
commandLine
=
result
.
join
(
'
'
);
// There are special rules quoted command line in cmd.exe
if
(
Platform
.
is
Windows
)
{
if
(
platform
===
Platform
.
Platform
.
Windows
)
{
if
(
basename
===
'
cmd
'
&&
commandQuoted
&&
argQuoted
)
{
commandLine
=
'
"
'
+
commandLine
+
'
"
'
;
}
else
if
(
basename
===
'
powershell
'
&&
commandQuoted
)
{
...
...
@@ -813,7 +857,7 @@ export class TerminalTaskSystem implements ITaskSystem {
}
}
if
(
basename
===
'
cmd
'
&&
Platform
.
is
Windows
&&
commandQuoted
&&
argQuoted
)
{
if
(
basename
===
'
cmd
'
&&
platform
===
Platform
.
Platform
.
Windows
&&
commandQuoted
&&
argQuoted
)
{
commandLine
=
'
"
'
+
commandLine
+
'
"
'
;
}
return
commandLine
;
...
...
@@ -904,62 +948,6 @@ export class TerminalTaskSystem implements ITaskSystem {
return
{
command
,
args
};
}
private
findExecutable
(
command
:
string
,
cwd
:
string
,
options
:
CommandOptions
):
string
{
// If we have an absolute path then we take it.
if
(
path
.
isAbsolute
(
command
))
{
return
command
;
}
let
dir
=
path
.
dirname
(
command
);
if
(
dir
!==
'
.
'
)
{
// We have a directory and the directory is relative (see above). Make the path absolute
// to the current working directory.
return
path
.
join
(
cwd
,
command
);
}
let
paths
:
string
[]
|
undefined
=
undefined
;
// The options can override the PATH. So consider that PATH if present.
if
(
options
&&
options
.
env
)
{
// Path can be named in many different ways and for the execution it doesn't matter
for
(
let
key
of
Object
.
keys
(
options
.
env
))
{
if
(
key
.
toLowerCase
()
===
'
path
'
)
{
if
(
Types
.
isString
(
options
.
env
[
key
]))
{
paths
=
options
.
env
[
key
].
split
(
path
.
delimiter
);
}
break
;
}
}
}
if
(
paths
===
void
0
&&
Types
.
isString
(
process
.
env
.
PATH
))
{
paths
=
process
.
env
.
PATH
.
split
(
path
.
delimiter
);
}
// No PATH environment. Make path absolute to the cwd.
if
(
paths
===
void
0
||
paths
.
length
===
0
)
{
return
path
.
join
(
cwd
,
command
);
}
// We have a simple file name. We get the path variable from the env
// and try to find the executable on the path.
for
(
let
pathEntry
of
paths
)
{
// The path entry is absolute.
let
fullPath
:
string
;
if
(
path
.
isAbsolute
(
pathEntry
))
{
fullPath
=
path
.
join
(
pathEntry
,
command
);
}
else
{
fullPath
=
path
.
join
(
cwd
,
pathEntry
,
command
);
}
if
(
fs
.
existsSync
(
fullPath
))
{
return
fullPath
;
}
let
withExtension
=
fullPath
+
'
.com
'
;
if
(
fs
.
existsSync
(
withExtension
))
{
return
withExtension
;
}
withExtension
=
fullPath
+
'
.exe
'
;
if
(
fs
.
existsSync
(
withExtension
))
{
return
withExtension
;
}
}
return
path
.
join
(
cwd
,
command
);
}
private
resolveVariables
(
resolver
:
VariableResolver
,
value
:
string
[]):
string
[];
private
resolveVariables
(
resolver
:
VariableResolver
,
value
:
CommandString
[]):
CommandString
[];
private
resolveVariables
(
resolver
:
VariableResolver
,
value
:
CommandString
[]):
CommandString
[]
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录