Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
288445a5
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,发现更多精彩内容 >>
提交
288445a5
编写于
4月 07, 2020
作者:
S
Sandeep Somavarapu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
#94599 Move exe based tips to new service in shared process
上级
9fdfbbc3
变更
9
显示空白变更内容
内联
并排
Showing
9 changed file
with
216 addition
and
73 deletion
+216
-73
src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts
.../code/electron-browser/sharedProcess/sharedProcessMain.ts
+8
-2
src/vs/platform/extensionManagement/common/extensionManagement.ts
...latform/extensionManagement/common/extensionManagement.ts
+13
-0
src/vs/platform/extensionManagement/common/extensionManagementIpc.ts
...form/extensionManagement/common/extensionManagementIpc.ts
+20
-1
src/vs/platform/extensionManagement/node/extensionTipsService.ts
...platform/extensionManagement/node/extensionTipsService.ts
+93
-0
src/vs/workbench/contrib/extensions/electron-browser/extensionRecommendationsService.ts
...sions/electron-browser/extensionRecommendationsService.ts
+21
-70
src/vs/workbench/services/extensionManagement/common/extensionTipsService.ts
...rvices/extensionManagement/common/extensionTipsService.ts
+26
-0
src/vs/workbench/services/extensionManagement/electron-browser/extensionTipsService.ts
...ensionManagement/electron-browser/extensionTipsService.ts
+33
-0
src/vs/workbench/workbench.desktop.main.ts
src/vs/workbench/workbench.desktop.main.ts
+1
-0
src/vs/workbench/workbench.web.main.ts
src/vs/workbench/workbench.web.main.ts
+1
-0
未找到文件。
src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts
浏览文件 @
288445a5
...
...
@@ -13,8 +13,8 @@ import { InstantiationService } from 'vs/platform/instantiation/common/instantia
import
{
IEnvironmentService
}
from
'
vs/platform/environment/common/environment
'
;
import
{
ParsedArgs
}
from
'
vs/platform/environment/node/argv
'
;
import
{
EnvironmentService
}
from
'
vs/platform/environment/node/environmentService
'
;
import
{
ExtensionManagementChannel
}
from
'
vs/platform/extensionManagement/common/extensionManagementIpc
'
;
import
{
IExtensionManagementService
,
IExtensionGalleryService
,
IGlobalExtensionEnablementService
}
from
'
vs/platform/extensionManagement/common/extensionManagement
'
;
import
{
ExtensionManagementChannel
,
ExtensionTipsChannel
}
from
'
vs/platform/extensionManagement/common/extensionManagementIpc
'
;
import
{
IExtensionManagementService
,
IExtensionGalleryService
,
IGlobalExtensionEnablementService
,
IExtensionTipsService
}
from
'
vs/platform/extensionManagement/common/extensionManagement
'
;
import
{
ExtensionManagementService
}
from
'
vs/platform/extensionManagement/node/extensionManagementService
'
;
import
{
ExtensionGalleryService
}
from
'
vs/platform/extensionManagement/common/extensionGalleryService
'
;
import
{
IConfigurationService
}
from
'
vs/platform/configuration/common/configuration
'
;
...
...
@@ -69,6 +69,7 @@ import { IAuthenticationTokenService, AuthenticationTokenService } from 'vs/plat
import
{
AuthenticationTokenServiceChannel
}
from
'
vs/platform/authentication/common/authenticationIpc
'
;
import
{
UserDataSyncBackupStoreService
}
from
'
vs/platform/userDataSync/common/userDataSyncBackupStoreService
'
;
import
{
IStorageKeysSyncRegistryService
}
from
'
vs/platform/userDataSync/common/storageKeys
'
;
import
{
ExtensionTipsService
}
from
'
vs/platform/extensionManagement/node/extensionTipsService
'
;
export
interface
ISharedProcessConfiguration
{
readonly
machineId
:
string
;
...
...
@@ -190,6 +191,7 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat
services
.
set
(
IExtensionGalleryService
,
new
SyncDescriptor
(
ExtensionGalleryService
));
services
.
set
(
ILocalizationsService
,
new
SyncDescriptor
(
LocalizationsService
));
services
.
set
(
IDiagnosticsService
,
new
SyncDescriptor
(
DiagnosticsService
));
services
.
set
(
IExtensionTipsService
,
new
SyncDescriptor
(
ExtensionTipsService
));
services
.
set
(
ICredentialsService
,
new
SyncDescriptor
(
KeytarCredentialsService
));
services
.
set
(
IAuthenticationTokenService
,
new
SyncDescriptor
(
AuthenticationTokenService
));
...
...
@@ -218,6 +220,10 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat
const
diagnosticsChannel
=
new
DiagnosticsChannel
(
diagnosticsService
);
server
.
registerChannel
(
'
diagnostics
'
,
diagnosticsChannel
);
const
extensionTipsService
=
accessor
.
get
(
IExtensionTipsService
);
const
extensionTipsChannel
=
new
ExtensionTipsChannel
(
extensionTipsService
);
server
.
registerChannel
(
'
extensionTipsService
'
,
extensionTipsChannel
);
const
authTokenService
=
accessor
.
get
(
IAuthenticationTokenService
);
const
authTokenChannel
=
new
AuthenticationTokenServiceChannel
(
authTokenService
);
server
.
registerChannel
(
'
authToken
'
,
authTokenChannel
);
...
...
src/vs/platform/extensionManagement/common/extensionManagement.ts
浏览文件 @
288445a5
...
...
@@ -10,6 +10,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
CancellationToken
}
from
'
vs/base/common/cancellation
'
;
import
{
IExtensionManifest
,
IExtension
,
ExtensionType
}
from
'
vs/platform/extensions/common/extensions
'
;
import
{
IExeBasedExtensionTip
}
from
'
vs/platform/product/common/productService
'
;
export
const
EXTENSION_IDENTIFIER_PATTERN
=
'
^([a-z0-9A-Z][a-z0-9
\
-A-Z]*)
\\
.([a-z0-9A-Z][a-z0-9
\
-A-Z]*)$
'
;
export
const
EXTENSION_IDENTIFIER_REGEX
=
new
RegExp
(
EXTENSION_IDENTIFIER_PATTERN
);
...
...
@@ -221,6 +222,18 @@ export interface IGlobalExtensionEnablementService {
}
export
type
IExecutableBasedExtensionTip
=
{
extensionId
:
string
}
&
Omit
<
Omit
<
IExeBasedExtensionTip
,
'
recommendations
'
>
,
'
important
'
>
;
export
const
IExtensionTipsService
=
createDecorator
<
IExtensionTipsService
>
(
'
IExtensionTipsService
'
);
export
interface
IExtensionTipsService
{
_serviceBrand
:
undefined
;
getImportantExecutableBasedTips
():
Promise
<
IExecutableBasedExtensionTip
[]
>
;
getOtherExecutableBasedTips
():
Promise
<
IExecutableBasedExtensionTip
[]
>
;
}
export
const
ExtensionsLabel
=
localize
(
'
extensions
'
,
"
Extensions
"
);
export
const
ExtensionsChannelId
=
'
extensions
'
;
export
const
PreferencesLabel
=
localize
(
'
preferences
'
,
"
Preferences
"
);
src/vs/platform/extensionManagement/common/extensionManagementIpc.ts
浏览文件 @
288445a5
...
...
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import
{
IChannel
,
IServerChannel
}
from
'
vs/base/parts/ipc/common/ipc
'
;
import
{
IExtensionManagementService
,
ILocalExtension
,
InstallExtensionEvent
,
DidInstallExtensionEvent
,
IGalleryExtension
,
DidUninstallExtensionEvent
,
IExtensionIdentifier
,
IGalleryMetadata
,
IReportedExtension
}
from
'
vs/platform/extensionManagement/common/extensionManagement
'
;
import
{
IExtensionManagementService
,
ILocalExtension
,
InstallExtensionEvent
,
DidInstallExtensionEvent
,
IGalleryExtension
,
DidUninstallExtensionEvent
,
IExtensionIdentifier
,
IGalleryMetadata
,
IReportedExtension
,
IExtensionTipsService
}
from
'
vs/platform/extensionManagement/common/extensionManagement
'
;
import
{
Event
}
from
'
vs/base/common/event
'
;
import
{
URI
,
UriComponents
}
from
'
vs/base/common/uri
'
;
import
{
IURITransformer
,
DefaultURITransformer
,
transformAndReviveIncomingURIs
}
from
'
vs/base/common/uriIpc
'
;
...
...
@@ -130,3 +130,22 @@ export class ExtensionManagementChannelClient implements IExtensionManagementSer
return
Promise
.
resolve
(
this
.
channel
.
call
(
'
getExtensionsReport
'
));
}
}
export
class
ExtensionTipsChannel
implements
IServerChannel
{
constructor
(
private
service
:
IExtensionTipsService
)
{
}
listen
(
context
:
any
,
event
:
string
):
Event
<
any
>
{
throw
new
Error
(
'
Invalid listen
'
);
}
call
(
context
:
any
,
command
:
string
,
args
?:
any
):
Promise
<
any
>
{
switch
(
command
)
{
case
'
getImportantExecutableBasedTips
'
:
return
this
.
service
.
getImportantExecutableBasedTips
();
case
'
getOtherExecutableBasedTips
'
:
return
this
.
service
.
getOtherExecutableBasedTips
();
}
throw
new
Error
(
'
Invalid call
'
);
}
}
src/vs/platform/extensionManagement/node/extensionTipsService.ts
0 → 100644
浏览文件 @
288445a5
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
join
,
}
from
'
vs/base/common/path
'
;
import
{
IProductService
,
IExeBasedExtensionTip
}
from
'
vs/platform/product/common/productService
'
;
import
{
IEnvironmentService
}
from
'
vs/platform/environment/common/environment
'
;
import
{
env
as
processEnv
}
from
'
vs/base/common/process
'
;
import
{
INativeEnvironmentService
}
from
'
vs/platform/environment/node/environmentService
'
;
import
{
IFileService
}
from
'
vs/platform/files/common/files
'
;
import
{
isWindows
}
from
'
vs/base/common/platform
'
;
import
{
isNonEmptyArray
}
from
'
vs/base/common/arrays
'
;
import
{
IExtensionTipsService
,
IExecutableBasedExtensionTip
}
from
'
vs/platform/extensionManagement/common/extensionManagement
'
;
import
{
IStringDictionary
,
forEach
}
from
'
vs/base/common/collections
'
;
export
class
ExtensionTipsService
implements
IExtensionTipsService
{
_serviceBrand
:
any
;
private
readonly
allImportantExecutableTips
:
IStringDictionary
<
IExeBasedExtensionTip
>
=
{};
private
readonly
allOtherExecutableTips
:
IStringDictionary
<
IExeBasedExtensionTip
>
=
{};
constructor
(
@
IFileService
private
readonly
fileService
:
IFileService
,
@
IEnvironmentService
private
readonly
environmentService
:
IEnvironmentService
,
@
IProductService
private
readonly
productService
:
IProductService
,
)
{
if
(
this
.
productService
.
exeBasedExtensionTips
)
{
forEach
(
this
.
productService
.
exeBasedExtensionTips
,
({
key
,
value
})
=>
{
if
(
value
.
important
)
{
this
.
allImportantExecutableTips
[
key
]
=
value
;
}
else
{
this
.
allOtherExecutableTips
[
key
]
=
value
;
}
});
}
}
getImportantExecutableBasedTips
():
Promise
<
IExecutableBasedExtensionTip
[]
>
{
return
this
.
getValidExecutableBasedExtensionTips
(
this
.
allImportantExecutableTips
);
}
getOtherExecutableBasedTips
():
Promise
<
IExecutableBasedExtensionTip
[]
>
{
return
this
.
getValidExecutableBasedExtensionTips
(
this
.
allOtherExecutableTips
);
}
private
async
getValidExecutableBasedExtensionTips
(
executableTips
:
IStringDictionary
<
IExeBasedExtensionTip
>
):
Promise
<
IExecutableBasedExtensionTip
[]
>
{
const
result
:
IExecutableBasedExtensionTip
[]
=
[];
const
checkedExecutables
:
Map
<
string
,
boolean
>
=
new
Map
<
string
,
boolean
>
();
for
(
const
exeName
of
Object
.
keys
(
executableTips
))
{
const
extensionTip
=
executableTips
[
exeName
];
if
(
!
isNonEmptyArray
(
extensionTip
?.
recommendations
))
{
continue
;
}
const
exePaths
:
string
[]
=
[];
if
(
isWindows
)
{
if
(
extensionTip
.
windowsPath
)
{
exePaths
.
push
(
extensionTip
.
windowsPath
.
replace
(
'
%USERPROFILE%
'
,
processEnv
[
'
USERPROFILE
'
]
!
)
.
replace
(
'
%ProgramFiles(x86)%
'
,
processEnv
[
'
ProgramFiles(x86)
'
]
!
)
.
replace
(
'
%ProgramFiles%
'
,
processEnv
[
'
ProgramFiles
'
]
!
)
.
replace
(
'
%APPDATA%
'
,
processEnv
[
'
APPDATA
'
]
!
)
.
replace
(
'
%WINDIR%
'
,
processEnv
[
'
WINDIR
'
]
!
));
}
}
else
{
exePaths
.
push
(
join
(
'
/usr/local/bin
'
,
exeName
));
exePaths
.
push
(
join
((
this
.
environmentService
as
INativeEnvironmentService
).
userHome
.
fsPath
,
exeName
));
}
for
(
const
exePath
of
exePaths
)
{
let
exists
=
checkedExecutables
.
get
(
exePath
);
if
(
exists
===
undefined
)
{
exists
=
await
this
.
fileService
.
exists
(
URI
.
file
(
exePath
));
checkedExecutables
.
set
(
exePath
,
exists
);
}
if
(
exists
)
{
extensionTip
.
recommendations
.
forEach
(
recommendation
=>
result
.
push
({
extensionId
:
recommendation
,
friendlyName
:
extensionTip
.
friendlyName
,
exeFriendlyName
:
extensionTip
.
exeFriendlyName
,
windowsPath
:
extensionTip
.
windowsPath
,
}));
}
}
}
return
result
;
}
}
src/vs/workbench/contrib/extensions/electron-browser/extensionRecommendationsService.ts
浏览文件 @
288445a5
...
...
@@ -5,11 +5,10 @@
import
{
ExtensionRecommendationsService
,
milliSecondsInADay
,
choiceNever
}
from
'
vs/workbench/contrib/extensions/browser/extensionRecommendationsService
'
;
import
{
IExtensionRecommendationsService
,
IWorkbenchExtensionEnablementService
,
ExtensionRecommendationReason
,
IExtensionRecommendation
,
ExtensionRecommendationSource
}
from
'
vs/workbench/services/extensionManagement/common/extensionManagement
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
join
,
basename
}
from
'
vs/base/common/path
'
;
import
{
basename
}
from
'
vs/base/common/path
'
;
import
{
distinct
,
shuffle
}
from
'
vs/base/common/arrays
'
;
import
{
I
ExeBasedExtensionTip
,
I
ProductService
}
from
'
vs/platform/product/common/productService
'
;
import
{
IExtensionGalleryService
,
IExtensionManagementService
}
from
'
vs/platform/extensionManagement/common/extensionManagement
'
;
import
{
IProductService
}
from
'
vs/platform/product/common/productService
'
;
import
{
IExtensionGalleryService
,
IExtensionManagementService
,
IExtensionTipsService
,
IExecutableBasedExtensionTip
}
from
'
vs/platform/extensionManagement/common/extensionManagement
'
;
import
{
IModelService
}
from
'
vs/editor/common/services/modelService
'
;
import
{
IStorageService
,
StorageScope
}
from
'
vs/platform/storage/common/storage
'
;
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
...
...
@@ -31,10 +30,8 @@ import { ExtensionType } from 'vs/platform/extensions/common/extensions';
import
{
localize
}
from
'
vs/nls
'
;
import
Severity
from
'
vs/base/common/severity
'
;
import
{
InstallRecommendedExtensionAction
,
ShowRecommendedExtensionsAction
}
from
'
vs/workbench/contrib/extensions/browser/extensionsActions
'
;
import
{
forEach
}
from
'
vs/base/common/collections
'
;
import
{
platform
,
env
as
processEnv
}
from
'
vs/base/common/process
'
;
import
{
forEach
,
IStringDictionary
}
from
'
vs/base/common/collections
'
;
import
{
isNumber
}
from
'
vs/base/common/types
'
;
import
{
INativeEnvironmentService
}
from
'
vs/platform/environment/node/environmentService
'
;
interface
IDynamicWorkspaceRecommendations
{
remoteSet
:
string
[];
...
...
@@ -43,8 +40,7 @@ interface IDynamicWorkspaceRecommendations {
export
class
NativeExtensionRecommendationsService
extends
ExtensionRecommendationsService
implements
IExtensionRecommendationsService
{
private
_exeBasedRecommendations
:
{
[
id
:
string
]:
IExeBasedExtensionTip
;
}
=
Object
.
create
(
null
);
private
_importantExeBasedRecommendations
:
{
[
id
:
string
]:
IExeBasedExtensionTip
;
}
=
Object
.
create
(
null
);
private
_exeBasedRecommendations
:
{
[
id
:
string
]:
IExecutableBasedExtensionTip
;
}
=
Object
.
create
(
null
);
private
proactiveRecommendationsFetched
:
boolean
=
false
;
private
_extensionsRecommendationsUrl
:
string
|
undefined
;
private
_dynamicWorkspaceRecommendations
:
string
[]
=
[];
...
...
@@ -71,6 +67,7 @@ export class NativeExtensionRecommendationsService extends ExtensionRecommendati
@
IProductService
productService
:
IProductService
,
@
IRequestService
private
readonly
requestService
:
IRequestService
,
@
IWorkspaceTagsService
private
readonly
workspaceTagsService
:
IWorkspaceTagsService
,
@
IExtensionTipsService
private
readonly
extensionTipsService
:
IExtensionTipsService
,
)
{
super
(
galleryService
,
modelService
,
storageService
,
extensionsService
,
extensionEnablementService
,
instantiationService
,
fileService
,
contextService
,
configurationService
,
telemetryService
,
environmentService
,
extensionService
,
viewletService
,
notificationService
,
extensionManagementService
,
extensionWorkbenchService
,
...
...
@@ -111,14 +108,15 @@ export class NativeExtensionRecommendationsService extends ExtensionRecommendati
if
(
!
this
.
proactiveRecommendationsFetched
)
{
this
.
proactiveRecommendationsFetched
=
true
;
// Executable based recommendations carry out a lot of file stats, delay the resolution so that the startup is not affected
fetchPromise
=
timeout
(
10000
).
then
(()
=>
Promise
.
all
([
this
.
fetchDynamicWorkspaceRecommendations
(),
this
.
fetch
ExecutableRecommendations
(
false
)]));
fetchPromise
=
timeout
(
10000
).
then
(()
=>
Promise
.
all
([
this
.
fetchDynamicWorkspaceRecommendations
(),
this
.
fetch
OtherExeBasedRecommendations
(
)]));
}
return
fetchPromise
;
}
private
async
fetchImportantExeBasedRecommendation
():
Promise
<
void
>
{
await
this
.
fetchExecutableRecommendations
(
true
);
await
this
.
promptForImportantExeBasedExtension
();
const
importantExectuableBasedTips
=
await
this
.
extensionTipsService
.
getImportantExecutableBasedTips
();
importantExectuableBasedTips
.
forEach
(
tip
=>
this
.
_exeBasedRecommendations
[
tip
.
extensionId
.
toLowerCase
()]
=
tip
);
await
this
.
promptForImportantExeBasedExtension
(
importantExectuableBasedTips
);
}
/**
...
...
@@ -209,13 +207,16 @@ export class NativeExtensionRecommendationsService extends ExtensionRecommendati
}
}
private
async
promptForImportantExeBasedExtension
():
Promise
<
boolean
>
{
private
async
promptForImportantExeBasedExtension
(
importantExectuableBasedTips
:
IExecutableBasedExtensionTip
[]
):
Promise
<
boolean
>
{
let
recommendationsToSuggest
=
Object
.
keys
(
this
.
_importantExeBasedRecommendations
);
const
importantExeBasedRecommendations
:
IStringDictionary
<
IExecutableBasedExtensionTip
>
=
{};
importantExectuableBasedTips
.
forEach
(
tip
=>
importantExeBasedRecommendations
[
tip
.
extensionId
.
toLowerCase
()]
=
tip
);
let
recommendationsToSuggest
=
Object
.
keys
(
importantExeBasedRecommendations
);
const
installed
=
await
this
.
extensionManagementService
.
getInstalled
(
ExtensionType
.
User
);
recommendationsToSuggest
=
this
.
filterInstalled
(
recommendationsToSuggest
,
installed
,
(
extensionId
)
=>
{
const
tip
=
this
.
_
importantExeBasedRecommendations
[
extensionId
];
const
tip
=
importantExeBasedRecommendations
[
extensionId
];
/* __GDPR__
"exeExtensionRecommendations:alreadyInstalled" : {
...
...
@@ -232,7 +233,7 @@ export class NativeExtensionRecommendationsService extends ExtensionRecommendati
}
for
(
const
extensionId
of
recommendationsToSuggest
)
{
const
tip
=
this
.
_
importantExeBasedRecommendations
[
extensionId
];
const
tip
=
importantExeBasedRecommendations
[
extensionId
];
/* __GDPR__
"exeExtensionRecommendations:notInstalled" : {
...
...
@@ -259,7 +260,7 @@ export class NativeExtensionRecommendationsService extends ExtensionRecommendati
}
const
extensionId
=
recommendationsToSuggest
[
0
];
const
tip
=
this
.
_
importantExeBasedRecommendations
[
extensionId
];
const
tip
=
importantExeBasedRecommendations
[
extensionId
];
const
message
=
localize
(
'
exeRecommended
'
,
"
The '{0}' extension is recommended as you have {1} installed on your system.
"
,
tip
.
friendlyName
!
,
tip
.
exeFriendlyName
||
basename
(
tip
.
windowsPath
!
));
this
.
notificationService
.
prompt
(
Severity
.
Info
,
message
,
...
...
@@ -332,59 +333,9 @@ export class NativeExtensionRecommendationsService extends ExtensionRecommendati
return
true
;
}
/**
* If user has any of the tools listed in this.productService.exeBasedExtensionTips, fetch corresponding recommendations
*/
private
async
fetchExecutableRecommendations
(
important
:
boolean
):
Promise
<
void
>
{
if
(
!
this
.
productService
.
exeBasedExtensionTips
)
{
return
;
}
const
foundExecutables
:
Set
<
string
>
=
new
Set
<
string
>
();
const
findExecutable
=
(
exeName
:
string
,
tip
:
IExeBasedExtensionTip
,
path
:
string
)
=>
{
return
this
.
fileService
.
exists
(
URI
.
file
(
path
)).
then
(
exists
=>
{
if
(
exists
&&
!
foundExecutables
.
has
(
exeName
))
{
foundExecutables
.
add
(
exeName
);
(
tip
[
'
recommendations
'
]
||
[]).
forEach
(
extensionId
=>
{
if
(
tip
.
friendlyName
)
{
if
(
important
)
{
this
.
_importantExeBasedRecommendations
[
extensionId
.
toLowerCase
()]
=
tip
;
}
this
.
_exeBasedRecommendations
[
extensionId
.
toLowerCase
()]
=
tip
;
}
});
}
});
};
const
promises
:
Promise
<
void
>
[]
=
[];
// Loop through recommended extensions
forEach
(
this
.
productService
.
exeBasedExtensionTips
,
entry
=>
{
if
(
typeof
entry
.
value
!==
'
object
'
||
!
Array
.
isArray
(
entry
.
value
[
'
recommendations
'
]))
{
return
;
}
if
(
important
!==
!!
entry
.
value
.
important
)
{
return
;
}
const
exeName
=
entry
.
key
;
if
(
platform
===
'
win32
'
)
{
let
windowsPath
=
entry
.
value
[
'
windowsPath
'
];
if
(
!
windowsPath
||
typeof
windowsPath
!==
'
string
'
)
{
return
;
}
windowsPath
=
windowsPath
.
replace
(
'
%USERPROFILE%
'
,
processEnv
[
'
USERPROFILE
'
]
!
)
.
replace
(
'
%ProgramFiles(x86)%
'
,
processEnv
[
'
ProgramFiles(x86)
'
]
!
)
.
replace
(
'
%ProgramFiles%
'
,
processEnv
[
'
ProgramFiles
'
]
!
)
.
replace
(
'
%APPDATA%
'
,
processEnv
[
'
APPDATA
'
]
!
)
.
replace
(
'
%WINDIR%
'
,
processEnv
[
'
WINDIR
'
]
!
);
promises
.
push
(
findExecutable
(
exeName
,
entry
.
value
,
windowsPath
));
}
else
{
promises
.
push
(
findExecutable
(
exeName
,
entry
.
value
,
join
(
'
/usr/local/bin
'
,
exeName
)));
promises
.
push
(
findExecutable
(
exeName
,
entry
.
value
,
join
((
this
.
environmentService
as
INativeEnvironmentService
).
userHome
.
fsPath
,
exeName
)));
}
});
await
Promise
.
all
(
promises
);
private
async
fetchOtherExeBasedRecommendations
():
Promise
<
void
>
{
const
otherExectuableBasedTips
=
await
this
.
extensionTipsService
.
getOtherExecutableBasedTips
();
otherExectuableBasedTips
.
forEach
(
tip
=>
this
.
_exeBasedRecommendations
[
tip
.
extensionId
.
toLowerCase
()]
=
tip
);
}
getAllRecommendationsWithReason
():
{
[
id
:
string
]:
{
reasonId
:
ExtensionRecommendationReason
,
reasonText
:
string
};
}
{
...
...
src/vs/workbench/services/extensionManagement/common/extensionTipsService.ts
0 → 100644
浏览文件 @
288445a5
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
registerSingleton
}
from
'
vs/platform/instantiation/common/extensions
'
;
import
{
IExtensionTipsService
,
IExecutableBasedExtensionTip
}
from
'
vs/platform/extensionManagement/common/extensionManagement
'
;
class
WebExtensionTipsService
implements
IExtensionTipsService
{
_serviceBrand
:
any
;
constructor
()
{
}
async
getImportantExecutableBasedTips
():
Promise
<
IExecutableBasedExtensionTip
[]
>
{
return
[];
}
async
getOtherExecutableBasedTips
():
Promise
<
IExecutableBasedExtensionTip
[]
>
{
return
[];
}
}
registerSingleton
(
IExtensionTipsService
,
WebExtensionTipsService
);
src/vs/workbench/services/extensionManagement/electron-browser/extensionTipsService.ts
0 → 100644
浏览文件 @
288445a5
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
registerSingleton
}
from
'
vs/platform/instantiation/common/extensions
'
;
import
{
ISharedProcessService
}
from
'
vs/platform/ipc/electron-browser/sharedProcessService
'
;
import
{
IChannel
}
from
'
vs/base/parts/ipc/common/ipc
'
;
import
{
IExtensionTipsService
,
IExecutableBasedExtensionTip
}
from
'
vs/platform/extensionManagement/common/extensionManagement
'
;
class
NativeExtensionTipsService
implements
IExtensionTipsService
{
_serviceBrand
:
any
;
private
readonly
channel
:
IChannel
;
constructor
(
@
ISharedProcessService
sharedProcessService
:
ISharedProcessService
)
{
this
.
channel
=
sharedProcessService
.
getChannel
(
'
extensionTipsService
'
);
}
getImportantExecutableBasedTips
():
Promise
<
IExecutableBasedExtensionTip
[]
>
{
return
this
.
channel
.
call
<
IExecutableBasedExtensionTip
[]
>
(
'
getImportantExecutableBasedTips
'
);
}
getOtherExecutableBasedTips
():
Promise
<
IExecutableBasedExtensionTip
[]
>
{
return
this
.
channel
.
call
<
IExecutableBasedExtensionTip
[]
>
(
'
getOtherExecutableBasedTips
'
);
}
}
registerSingleton
(
IExtensionTipsService
,
NativeExtensionTipsService
);
src/vs/workbench/workbench.desktop.main.ts
浏览文件 @
288445a5
...
...
@@ -39,6 +39,7 @@ import 'vs/workbench/services/keybinding/electron-browser/keybinding.contributio
import
'
vs/workbench/services/extensions/electron-browser/extensionService
'
;
import
'
vs/workbench/services/contextmenu/electron-browser/contextmenuService
'
;
import
'
vs/workbench/services/extensionManagement/electron-browser/extensionManagementServerService
'
;
import
'
vs/workbench/services/extensionManagement/electron-browser/extensionTipsService
'
;
import
'
vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl
'
;
import
'
vs/workbench/services/telemetry/electron-browser/telemetryService
'
;
import
'
vs/workbench/services/configurationResolver/electron-browser/configurationResolverService
'
;
...
...
src/vs/workbench/workbench.web.main.ts
浏览文件 @
288445a5
...
...
@@ -34,6 +34,7 @@ import 'vs/workbench/services/textfile/browser/browserTextFileService';
import
'
vs/workbench/services/keybinding/browser/keymapService
'
;
import
'
vs/workbench/services/extensions/browser/extensionService
'
;
import
'
vs/workbench/services/extensionManagement/common/extensionManagementServerService
'
;
import
'
vs/workbench/services/extensionManagement/common/extensionTipsService
'
;
import
'
vs/workbench/services/telemetry/browser/telemetryService
'
;
import
'
vs/workbench/services/configurationResolver/browser/configurationResolverService
'
;
import
'
vs/workbench/services/credentials/browser/credentialsService
'
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录