!6 添加更新升级模块

Merge pull request !6 from mcy-kylin/master
This commit is contained in:
mcy-kylin 2023-11-24 01:01:13 +00:00 committed by wangpenglong
parent 2a8d743165
commit 2e99a00dd6
5 changed files with 145 additions and 39 deletions

View File

@ -91,6 +91,7 @@
"https://open-vsx.org" "https://open-vsx.org"
], ],
"helpDocUrl":"https://gitee.com/openkylin/extensions-repo/blob/master/user-guide/%E7%9B%AE%E5%BD%95.md", "helpDocUrl":"https://gitee.com/openkylin/extensions-repo/blob/master/user-guide/%E7%9B%AE%E5%BD%95.md",
"updateCheckUrl":"https://kylinhorn.cn/updateCheck/kylincode",
"extensionsControlManifest":{ "extensionsControlManifest":{
"malicious": [], "malicious": [],
"deprecated": { "deprecated": {

View File

@ -150,7 +150,7 @@ export interface IProductConfiguration {
readonly showTelemetryOptOut?: boolean; readonly showTelemetryOptOut?: boolean;
readonly helpDocUrl?: string; readonly helpDocUrl?: string;
readonly updateCheckUrl?: string;
readonly serverGreeting?: string[]; readonly serverGreeting?: string[];
readonly serverLicense?: string[]; readonly serverLicense?: string[];
readonly serverLicensePrompt?: string; readonly serverLicensePrompt?: string;

View File

@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { isWeb, isWindows } from 'vs/base/common/platform'; // import { isWeb, isWindows } from 'vs/base/common/platform';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
import { ConfigurationScope, Extensions as ConfigurationExtensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; import { ConfigurationScope, Extensions as ConfigurationExtensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
import { Registry } from 'vs/platform/registry/common/platform'; import { Registry } from 'vs/platform/registry/common/platform';
@ -17,39 +17,39 @@ configurationRegistry.registerConfiguration({
properties: { properties: {
'update.mode': { 'update.mode': {
type: 'string', type: 'string',
enum: ['none', 'manual', 'start', 'default'], enum: ['enable', 'disable'],
default: 'none', default: 'enable',
scope: ConfigurationScope.APPLICATION, scope: ConfigurationScope.APPLICATION,
description: localize('updateMode', "Configure whether you receive automatic updates. Requires a restart after change. The updates are fetched from a Microsoft online service."), description: localize('updateMode', "Configure whether you receive automatic updates. Requires a restart after change. The updates are fetched from a Kylin online service.").replace('微软', 'Kylin'),
tags: ['usesOnlineServices'], tags: ['usesOnlineServices'],
enumDescriptions: [ enumDescriptions: [
localize('none', "Disable updates."), localize('enable', "Enable updates."),
localize('manual', "Disable automatic background update checks. Updates will be available if you manually check for updates."), localize('disable', "Disable automatic background update checks."),
localize('start', "Check for updates only on startup. Disable automatic background update checks."), // localize('start', "Check for updates only on startup. Disable automatic background update checks."),
localize('default', "Enable automatic update checks. Code will check for updates automatically and periodically.") // localize('default', "Enable automatic update checks. Code will check for updates automatically and periodically.")
] ]
}, },
'update.channel': { // 'update.channel': {
type: 'string', // type: 'string',
default: 'default', // default: 'default',
scope: ConfigurationScope.APPLICATION, // scope: ConfigurationScope.APPLICATION,
description: localize('updateMode', "Configure whether you receive automatic updates. Requires a restart after change. The updates are fetched from a Microsoft online service."), // description: localize('updateMode', "Configure whether you receive automatic updates. Requires a restart after change. The updates are fetched from a Microsoft online service."),
deprecationMessage: localize('deprecated', "This setting is deprecated, please use '{0}' instead.", 'update.mode') // deprecationMessage: localize('deprecated', "This setting is deprecated, please use '{0}' instead.", 'update.mode')
}, // },
'update.enableWindowsBackgroundUpdates': { // 'update.enableWindowsBackgroundUpdates': {
type: 'boolean', // type: 'boolean',
default: true, // default: true,
scope: ConfigurationScope.APPLICATION, // scope: ConfigurationScope.APPLICATION,
title: localize('enableWindowsBackgroundUpdatesTitle', "Enable Background Updates on Windows"), // title: localize('enableWindowsBackgroundUpdatesTitle', "Enable Background Updates on Windows"),
description: localize('enableWindowsBackgroundUpdates', "Enable to download and install new VS Code versions in the background on Windows."), // description: localize('enableWindowsBackgroundUpdates', "Enable to download and install new versions in the background on Windows."),
included: isWindows && !isWeb // included: isWindows && !isWeb
}, // },
'update.showReleaseNotes': { // 'update.showReleaseNotes': {
type: 'boolean', // type: 'boolean',
default: false, // default: false,
scope: ConfigurationScope.APPLICATION, // scope: ConfigurationScope.APPLICATION,
description: localize('showReleaseNotes', "Show Release Notes after an update. The Release Notes are fetched from a Microsoft online service."), // description: localize('showReleaseNotes', "Show Release Notes after an update. The Release Notes are fetched from a Microsoft online service."),
tags: ['usesOnlineServices'] // tags: ['usesOnlineServices']
} // }
} }
}); });

View File

@ -89,13 +89,13 @@ export abstract class AbstractUpdateService implements IUpdateService {
this.setState(State.Idle(this.getUpdateType())); this.setState(State.Idle(this.getUpdateType()));
if (updateMode === 'manual') { if (updateMode === 'disable') {
this.logService.info('update#ctor - manual checks only; automatic updates are disabled by user preference'); this.logService.info('update#ctor - ; automatic updates are disabled by user preference');
return; return;
} }
if (updateMode === 'start') { if (updateMode === 'enable') {
this.logService.info('update#ctor - startup checks only; automatic updates are disabled by user preference'); this.logService.info('update#ctor - checks enable; automatic updates are disabled by user preference');
// Check for updates only once after 30 seconds // Check for updates only once after 30 seconds
setTimeout(() => this.checkForUpdates(false), 30 * 1000); setTimeout(() => this.checkForUpdates(false), 30 * 1000);
@ -105,8 +105,8 @@ export abstract class AbstractUpdateService implements IUpdateService {
} }
} }
protected getUpdateMode(): 'none' | 'manual' | 'start' | 'default' { protected getUpdateMode(): 'enable' | 'disable' {
return getMigratedSettingValue<'none' | 'manual' | 'start' | 'default'>(this.configurationService, 'update.mode', 'update.channel'); return getMigratedSettingValue<'enable' | 'disable'>(this.configurationService, 'update.mode', 'update.channel');
} }
private getProductQuality(updateMode: string): string | undefined { private getProductQuality(updateMode: string): string | undefined {
@ -189,7 +189,7 @@ export abstract class AbstractUpdateService implements IUpdateService {
const mode = await this.getUpdateMode(); const mode = await this.getUpdateMode();
if (mode === 'none') { if (mode === 'disable') {
return false; return false;
} }

View File

@ -8,7 +8,7 @@ import { URI } from 'vs/base/common/uri';
import { onUnexpectedError } from 'vs/base/common/errors'; import { onUnexpectedError } from 'vs/base/common/errors';
import { equals } from 'vs/base/common/objects'; import { equals } from 'vs/base/common/objects';
import { EventType, EventHelper, addDisposableListener, scheduleAtNextAnimationFrame, ModifierKeyEmitter } from 'vs/base/browser/dom'; import { EventType, EventHelper, addDisposableListener, scheduleAtNextAnimationFrame, ModifierKeyEmitter } from 'vs/base/browser/dom';
import { Separator, WorkbenchActionExecutedClassification, WorkbenchActionExecutedEvent } from 'vs/base/common/actions'; import { Separator, WorkbenchActionExecutedClassification, WorkbenchActionExecutedEvent, Action } from 'vs/base/common/actions';
import { IFileService } from 'vs/platform/files/common/files'; import { IFileService } from 'vs/platform/files/common/files';
import { EditorResourceAccessor, IUntitledTextResourceEditorInput, SideBySideEditor, pathsToEditors, IResourceDiffEditorInput, IUntypedEditorInput } from 'vs/workbench/common/editor'; import { EditorResourceAccessor, IUntitledTextResourceEditorInput, SideBySideEditor, pathsToEditors, IResourceDiffEditorInput, IUntypedEditorInput } from 'vs/workbench/common/editor';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
@ -65,6 +65,7 @@ import { toErrorMessage } from 'vs/base/common/errorMessage';
import { registerWindowDriver } from 'vs/platform/driver/electron-sandbox/driver'; import { registerWindowDriver } from 'vs/platform/driver/electron-sandbox/driver';
import { ILabelService } from 'vs/platform/label/common/label'; import { ILabelService } from 'vs/platform/label/common/label';
import { dirname } from 'vs/base/common/resources'; import { dirname } from 'vs/base/common/resources';
import { Codicon } from 'vs/base/common/codicons';
export class NativeWindow extends Disposable { export class NativeWindow extends Disposable {
@ -655,6 +656,110 @@ export class NativeWindow extends Disposable {
if (this.environmentService.enableSmokeTestDriver) { if (this.environmentService.enableSmokeTestDriver) {
this.setupDriver(); this.setupDriver();
} }
this.updateCheck();
}
private async updateCheck() {
// add kylin team
let notificationService = this.notificationService;
let configurationService = this.configurationService;
let storageService = this.storageService;
let productService = this.productService;
if (!productService.IDEVersion || !productService.updateCheckUrl) {
return;
}
let updateInfoRequest = (id: string, drunk: string) => {
let httpRequest = new XMLHttpRequest();
const url = productService.updateCheckUrl + `/${id}` + `?data=${drunk}`;
httpRequest.open('GET', url, true);
httpRequest.send();
httpRequest.onreadystatechange = function () {
if (httpRequest.readyState == 4 && httpRequest.status == 200) {
let json = httpRequest.responseText;
try {
let version = '';
let obj = JSON.parse(json);
if (obj?.ret === 0) {
if (typeof (obj.data) === 'string') {
let vobj = JSON.parse(obj.data);
if (vobj) version = vobj.version as string;
} else if (typeof (obj.data) === 'object') {
version = obj.data.version;
}
console.log(`Update request success, ret = 0, version is ${version} obj ${obj?.data} = ${JSON.stringify(json)}`);
if (version > productService.IDEVersion) {
let ncheck = storageService.get('updatenotcheck', StorageScope.GLOBAL);
if (ncheck === 'true') {
return;
}
notificationService.notify({
severity: Severity.Info,
message: `当前Kylin-Code发布了新版本可以尝试新版本。`,
actions: {
primary: [new Action('updatecheck', `不再提示`, Codicon.check.classNames, true, () => {
storageService.store('updatenotcheck', 'true', StorageScope.GLOBAL, StorageTarget.MACHINE);
})],
}
});
}
}
} catch (error) {
console.warn(`Update check request failed, status error...`);
}
} else {
console.warn(`Update check request, status ${httpRequest.status}...`);
}
};
}
let sign = this.environmentService.machineId + this.environmentService.userHome + this.environmentService.os.release;
const gensha1 = async (s: string) => {
const encoder = new TextEncoder();
const hash = await crypto.subtle.digest('sha-1', encoder.encode(sign));
return [...new Uint8Array(hash)]
.map(x => x.toString(16).padStart(2, '0'))
.join('');
}
let identifyID = await gensha1(sign);
this._register(configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration('update.mode')) { // 修改更新配置
let mod = configurationService.getValue<string>('update.mode');
if (mod === 'enable') {
console.log(`Enable update version request...`);
storageService.store('updatenotcheck', 'false', StorageScope.GLOBAL, StorageTarget.MACHINE);
}
}
}));
setInterval(() => {
let checked = configurationService.getValue<string>('update.mode');
if (checked === 'disable') {
return;
}
// 根据storage中的时间戳判断是否发送请求 间隔天则发送升级
let uInfo = storageService.get(`updateCheckInfo`, StorageScope.GLOBAL);
if (uInfo) {
let objTmp = JSON.parse(uInfo);
if (objTmp?.date) {
if (new Date(objTmp.date).toDateString() === new Date().toDateString()) {
// console.log('update check date once.');
return; // 一天发送一次
}
}
}
// 更新时间
let tmp = JSON.stringify({
'date': new Date().toDateString()
})
let typeC = 'kylincode';
let index = productService.updateCheckUrl?.lastIndexOf("\/");
if (index) {
typeC = productService.updateCheckUrl?.substring(index + 1, productService.updateCheckUrl?.length) as string;
}
storageService.store(`updateCheckInfo`, `${tmp}`, StorageScope.GLOBAL, StorageTarget.MACHINE);
updateInfoRequest(identifyID, JSON.stringify({ // 发送更新
currentVersion: productService.IDEVersion,
from: typeC
}));
}, 20000);
} }
private setupDriver(): void { private setupDriver(): void {