Compare commits
No commits in common. "default" and "v1.0.0" have entirely different histories.
23
.github/workflows/pack.yml
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
name: Build Pack
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
jobs:
|
||||||
|
pack:
|
||||||
|
runs-on: ${{matrix.os}}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ windows-latest, macOS-latest]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Install and Pack
|
||||||
|
run: |
|
||||||
|
npm install
|
||||||
|
npm run pack
|
||||||
|
- name: Upload file
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: packs
|
||||||
|
path: |
|
||||||
|
*
|
30
.gitignore
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.js
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build-web
|
||||||
|
/build-electron
|
||||||
|
/build
|
||||||
|
/dist
|
||||||
|
/packs
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
yarn.lock
|
||||||
|
package-lock.json
|
||||||
|
|
||||||
|
.parcel-cache
|
0
.prettierignore
Normal file
15
.prettierrc
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all",
|
||||||
|
"printWidth": 100,
|
||||||
|
"proseWrap": "never",
|
||||||
|
"arrowParens": "avoid",
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": ".prettierrc",
|
||||||
|
"options": {
|
||||||
|
"parser": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -1 +1,3 @@
|
|||||||
|
# 微信视频号下载器
|
||||||
|
|
||||||
|
<img src="https://user-images.githubusercontent.com/11046969/169296046-513b5e3a-a688-4342-9759-eb131ef7e42f.png" width="100" />
|
||||||
|
17
config-overrides.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
const { override, addLessLoader, adjustStyleLoaders } = require('customize-cra');
|
||||||
|
|
||||||
|
module.exports = override(
|
||||||
|
addLessLoader({
|
||||||
|
lessOptions: {
|
||||||
|
javascriptEnabled: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
adjustStyleLoaders(({ use: [, , postcss] }) => {
|
||||||
|
const postcssOptions = postcss.options;
|
||||||
|
postcss.options = { postcssOptions };
|
||||||
|
}),
|
||||||
|
function (config) {
|
||||||
|
config.target = 'electron-renderer';
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
);
|
49
electron/cert.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import CONFIG from './const';
|
||||||
|
import mkdirp from 'mkdirp';
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import { clipboard, dialog } from 'electron';
|
||||||
|
import spawn from 'cross-spawn';
|
||||||
|
|
||||||
|
export function checkCertInstalled() {
|
||||||
|
return fs.existsSync(CONFIG.INSTALL_CERT_FLAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function installCert(checkInstalled = true) {
|
||||||
|
if (checkInstalled && checkCertInstalled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdirp.sync(path.dirname(CONFIG.INSTALL_CERT_FLAG));
|
||||||
|
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
clipboard.writeText(
|
||||||
|
`echo "输入本地登录密码" && sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "${CONFIG.CERT_PUBLIC_PATH}" && touch ${CONFIG.INSTALL_CERT_FLAG} && echo "安装完成"`,
|
||||||
|
);
|
||||||
|
dialog.showMessageBoxSync({
|
||||||
|
type: 'info',
|
||||||
|
message: `命令已复制到剪贴板,粘贴命令到终端并运行以安装并信任证书`,
|
||||||
|
});
|
||||||
|
|
||||||
|
reject();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const result = spawn.sync(CONFIG.WIN_CERT_INSTALL_HELPER, [
|
||||||
|
'-c',
|
||||||
|
'-add',
|
||||||
|
CONFIG.CERT_PUBLIC_PATH,
|
||||||
|
'-s',
|
||||||
|
'root',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (result.stdout.toString().indexOf('Succeeded') > -1) {
|
||||||
|
fs.writeFileSync(CONFIG.INSTALL_CERT_FLAG, '');
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
37
electron/const.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import path from 'path';
|
||||||
|
import isDev from 'electron-is-dev';
|
||||||
|
import url from 'url';
|
||||||
|
import os from 'os';
|
||||||
|
import { app } from 'electron';
|
||||||
|
|
||||||
|
const APP_PATH = app.getAppPath();
|
||||||
|
// 对于一些 shell 去执行的文件,asar 目录下无法使用。配合 extraResources
|
||||||
|
const EXECUTABLE_PATH = path.join(
|
||||||
|
APP_PATH.indexOf('app.asar') > -1
|
||||||
|
? APP_PATH.substring(0, APP_PATH.indexOf('app.asar'))
|
||||||
|
: APP_PATH,
|
||||||
|
'public',
|
||||||
|
);
|
||||||
|
const HOME_PATH = path.join(os.homedir(), '.wechat-video-downloader');
|
||||||
|
|
||||||
|
export default {
|
||||||
|
APP_START_URL: isDev
|
||||||
|
? 'http://localhost:3000'
|
||||||
|
: url.format({
|
||||||
|
pathname: path.join(APP_PATH, './build/index.html'),
|
||||||
|
protocol: 'file:',
|
||||||
|
slashes: true,
|
||||||
|
}),
|
||||||
|
IS_DEV: isDev,
|
||||||
|
EXECUTABLE_PATH,
|
||||||
|
HOME_PATH,
|
||||||
|
CERT_PRIVATE_PATH: path.join(EXECUTABLE_PATH, './keys/private.pem'),
|
||||||
|
CERT_PUBLIC_PATH: path.join(EXECUTABLE_PATH, './keys/public.pem'),
|
||||||
|
INSTALL_CERT_FLAG: path.join(HOME_PATH, './installed.lock'),
|
||||||
|
WIN_CERT_INSTALL_HELPER: path.join(EXECUTABLE_PATH, './w_c.exe'),
|
||||||
|
APP_CN_NAME: '微信视频号下载器',
|
||||||
|
APP_EN_NAME: 'WeChat Video Downloader',
|
||||||
|
REGEDIT_VBS_PATH: path.join(EXECUTABLE_PATH, './regedit-vbs'),
|
||||||
|
OPEN_SSL_BIN_PATH: path.join(EXECUTABLE_PATH, './openssl/openssl.exe'),
|
||||||
|
OPEN_SSL_CNF_PATH: path.join(EXECUTABLE_PATH, './openssl/openssl.cnf'),
|
||||||
|
};
|
49
electron/index.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import { app, BrowserWindow, Menu } from 'electron';
|
||||||
|
import CONFIG from './const';
|
||||||
|
import { checkUpdate } from './utils';
|
||||||
|
import initIPC, { setWin } from './ipc';
|
||||||
|
|
||||||
|
app.commandLine.appendSwitch('--no-proxy-server');
|
||||||
|
process.on('uncaughtException', () => {});
|
||||||
|
process.on('unhandledRejection', () => {});
|
||||||
|
|
||||||
|
function createWindow() {
|
||||||
|
Menu.setApplicationMenu(null);
|
||||||
|
checkUpdate(
|
||||||
|
'https://cdn.jsdelivr.net/gh/lecepin/WeChatVideoDownloader/package.json',
|
||||||
|
'https://github.com/lecepin/WeChatVideoDownloader/releases',
|
||||||
|
);
|
||||||
|
|
||||||
|
const mainWindow = new BrowserWindow({
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
// resizable: false,
|
||||||
|
// maximizable: false,
|
||||||
|
webPreferences: {
|
||||||
|
webSecurity: false,
|
||||||
|
nodeIntegration: true,
|
||||||
|
contextIsolation: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
setWin(mainWindow);
|
||||||
|
mainWindow.loadURL(CONFIG.APP_START_URL);
|
||||||
|
CONFIG.IS_DEV && mainWindow.webContents.openDevTools();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.whenReady().then(() => {
|
||||||
|
initIPC();
|
||||||
|
createWindow();
|
||||||
|
|
||||||
|
app.on('activate', () => {
|
||||||
|
if (BrowserWindow.getAllWindows().length === 0) {
|
||||||
|
createWindow();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.on('window-all-closed', () => {
|
||||||
|
if (process.platform !== 'darwin') {
|
||||||
|
app.quit();
|
||||||
|
}
|
||||||
|
});
|
58
electron/ipc.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import { ipcMain, dialog } from 'electron';
|
||||||
|
import log from 'electron-log';
|
||||||
|
import { throttle } from 'lodash';
|
||||||
|
import { startServer } from './proxyServer';
|
||||||
|
import { installCert, checkCertInstalled } from './cert';
|
||||||
|
import { downloadFile } from './utils';
|
||||||
|
|
||||||
|
let win;
|
||||||
|
|
||||||
|
export default function initIPC() {
|
||||||
|
ipcMain.handle('invoke_初始化信息', async (event, arg) => {
|
||||||
|
return checkCertInstalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('invoke_开始初始化', (event, arg) => {
|
||||||
|
return installCert(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('invoke_启动服务', async (event, arg) => {
|
||||||
|
return startServer({
|
||||||
|
interceptCallback: phase => async (req, res) => {
|
||||||
|
if (phase === 'response' && res?._data?.headers?.['content-type'] == 'video/mp4') {
|
||||||
|
win?.webContents?.send?.('VIDEO_CAPTURE', {
|
||||||
|
url: req.fullUrl(),
|
||||||
|
size: res?._data?.headers?.['content-length'] ?? 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setProxyErrorCallback: err => {
|
||||||
|
console.log('开启代理失败', err);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('invoke_选择下载位置', async (event, arg) => {
|
||||||
|
const result = dialog.showOpenDialogSync({ title: '保存', properties: ['openDirectory'] });
|
||||||
|
|
||||||
|
if (!result?.[0]) {
|
||||||
|
throw '取消';
|
||||||
|
}
|
||||||
|
|
||||||
|
return result?.[0];
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('invoke_下载视频', async (event, { url, savePath }) => {
|
||||||
|
return downloadFile(
|
||||||
|
url,
|
||||||
|
`${savePath}/${Date.now()}.mp4`,
|
||||||
|
throttle(value => win?.webContents?.send?.('e_进度变化', value), 1000),
|
||||||
|
).catch(err => {
|
||||||
|
console;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setWin(w) {
|
||||||
|
win = w;
|
||||||
|
}
|
64
electron/proxyServer.js
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import hoxy from 'hoxy';
|
||||||
|
import getPort from 'get-port';
|
||||||
|
import log from 'electron-log';
|
||||||
|
import { app } from 'electron';
|
||||||
|
import CONFIG from './const';
|
||||||
|
import { setProxy, closeProxy } from './setProxy';
|
||||||
|
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
process.env.OPENSSL_BIN = CONFIG.OPEN_SSL_BIN_PATH;
|
||||||
|
process.env.OPENSSL_CONF = CONFIG.OPEN_SSL_CNF_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function startServer({
|
||||||
|
interceptCallback = f => f => f,
|
||||||
|
setProxyErrorCallback = f => f,
|
||||||
|
}) {
|
||||||
|
const port = await getPort();
|
||||||
|
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
const proxy = hoxy
|
||||||
|
.createServer({
|
||||||
|
certAuthority: {
|
||||||
|
key: fs.readFileSync(CONFIG.CERT_PRIVATE_PATH),
|
||||||
|
cert: fs.readFileSync(CONFIG.CERT_PUBLIC_PATH),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.listen(port, () => {
|
||||||
|
setProxy('127.0.0.1', port)
|
||||||
|
.then(() => resolve())
|
||||||
|
.catch(() => {
|
||||||
|
setProxyErrorCallback(data);
|
||||||
|
reject('设置代理失败');
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.on('error', err => {
|
||||||
|
log.log('proxy err', err);
|
||||||
|
});
|
||||||
|
|
||||||
|
proxy.intercept(
|
||||||
|
{
|
||||||
|
phase: 'request',
|
||||||
|
},
|
||||||
|
interceptCallback('request'),
|
||||||
|
);
|
||||||
|
|
||||||
|
proxy.intercept(
|
||||||
|
{
|
||||||
|
phase: 'response',
|
||||||
|
},
|
||||||
|
interceptCallback('response'),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
app.on('before-quit', async e => {
|
||||||
|
e.preventDefault();
|
||||||
|
try {
|
||||||
|
await closeProxy();
|
||||||
|
console.log('close proxy success');
|
||||||
|
} catch (error) {}
|
||||||
|
|
||||||
|
app.exit();
|
||||||
|
});
|
109
electron/setProxy.js
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
import { exec } from 'child_process';
|
||||||
|
import regedit from 'regedit';
|
||||||
|
import CONFIG from './const';
|
||||||
|
|
||||||
|
regedit.setExternalVBSLocation(CONFIG.REGEDIT_VBS_PATH);
|
||||||
|
|
||||||
|
export async function setProxy(host, port) {
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
const networks = await getMacAvailableNetworks();
|
||||||
|
|
||||||
|
if (networks.length === 0) {
|
||||||
|
throw 'no network';
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(
|
||||||
|
networks.map(network => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
exec(`networksetup -setsecurewebproxy "${network}" ${host} ${port}`, error => {
|
||||||
|
if (error) {
|
||||||
|
reject(null);
|
||||||
|
} else {
|
||||||
|
resolve(network);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const valuesToPut = {
|
||||||
|
'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings': {
|
||||||
|
ProxyServer: {
|
||||||
|
value: `${host}:${port}`,
|
||||||
|
type: 'REG_SZ',
|
||||||
|
},
|
||||||
|
ProxyEnable: {
|
||||||
|
value: 1,
|
||||||
|
type: 'REG_DWORD',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return regedit.promisified.putValue(valuesToPut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function closeProxy() {
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
const networks = await getMacAvailableNetworks();
|
||||||
|
|
||||||
|
if (networks.length === 0) {
|
||||||
|
throw 'no network';
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(
|
||||||
|
networks.map(network => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
exec(`networksetup -setsecurewebproxystate "${network}" off`, error => {
|
||||||
|
if (error) {
|
||||||
|
reject(null);
|
||||||
|
} else {
|
||||||
|
resolve(network);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const valuesToPut = {
|
||||||
|
'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings': {
|
||||||
|
ProxyEnable: {
|
||||||
|
value: 0,
|
||||||
|
type: 'REG_DWORD',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return regedit.promisified.putValue(valuesToPut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMacAvailableNetworks() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
exec('networksetup -listallnetworkservices', (error, stdout) => {
|
||||||
|
if (error) {
|
||||||
|
reject(error);
|
||||||
|
} else {
|
||||||
|
Promise.all(
|
||||||
|
stdout
|
||||||
|
.toString()
|
||||||
|
.split('\n')
|
||||||
|
.map(network => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
exec(
|
||||||
|
`networksetup getinfo "${network}" | grep "^IP address:\\s\\d"`,
|
||||||
|
(error, stdout) => {
|
||||||
|
if (error) {
|
||||||
|
resolve(null);
|
||||||
|
} else {
|
||||||
|
resolve(stdout ? network : null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
).then(networks => {
|
||||||
|
resolve(networks.filter(Boolean));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
62
electron/utils.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { get } from 'axios';
|
||||||
|
import { app, dialog, shell } from 'electron';
|
||||||
|
import semver from 'semver';
|
||||||
|
import fs from 'fs';
|
||||||
|
|
||||||
|
// packageUrl 需要包含 { "version": "1.0.0" } 结构
|
||||||
|
function checkUpdate(
|
||||||
|
// 可以使用加速地址 https://cdn.jsdelivr.net/gh/lecepin/electron-react-tpl/package.json
|
||||||
|
packageUrl = 'https://raw.githubusercontent.com/lecepin/electron-react-tpl/master/package.json',
|
||||||
|
downloadUrl = 'https://github.com/lecepin/electron-react-tpl/releases',
|
||||||
|
) {
|
||||||
|
get(packageUrl)
|
||||||
|
.then(({ data }) => {
|
||||||
|
if (semver.gt(data?.version, app.getVersion())) {
|
||||||
|
const result = dialog.showMessageBoxSync({
|
||||||
|
message: '发现新版本,是否更新?',
|
||||||
|
type: 'question',
|
||||||
|
cancelId: 1,
|
||||||
|
defaultId: 0,
|
||||||
|
buttons: ['进入新版本下载页面', '取消'],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result === 0 && downloadUrl) {
|
||||||
|
shell.openExternal(downloadUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
function downloadFile(url, fullFileName, progressCallback) {
|
||||||
|
return get(url, {
|
||||||
|
responseType: 'stream',
|
||||||
|
headers: {
|
||||||
|
'User-Agent':
|
||||||
|
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36',
|
||||||
|
},
|
||||||
|
}).then(({ data, headers }) => {
|
||||||
|
let currentLen = 0;
|
||||||
|
const totalLen = headers['content-length'];
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
data.on('data', ({ length }) => {
|
||||||
|
currentLen += length;
|
||||||
|
progressCallback?.(currentLen / totalLen);
|
||||||
|
});
|
||||||
|
|
||||||
|
data.on('error', err => reject(err));
|
||||||
|
|
||||||
|
data.pipe(
|
||||||
|
fs.createWriteStream(fullFileName).on('finish', () => {
|
||||||
|
resolve({
|
||||||
|
fullFileName,
|
||||||
|
totalLen,
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export { checkUpdate, downloadFile };
|
124
package.json
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
{
|
||||||
|
"name": "wechat-video-downloader",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "./build-electron/index.js",
|
||||||
|
"homepage": "./",
|
||||||
|
"scripts": {
|
||||||
|
"postinstall": "husky install",
|
||||||
|
"start": "concurrently \"cross-env BROWSER=none npm run start-web\" \"wait-on http://localhost:3000 && npm run start-electron\" ",
|
||||||
|
"start-debug": "concurrently \"cross-env BROWSER=none npm run start-web\" \"wait-on http://localhost:3000 && npm run debug-electron\" ",
|
||||||
|
"start-web": "react-app-rewired start",
|
||||||
|
"start-electron": "webpack --config webpack.electron.js && electron .",
|
||||||
|
"debug-electron": "webpack --config webpack.electron.js && electron --inspect --unhandled-rejections=strict --trace-deprecation .",
|
||||||
|
"build-web": "react-app-rewired build",
|
||||||
|
"build-electron": "webpack --config webpack.electron.js",
|
||||||
|
"build-all": "rm -rf ./build && rm -rf ./build-electron && npm run build-electron && npm run build-web",
|
||||||
|
"pack": "npm run build-all && electron-builder",
|
||||||
|
"gen-icon": "electron-icon-builder --input=./public/icon/icon.png --output=./public/icon",
|
||||||
|
"pretty": "prettier -c --write \"(src/**/*|electron/**/*)\""
|
||||||
|
},
|
||||||
|
"targets": {
|
||||||
|
"electron": {
|
||||||
|
"source": "electron/index.js",
|
||||||
|
"context": "electron-main",
|
||||||
|
"distDir": "build-electron"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"husky": {
|
||||||
|
"hooks": {
|
||||||
|
"pre-commit": "prettier -c --write \"(src/**/*|electron/**/*)\" && git add -A ."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"concurrently": "^7.1.0",
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
|
"customize-cra": "^1.0.0",
|
||||||
|
"electron": "^18.2.3",
|
||||||
|
"electron-builder": "^23.0.3",
|
||||||
|
"electron-icon-builder": "^2.0.1",
|
||||||
|
"husky": "^8.0.1",
|
||||||
|
"less": "^4.1.2",
|
||||||
|
"less-loader": "^11.0.0",
|
||||||
|
"prettier": "^2.6.2",
|
||||||
|
"react-app-rewired": "^2.2.1",
|
||||||
|
"react-scripts": "5.0.1",
|
||||||
|
"wait-on": "^6.0.1",
|
||||||
|
"webpack": "^5.72.1",
|
||||||
|
"webpack-cli": "^4.9.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@ant-design/icons": "^4.7.0",
|
||||||
|
"@xstate/react": "^3.0.0",
|
||||||
|
"antd": "^4.20.5",
|
||||||
|
"axios": "^0.27.2",
|
||||||
|
"cross-spawn": "^7.0.3",
|
||||||
|
"electron-is-dev": "^2.0.0",
|
||||||
|
"electron-log": "^4.4.7",
|
||||||
|
"get-port": "^6.1.2",
|
||||||
|
"hoxy": "^3.3.1",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"mkdirp": "^1.0.4",
|
||||||
|
"pretty-bytes": "^6.0.0",
|
||||||
|
"react": "^18.1.0",
|
||||||
|
"react-dom": "^18.1.0",
|
||||||
|
"regedit": "5.0.0",
|
||||||
|
"semver": "^7.3.7",
|
||||||
|
"xstate": "^4.32.1"
|
||||||
|
},
|
||||||
|
"author": "lecepin",
|
||||||
|
"license": "ISC",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/lecepin/WeChatVideoDownloader.git"
|
||||||
|
},
|
||||||
|
"build": {
|
||||||
|
"extends": null,
|
||||||
|
"productName": "WeChatVideoDownloader",
|
||||||
|
"appId": "com.lecepin.WeChatVideoDownloader",
|
||||||
|
"directories": {
|
||||||
|
"output": "packs"
|
||||||
|
},
|
||||||
|
"npmRebuild": false,
|
||||||
|
"files": [
|
||||||
|
"build/**/*",
|
||||||
|
"build-electron/**/*",
|
||||||
|
"public/**/*"
|
||||||
|
],
|
||||||
|
"mac": {
|
||||||
|
"icon": "public/icon/icons/mac/icon.icns"
|
||||||
|
},
|
||||||
|
"win": {
|
||||||
|
"target": [
|
||||||
|
{
|
||||||
|
"target": "nsis",
|
||||||
|
"arch": [
|
||||||
|
"ia32"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"icon": "public/icon/icons/win/icon.ico"
|
||||||
|
},
|
||||||
|
"nsis": {
|
||||||
|
"oneClick": false,
|
||||||
|
"perMachine": false,
|
||||||
|
"allowElevation": true,
|
||||||
|
"allowToChangeInstallationDirectory": true
|
||||||
|
},
|
||||||
|
"extraResources": [
|
||||||
|
"public"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"browserslist": {
|
||||||
|
"production": [
|
||||||
|
">0.2%",
|
||||||
|
"not dead",
|
||||||
|
"not op_mini all"
|
||||||
|
],
|
||||||
|
"development": [
|
||||||
|
"last 1 chrome version",
|
||||||
|
"last 1 firefox version",
|
||||||
|
"last 1 safari version"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
BIN
public/icon/icon.png
Normal file
After Width: | Height: | Size: 276 KiB |
BIN
public/icon/icons/mac/icon.icns
Normal file
BIN
public/icon/icons/png/1024x1024.png
Normal file
After Width: | Height: | Size: 265 KiB |
BIN
public/icon/icons/png/128x128.png
Normal file
After Width: | Height: | Size: 9.8 KiB |
BIN
public/icon/icons/png/16x16.png
Normal file
After Width: | Height: | Size: 639 B |
BIN
public/icon/icons/png/24x24.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
public/icon/icons/png/256x256.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
public/icon/icons/png/32x32.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
public/icon/icons/png/48x48.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
public/icon/icons/png/512x512.png
Normal file
After Width: | Height: | Size: 99 KiB |
BIN
public/icon/icons/png/64x64.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
public/icon/icons/win/icon.ico
Normal file
After Width: | Height: | Size: 353 KiB |
12
public/index.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>微信视频号下载器</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
<div id="root"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
27
public/keys/private.key
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEogIBAAKCAQEAsmAqn3hYd/YZcrfgqM1Q6xgHI50EBckbOkfCqTWS1yVFZjLF
|
||||||
|
bMehWb9xGFZJD21A5sxl4xelIWblhety+YTVa/mn2CEJh3je069oeULfXdzhhHyf
|
||||||
|
/ci0IloJhvX+2RJ+176uTKKcWhuOtNVs5VeFoHDoUcISnTqkaVyWeeLfafgrOW7w
|
||||||
|
N8ip128nuBx19ylIygb/DELmjKRRCSpx2vOw2JErTM8L5r0f4eWdqiwBOwu0NHWy
|
||||||
|
Svh9YG8B31UPga4I8FbFhybOP9cQNQPafOSfjwuZoi5CAtyJbwT7KyII9iMD74bZ
|
||||||
|
1mTx2xokmQ2TeiCSKSF8Mx9/8Gq+95mzvvIbRwIDAQABAoIBAHNt++caj9WBclJk
|
||||||
|
X4Oc6eJYuDX5o+LCk1YRngy12IJVYiWScWPFg8p6MouXOsw63Sb92mksofWNirYw
|
||||||
|
+UQzC5FGC7G3H12FgFzoQ+lEtxscluuPYlFukfMw5L1rbzG14FNo145MJHXDI4Qu
|
||||||
|
ILwA+T4sEorl1fndOwvbmJzjjcQaeRNz7/R9e6QTOlZ2+IEMKnHSBXXGJbDj6mPN
|
||||||
|
+f1/ec6nVENdxazgRCi0xfinyft4Ipst93Eb+wGcpk+J43aF+0leWQCdl6Y9U1Lz
|
||||||
|
zpv5H5XOQdwpX+dpuioRp73zwPwIialq+hTUN28Bn9U1jW2tjxUl/vgIpjy1s94a
|
||||||
|
UipRwSECgYEA57vYB+wGnxQxY9IPpr9H/y3HciIwCnuOEsWBzjYe8sIqBif2tEpO
|
||||||
|
OgDZZMQY7+JJrDQbDRs442TuRjKhJ5hiW+MyoiFWaYkBBoNVM8RBTkIjHfrh+uB2
|
||||||
|
XT15FbEyyxo3n9QY610ZJFRnW4Uf5V0osjOqqUgQRrVXvamk6NQH6FkCgYEAxQ3v
|
||||||
|
jFYPL3EkZe1br6X0RM42ykGv5Di5Q6NnjpSPcyn9a2obA1cZuCd5S1lhrkuZGsdI
|
||||||
|
iFapeL+7vpts9gu9/ii9y+CgEKplOMmm0ZrChBKAcXMZvdDKV3y5SmTMZPas4X5i
|
||||||
|
hqNqatx9/J93sMYWc0CuoosDEJYKtSz8GE+1rJ8CgYAmp5rdl21zU7b5Y6zgr7+e
|
||||||
|
vVArpbBFz15fmzqP309CR0kjRb9NS6fI3SNmP5+5RBHt+7MXeJcAt3FXnFJtfGnL
|
||||||
|
0hY8HTuA1y2onHe17uLF3xpkgdj4NEEKRJrSF4DViEYHDyYo/JqZCMtE5OvxIp0L
|
||||||
|
PLsXCcJNSSqdpJKxk8zN4QKBgEuoxSAh7uStUWddUkXHt1kvwDO6MtmyuddxhxJk
|
||||||
|
kguKxMWYUNTgfXyKk3TN1caBOkDg4UWP2LQHEgPmU1jJO2K5q9362hpsAj9ilY2H
|
||||||
|
GUZygCSPKAQMhZQ/zDj3KM9fMxPFXfkKB5MOI8V6SQ9zjy0jWaoJK90TbvsPUZ/Y
|
||||||
|
Aw5LAoGADifZwCHPiXhTfJjOom2uBgXmL03yTXcCw4EDIX3ZR0sP6ACPQq4T4jxZ
|
||||||
|
UJLXLjOb2pzCq0c5+k0cG6ahYINq4tGOo+vQ9fDvhKg0nlf1FrzxSd7S12o+un2q
|
||||||
|
+U+dBllYIDlRMgMhXu9CxFDjUsCwPRmsBvmVZiH4XSs6QVnfn90=
|
||||||
|
-----END RSA PRIVATE KEY-----
|
27
public/keys/private.pem
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEogIBAAKCAQEAsmAqn3hYd/YZcrfgqM1Q6xgHI50EBckbOkfCqTWS1yVFZjLF
|
||||||
|
bMehWb9xGFZJD21A5sxl4xelIWblhety+YTVa/mn2CEJh3je069oeULfXdzhhHyf
|
||||||
|
/ci0IloJhvX+2RJ+176uTKKcWhuOtNVs5VeFoHDoUcISnTqkaVyWeeLfafgrOW7w
|
||||||
|
N8ip128nuBx19ylIygb/DELmjKRRCSpx2vOw2JErTM8L5r0f4eWdqiwBOwu0NHWy
|
||||||
|
Svh9YG8B31UPga4I8FbFhybOP9cQNQPafOSfjwuZoi5CAtyJbwT7KyII9iMD74bZ
|
||||||
|
1mTx2xokmQ2TeiCSKSF8Mx9/8Gq+95mzvvIbRwIDAQABAoIBAHNt++caj9WBclJk
|
||||||
|
X4Oc6eJYuDX5o+LCk1YRngy12IJVYiWScWPFg8p6MouXOsw63Sb92mksofWNirYw
|
||||||
|
+UQzC5FGC7G3H12FgFzoQ+lEtxscluuPYlFukfMw5L1rbzG14FNo145MJHXDI4Qu
|
||||||
|
ILwA+T4sEorl1fndOwvbmJzjjcQaeRNz7/R9e6QTOlZ2+IEMKnHSBXXGJbDj6mPN
|
||||||
|
+f1/ec6nVENdxazgRCi0xfinyft4Ipst93Eb+wGcpk+J43aF+0leWQCdl6Y9U1Lz
|
||||||
|
zpv5H5XOQdwpX+dpuioRp73zwPwIialq+hTUN28Bn9U1jW2tjxUl/vgIpjy1s94a
|
||||||
|
UipRwSECgYEA57vYB+wGnxQxY9IPpr9H/y3HciIwCnuOEsWBzjYe8sIqBif2tEpO
|
||||||
|
OgDZZMQY7+JJrDQbDRs442TuRjKhJ5hiW+MyoiFWaYkBBoNVM8RBTkIjHfrh+uB2
|
||||||
|
XT15FbEyyxo3n9QY610ZJFRnW4Uf5V0osjOqqUgQRrVXvamk6NQH6FkCgYEAxQ3v
|
||||||
|
jFYPL3EkZe1br6X0RM42ykGv5Di5Q6NnjpSPcyn9a2obA1cZuCd5S1lhrkuZGsdI
|
||||||
|
iFapeL+7vpts9gu9/ii9y+CgEKplOMmm0ZrChBKAcXMZvdDKV3y5SmTMZPas4X5i
|
||||||
|
hqNqatx9/J93sMYWc0CuoosDEJYKtSz8GE+1rJ8CgYAmp5rdl21zU7b5Y6zgr7+e
|
||||||
|
vVArpbBFz15fmzqP309CR0kjRb9NS6fI3SNmP5+5RBHt+7MXeJcAt3FXnFJtfGnL
|
||||||
|
0hY8HTuA1y2onHe17uLF3xpkgdj4NEEKRJrSF4DViEYHDyYo/JqZCMtE5OvxIp0L
|
||||||
|
PLsXCcJNSSqdpJKxk8zN4QKBgEuoxSAh7uStUWddUkXHt1kvwDO6MtmyuddxhxJk
|
||||||
|
kguKxMWYUNTgfXyKk3TN1caBOkDg4UWP2LQHEgPmU1jJO2K5q9362hpsAj9ilY2H
|
||||||
|
GUZygCSPKAQMhZQ/zDj3KM9fMxPFXfkKB5MOI8V6SQ9zjy0jWaoJK90TbvsPUZ/Y
|
||||||
|
Aw5LAoGADifZwCHPiXhTfJjOom2uBgXmL03yTXcCw4EDIX3ZR0sP6ACPQq4T4jxZ
|
||||||
|
UJLXLjOb2pzCq0c5+k0cG6ahYINq4tGOo+vQ9fDvhKg0nlf1FrzxSd7S12o+un2q
|
||||||
|
+U+dBllYIDlRMgMhXu9CxFDjUsCwPRmsBvmVZiH4XSs6QVnfn90=
|
||||||
|
-----END RSA PRIVATE KEY-----
|
17
public/keys/public.crt
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICuDCCAaACCQC7PQmrxgWOlTANBgkqhkiG9w0BAQsFADAdMRswGQYDVQQDDBJs
|
||||||
|
ZWNlcGluLTIwMjItMDUtMTkwIBcNMjIwNTE5MTI1NjA0WhgPMzAyMTA5MTkxMjU2
|
||||||
|
MDRaMB0xGzAZBgNVBAMMEmxlY2VwaW4tMjAyMi0wNS0xOTCCASIwDQYJKoZIhvcN
|
||||||
|
AQEBBQADggEPADCCAQoCggEBALJgKp94WHf2GXK34KjNUOsYByOdBAXJGzpHwqk1
|
||||||
|
ktclRWYyxWzHoVm/cRhWSQ9tQObMZeMXpSFm5YXrcvmE1Wv5p9ghCYd43tOvaHlC
|
||||||
|
313c4YR8n/3ItCJaCYb1/tkSfte+rkyinFobjrTVbOVXhaBw6FHCEp06pGlclnni
|
||||||
|
32n4Kzlu8DfIqddvJ7gcdfcpSMoG/wxC5oykUQkqcdrzsNiRK0zPC+a9H+Hlnaos
|
||||||
|
ATsLtDR1skr4fWBvAd9VD4GuCPBWxYcmzj/XEDUD2nzkn48LmaIuQgLciW8E+ysi
|
||||||
|
CPYjA++G2dZk8dsaJJkNk3ogkikhfDMff/BqvveZs77yG0cCAwEAATANBgkqhkiG
|
||||||
|
9w0BAQsFAAOCAQEADymHk+wLJAdv3p+4hHo57VLaBtwVYXc5oRUbUzgMYTTtPWIs
|
||||||
|
xuILEqXftMspt6PzdEt0V1WeCWNyypsAbur/CKpAOoVjBDPIo09TiYnYIn9xt5wQ
|
||||||
|
AmR5kVEZheuazcvzW3C9NAY1T6QDmxNvFCiCXRbtklOg2HqFDZX+pkj8CylQ9TDk
|
||||||
|
rroUg17b/FD1ds1uyPXzucEWfxqkOaujvsCnzrbFs9luB5VfM+QzLU+l9QRN9Tmj
|
||||||
|
z7CpGuP6vKvhXJLUjXkZ0q5JyL5wEAe6Ttbu+c/8HhPFKQsW6q/lQSDo0v0LGDrd
|
||||||
|
ikjWXhSrVjd8+qTTVgia/UNqv/wi+bkWnVdRzQ==
|
||||||
|
-----END CERTIFICATE-----
|
17
public/keys/public.pem
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICuDCCAaACCQC7PQmrxgWOlTANBgkqhkiG9w0BAQsFADAdMRswGQYDVQQDDBJs
|
||||||
|
ZWNlcGluLTIwMjItMDUtMTkwIBcNMjIwNTE5MTI1NjA0WhgPMzAyMTA5MTkxMjU2
|
||||||
|
MDRaMB0xGzAZBgNVBAMMEmxlY2VwaW4tMjAyMi0wNS0xOTCCASIwDQYJKoZIhvcN
|
||||||
|
AQEBBQADggEPADCCAQoCggEBALJgKp94WHf2GXK34KjNUOsYByOdBAXJGzpHwqk1
|
||||||
|
ktclRWYyxWzHoVm/cRhWSQ9tQObMZeMXpSFm5YXrcvmE1Wv5p9ghCYd43tOvaHlC
|
||||||
|
313c4YR8n/3ItCJaCYb1/tkSfte+rkyinFobjrTVbOVXhaBw6FHCEp06pGlclnni
|
||||||
|
32n4Kzlu8DfIqddvJ7gcdfcpSMoG/wxC5oykUQkqcdrzsNiRK0zPC+a9H+Hlnaos
|
||||||
|
ATsLtDR1skr4fWBvAd9VD4GuCPBWxYcmzj/XEDUD2nzkn48LmaIuQgLciW8E+ysi
|
||||||
|
CPYjA++G2dZk8dsaJJkNk3ogkikhfDMff/BqvveZs77yG0cCAwEAATANBgkqhkiG
|
||||||
|
9w0BAQsFAAOCAQEADymHk+wLJAdv3p+4hHo57VLaBtwVYXc5oRUbUzgMYTTtPWIs
|
||||||
|
xuILEqXftMspt6PzdEt0V1WeCWNyypsAbur/CKpAOoVjBDPIo09TiYnYIn9xt5wQ
|
||||||
|
AmR5kVEZheuazcvzW3C9NAY1T6QDmxNvFCiCXRbtklOg2HqFDZX+pkj8CylQ9TDk
|
||||||
|
rroUg17b/FD1ds1uyPXzucEWfxqkOaujvsCnzrbFs9luB5VfM+QzLU+l9QRN9Tmj
|
||||||
|
z7CpGuP6vKvhXJLUjXkZ0q5JyL5wEAe6Ttbu+c/8HhPFKQsW6q/lQSDo0v0LGDrd
|
||||||
|
ikjWXhSrVjd8+qTTVgia/UNqv/wi+bkWnVdRzQ==
|
||||||
|
-----END CERTIFICATE-----
|
BIN
public/openssl/HashInfo.txt
Normal file
126
public/openssl/OpenSSL License.txt
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
|
||||||
|
LICENSE ISSUES
|
||||||
|
==============
|
||||||
|
|
||||||
|
The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
|
||||||
|
the OpenSSL License and the original SSLeay license apply to the toolkit.
|
||||||
|
See below for the actual license texts. Actually both licenses are BSD-style
|
||||||
|
Open Source licenses. In case of any license issues related to OpenSSL
|
||||||
|
please contact openssl-core@openssl.org.
|
||||||
|
|
||||||
|
OpenSSL License
|
||||||
|
---------------
|
||||||
|
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright (c) 1998-2016 The OpenSSL Project. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. All advertising materials mentioning features or use of this
|
||||||
|
* software must display the following acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||||
|
*
|
||||||
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission. For written permission, please contact
|
||||||
|
* openssl-core@openssl.org.
|
||||||
|
*
|
||||||
|
* 5. Products derived from this software may not be called "OpenSSL"
|
||||||
|
* nor may "OpenSSL" appear in their names without prior written
|
||||||
|
* permission of the OpenSSL Project.
|
||||||
|
*
|
||||||
|
* 6. Redistributions of any form whatsoever must retain the following
|
||||||
|
* acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||||
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This product includes cryptographic software written by Eric Young
|
||||||
|
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||||
|
* Hudson (tjh@cryptsoft.com).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
Original SSLeay License
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This package is an SSL implementation written
|
||||||
|
* by Eric Young (eay@cryptsoft.com).
|
||||||
|
* The implementation was written so as to conform with Netscapes SSL.
|
||||||
|
*
|
||||||
|
* This library is free for commercial and non-commercial use as long as
|
||||||
|
* the following conditions are aheared to. The following conditions
|
||||||
|
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||||
|
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||||
|
* included with this distribution is covered by the same copyright terms
|
||||||
|
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||||
|
*
|
||||||
|
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||||
|
* the code are not to be removed.
|
||||||
|
* If this package is used in a product, Eric Young should be given attribution
|
||||||
|
* as the author of the parts of the library used.
|
||||||
|
* This can be in the form of a textual message at program startup or
|
||||||
|
* in documentation (online or textual) provided with the package.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* "This product includes cryptographic software written by
|
||||||
|
* Eric Young (eay@cryptsoft.com)"
|
||||||
|
* The word 'cryptographic' can be left out if the rouines from the library
|
||||||
|
* being used are not cryptographic related :-).
|
||||||
|
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||||
|
* the apps directory (application code) you must include an acknowledgement:
|
||||||
|
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The licence and distribution terms for any publically available version or
|
||||||
|
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||||
|
* copied and put under another distribution licence
|
||||||
|
* [including the GNU Public Licence.]
|
||||||
|
*/
|
59
public/openssl/ReadMe.txt
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
=============================================================================
|
||||||
|
OpenSSL v1.0.2q Precompiled Binaries for Win32
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
*** Release Information ***
|
||||||
|
|
||||||
|
Release Date: Nov 22, 2018
|
||||||
|
|
||||||
|
Author: Frederik A. Winkelsdorf (opendec.wordpress.com)
|
||||||
|
for the Indy Project (www.indyproject.org)
|
||||||
|
|
||||||
|
Requirements: Indy 10.5.5+ (SVN Version or Delphi 2009 and newer)
|
||||||
|
|
||||||
|
Dependencies: The libraries have no noteworthy dependencies
|
||||||
|
|
||||||
|
Installation: Copy both DLL files into your application directory
|
||||||
|
|
||||||
|
Supported OS: Windows 2000 up to Windows 10
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
*** Legal Disclaimer ***
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY ITS AUTHOR AND THE INDY PROJECT "AS IS" AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
OpenSSL license terms are provided in the file "OpenSSL License.txt".
|
||||||
|
|
||||||
|
PLEASE CHECK IF YOU NEED TO COMPLY WITH EXPORT RESTRICTIONS FOR CRYPTOGRAPHIC
|
||||||
|
SOFTWARE AND/OR PATENTS.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
*** Build Information Win32 ***
|
||||||
|
|
||||||
|
Built with: Microsoft Visual C++ 2008 Express Edition
|
||||||
|
The Netwide Assembler (NASM) v2.11.08 Win32
|
||||||
|
Strawberry Perl v5.22.0.1 Win32 Portable
|
||||||
|
Windows PowerShell
|
||||||
|
FinalBuilder 7
|
||||||
|
|
||||||
|
Commands: perl configure VC-WIN32
|
||||||
|
ms\do_nasm
|
||||||
|
adjusted ms\ntdll.mak (replaced "/MD" with "/MT")
|
||||||
|
adjusted ms\version32.rc (Indy Information inserted)
|
||||||
|
nmake -f ms\ntdll.mak
|
||||||
|
nmake -f ms\ntdll.mak test
|
||||||
|
editbin.exe /rebase:base=0x11000000 libeay32.dll
|
||||||
|
editbin.exe /rebase:base=0x12000000 ssleay32.dll
|
||||||
|
|
||||||
|
=============================================================================
|
BIN
public/openssl/libeay32.dll
Normal file
350
public/openssl/openssl.cnf
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
#
|
||||||
|
# OpenSSL example configuration file.
|
||||||
|
# This is mostly being used for generation of certificate requests.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Note that you can include other files from the main configuration
|
||||||
|
# file using the .include directive.
|
||||||
|
#.include filename
|
||||||
|
|
||||||
|
# This definition stops the following lines choking if HOME isn't
|
||||||
|
# defined.
|
||||||
|
HOME = .
|
||||||
|
|
||||||
|
# Extra OBJECT IDENTIFIER info:
|
||||||
|
#oid_file = $ENV::HOME/.oid
|
||||||
|
oid_section = new_oids
|
||||||
|
|
||||||
|
# To use this configuration file with the "-extfile" option of the
|
||||||
|
# "openssl x509" utility, name here the section containing the
|
||||||
|
# X.509v3 extensions to use:
|
||||||
|
# extensions =
|
||||||
|
# (Alternatively, use a configuration file that has only
|
||||||
|
# X.509v3 extensions in its main [= default] section.)
|
||||||
|
|
||||||
|
[ new_oids ]
|
||||||
|
|
||||||
|
# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
|
||||||
|
# Add a simple OID like this:
|
||||||
|
# testoid1=1.2.3.4
|
||||||
|
# Or use config file substitution like this:
|
||||||
|
# testoid2=${testoid1}.5.6
|
||||||
|
|
||||||
|
# Policies used by the TSA examples.
|
||||||
|
tsa_policy1 = 1.2.3.4.1
|
||||||
|
tsa_policy2 = 1.2.3.4.5.6
|
||||||
|
tsa_policy3 = 1.2.3.4.5.7
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
[ ca ]
|
||||||
|
default_ca = CA_default # The default ca section
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
[ CA_default ]
|
||||||
|
|
||||||
|
dir = ./demoCA # Where everything is kept
|
||||||
|
certs = $dir/certs # Where the issued certs are kept
|
||||||
|
crl_dir = $dir/crl # Where the issued crl are kept
|
||||||
|
database = $dir/index.txt # database index file.
|
||||||
|
#unique_subject = no # Set to 'no' to allow creation of
|
||||||
|
# several certs with same subject.
|
||||||
|
new_certs_dir = $dir/newcerts # default place for new certs.
|
||||||
|
|
||||||
|
certificate = $dir/cacert.pem # The CA certificate
|
||||||
|
serial = $dir/serial # The current serial number
|
||||||
|
crlnumber = $dir/crlnumber # the current crl number
|
||||||
|
# must be commented out to leave a V1 CRL
|
||||||
|
crl = $dir/crl.pem # The current CRL
|
||||||
|
private_key = $dir/private/cakey.pem# The private key
|
||||||
|
|
||||||
|
x509_extensions = usr_cert # The extensions to add to the cert
|
||||||
|
|
||||||
|
# Comment out the following two lines for the "traditional"
|
||||||
|
# (and highly broken) format.
|
||||||
|
name_opt = ca_default # Subject Name options
|
||||||
|
cert_opt = ca_default # Certificate field options
|
||||||
|
|
||||||
|
# Extension copying option: use with caution.
|
||||||
|
# copy_extensions = copy
|
||||||
|
|
||||||
|
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
|
||||||
|
# so this is commented out by default to leave a V1 CRL.
|
||||||
|
# crlnumber must also be commented out to leave a V1 CRL.
|
||||||
|
# crl_extensions = crl_ext
|
||||||
|
|
||||||
|
default_days = 365 # how long to certify for
|
||||||
|
default_crl_days= 30 # how long before next CRL
|
||||||
|
default_md = default # use public key default MD
|
||||||
|
preserve = no # keep passed DN ordering
|
||||||
|
|
||||||
|
# A few difference way of specifying how similar the request should look
|
||||||
|
# For type CA, the listed attributes must be the same, and the optional
|
||||||
|
# and supplied fields are just that :-)
|
||||||
|
policy = policy_match
|
||||||
|
|
||||||
|
# For the CA policy
|
||||||
|
[ policy_match ]
|
||||||
|
countryName = match
|
||||||
|
stateOrProvinceName = match
|
||||||
|
organizationName = match
|
||||||
|
organizationalUnitName = optional
|
||||||
|
commonName = supplied
|
||||||
|
emailAddress = optional
|
||||||
|
|
||||||
|
# For the 'anything' policy
|
||||||
|
# At this point in time, you must list all acceptable 'object'
|
||||||
|
# types.
|
||||||
|
[ policy_anything ]
|
||||||
|
countryName = optional
|
||||||
|
stateOrProvinceName = optional
|
||||||
|
localityName = optional
|
||||||
|
organizationName = optional
|
||||||
|
organizationalUnitName = optional
|
||||||
|
commonName = supplied
|
||||||
|
emailAddress = optional
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
[ req ]
|
||||||
|
default_bits = 2048
|
||||||
|
default_keyfile = privkey.pem
|
||||||
|
distinguished_name = req_distinguished_name
|
||||||
|
attributes = req_attributes
|
||||||
|
x509_extensions = v3_ca # The extensions to add to the self signed cert
|
||||||
|
|
||||||
|
# Passwords for private keys if not present they will be prompted for
|
||||||
|
# input_password = secret
|
||||||
|
# output_password = secret
|
||||||
|
|
||||||
|
# This sets a mask for permitted string types. There are several options.
|
||||||
|
# default: PrintableString, T61String, BMPString.
|
||||||
|
# pkix : PrintableString, BMPString (PKIX recommendation before 2004)
|
||||||
|
# utf8only: only UTF8Strings (PKIX recommendation after 2004).
|
||||||
|
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
|
||||||
|
# MASK:XXXX a literal mask value.
|
||||||
|
# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
|
||||||
|
string_mask = utf8only
|
||||||
|
|
||||||
|
# req_extensions = v3_req # The extensions to add to a certificate request
|
||||||
|
|
||||||
|
[ req_distinguished_name ]
|
||||||
|
countryName = Country Name (2 letter code)
|
||||||
|
countryName_default = AU
|
||||||
|
countryName_min = 2
|
||||||
|
countryName_max = 2
|
||||||
|
|
||||||
|
stateOrProvinceName = State or Province Name (full name)
|
||||||
|
stateOrProvinceName_default = Some-State
|
||||||
|
|
||||||
|
localityName = Locality Name (eg, city)
|
||||||
|
|
||||||
|
0.organizationName = Organization Name (eg, company)
|
||||||
|
0.organizationName_default = Internet Widgits Pty Ltd
|
||||||
|
|
||||||
|
# we can do this but it is not needed normally :-)
|
||||||
|
#1.organizationName = Second Organization Name (eg, company)
|
||||||
|
#1.organizationName_default = World Wide Web Pty Ltd
|
||||||
|
|
||||||
|
organizationalUnitName = Organizational Unit Name (eg, section)
|
||||||
|
#organizationalUnitName_default =
|
||||||
|
|
||||||
|
commonName = Common Name (e.g. server FQDN or YOUR name)
|
||||||
|
commonName_max = 64
|
||||||
|
|
||||||
|
emailAddress = Email Address
|
||||||
|
emailAddress_max = 64
|
||||||
|
|
||||||
|
# SET-ex3 = SET extension number 3
|
||||||
|
|
||||||
|
[ req_attributes ]
|
||||||
|
challengePassword = A challenge password
|
||||||
|
challengePassword_min = 4
|
||||||
|
challengePassword_max = 20
|
||||||
|
|
||||||
|
unstructuredName = An optional company name
|
||||||
|
|
||||||
|
[ usr_cert ]
|
||||||
|
|
||||||
|
# These extensions are added when 'ca' signs a request.
|
||||||
|
|
||||||
|
# This goes against PKIX guidelines but some CAs do it and some software
|
||||||
|
# requires this to avoid interpreting an end user certificate as a CA.
|
||||||
|
|
||||||
|
basicConstraints=CA:FALSE
|
||||||
|
|
||||||
|
# Here are some examples of the usage of nsCertType. If it is omitted
|
||||||
|
# the certificate can be used for anything *except* object signing.
|
||||||
|
|
||||||
|
# This is OK for an SSL server.
|
||||||
|
# nsCertType = server
|
||||||
|
|
||||||
|
# For an object signing certificate this would be used.
|
||||||
|
# nsCertType = objsign
|
||||||
|
|
||||||
|
# For normal client use this is typical
|
||||||
|
# nsCertType = client, email
|
||||||
|
|
||||||
|
# and for everything including object signing:
|
||||||
|
# nsCertType = client, email, objsign
|
||||||
|
|
||||||
|
# This is typical in keyUsage for a client certificate.
|
||||||
|
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||||
|
|
||||||
|
# This will be displayed in Netscape's comment listbox.
|
||||||
|
nsComment = "OpenSSL Generated Certificate"
|
||||||
|
|
||||||
|
# PKIX recommendations harmless if included in all certificates.
|
||||||
|
subjectKeyIdentifier=hash
|
||||||
|
authorityKeyIdentifier=keyid,issuer
|
||||||
|
|
||||||
|
# This stuff is for subjectAltName and issuerAltname.
|
||||||
|
# Import the email address.
|
||||||
|
# subjectAltName=email:copy
|
||||||
|
# An alternative to produce certificates that aren't
|
||||||
|
# deprecated according to PKIX.
|
||||||
|
# subjectAltName=email:move
|
||||||
|
|
||||||
|
# Copy subject details
|
||||||
|
# issuerAltName=issuer:copy
|
||||||
|
|
||||||
|
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
|
||||||
|
#nsBaseUrl
|
||||||
|
#nsRevocationUrl
|
||||||
|
#nsRenewalUrl
|
||||||
|
#nsCaPolicyUrl
|
||||||
|
#nsSslServerName
|
||||||
|
|
||||||
|
# This is required for TSA certificates.
|
||||||
|
# extendedKeyUsage = critical,timeStamping
|
||||||
|
|
||||||
|
[ v3_req ]
|
||||||
|
|
||||||
|
# Extensions to add to a certificate request
|
||||||
|
|
||||||
|
basicConstraints = CA:FALSE
|
||||||
|
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||||
|
|
||||||
|
[ v3_ca ]
|
||||||
|
|
||||||
|
|
||||||
|
# Extensions for a typical CA
|
||||||
|
|
||||||
|
|
||||||
|
# PKIX recommendation.
|
||||||
|
|
||||||
|
subjectKeyIdentifier=hash
|
||||||
|
|
||||||
|
authorityKeyIdentifier=keyid:always,issuer
|
||||||
|
|
||||||
|
basicConstraints = critical,CA:true
|
||||||
|
|
||||||
|
# Key usage: this is typical for a CA certificate. However since it will
|
||||||
|
# prevent it being used as an test self-signed certificate it is best
|
||||||
|
# left out by default.
|
||||||
|
# keyUsage = cRLSign, keyCertSign
|
||||||
|
|
||||||
|
# Some might want this also
|
||||||
|
# nsCertType = sslCA, emailCA
|
||||||
|
|
||||||
|
# Include email address in subject alt name: another PKIX recommendation
|
||||||
|
# subjectAltName=email:copy
|
||||||
|
# Copy issuer details
|
||||||
|
# issuerAltName=issuer:copy
|
||||||
|
|
||||||
|
# DER hex encoding of an extension: beware experts only!
|
||||||
|
# obj=DER:02:03
|
||||||
|
# Where 'obj' is a standard or added object
|
||||||
|
# You can even override a supported extension:
|
||||||
|
# basicConstraints= critical, DER:30:03:01:01:FF
|
||||||
|
|
||||||
|
[ crl_ext ]
|
||||||
|
|
||||||
|
# CRL extensions.
|
||||||
|
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
|
||||||
|
|
||||||
|
# issuerAltName=issuer:copy
|
||||||
|
authorityKeyIdentifier=keyid:always
|
||||||
|
|
||||||
|
[ proxy_cert_ext ]
|
||||||
|
# These extensions should be added when creating a proxy certificate
|
||||||
|
|
||||||
|
# This goes against PKIX guidelines but some CAs do it and some software
|
||||||
|
# requires this to avoid interpreting an end user certificate as a CA.
|
||||||
|
|
||||||
|
basicConstraints=CA:FALSE
|
||||||
|
|
||||||
|
# Here are some examples of the usage of nsCertType. If it is omitted
|
||||||
|
# the certificate can be used for anything *except* object signing.
|
||||||
|
|
||||||
|
# This is OK for an SSL server.
|
||||||
|
# nsCertType = server
|
||||||
|
|
||||||
|
# For an object signing certificate this would be used.
|
||||||
|
# nsCertType = objsign
|
||||||
|
|
||||||
|
# For normal client use this is typical
|
||||||
|
# nsCertType = client, email
|
||||||
|
|
||||||
|
# and for everything including object signing:
|
||||||
|
# nsCertType = client, email, objsign
|
||||||
|
|
||||||
|
# This is typical in keyUsage for a client certificate.
|
||||||
|
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||||
|
|
||||||
|
# This will be displayed in Netscape's comment listbox.
|
||||||
|
nsComment = "OpenSSL Generated Certificate"
|
||||||
|
|
||||||
|
# PKIX recommendations harmless if included in all certificates.
|
||||||
|
subjectKeyIdentifier=hash
|
||||||
|
authorityKeyIdentifier=keyid,issuer
|
||||||
|
|
||||||
|
# This stuff is for subjectAltName and issuerAltname.
|
||||||
|
# Import the email address.
|
||||||
|
# subjectAltName=email:copy
|
||||||
|
# An alternative to produce certificates that aren't
|
||||||
|
# deprecated according to PKIX.
|
||||||
|
# subjectAltName=email:move
|
||||||
|
|
||||||
|
# Copy subject details
|
||||||
|
# issuerAltName=issuer:copy
|
||||||
|
|
||||||
|
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
|
||||||
|
#nsBaseUrl
|
||||||
|
#nsRevocationUrl
|
||||||
|
#nsRenewalUrl
|
||||||
|
#nsCaPolicyUrl
|
||||||
|
#nsSslServerName
|
||||||
|
|
||||||
|
# This really needs to be in place for it to be a proxy certificate.
|
||||||
|
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
[ tsa ]
|
||||||
|
|
||||||
|
default_tsa = tsa_config1 # the default TSA section
|
||||||
|
|
||||||
|
[ tsa_config1 ]
|
||||||
|
|
||||||
|
# These are used by the TSA reply generation only.
|
||||||
|
dir = ./demoCA # TSA root directory
|
||||||
|
serial = $dir/tsaserial # The current serial number (mandatory)
|
||||||
|
crypto_device = builtin # OpenSSL engine to use for signing
|
||||||
|
signer_cert = $dir/tsacert.pem # The TSA signing certificate
|
||||||
|
# (optional)
|
||||||
|
certs = $dir/cacert.pem # Certificate chain to include in reply
|
||||||
|
# (optional)
|
||||||
|
signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
|
||||||
|
signer_digest = sha256 # Signing digest to use. (Optional)
|
||||||
|
default_policy = tsa_policy1 # Policy if request did not specify it
|
||||||
|
# (optional)
|
||||||
|
other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
|
||||||
|
digests = sha1, sha256, sha384, sha512 # Acceptable message digests (mandatory)
|
||||||
|
accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
|
||||||
|
clock_precision_digits = 0 # number of digits after dot. (optional)
|
||||||
|
ordering = yes # Is ordering defined for timestamps?
|
||||||
|
# (optional, default: no)
|
||||||
|
tsa_name = yes # Must the TSA name be included in the reply?
|
||||||
|
# (optional, default: no)
|
||||||
|
ess_cert_id_chain = no # Must the ESS cert id chain be included?
|
||||||
|
# (optional, default: no)
|
||||||
|
ess_cert_id_alg = sha1 # algorithm to compute certificate
|
||||||
|
# identifier (optional, default: sha1)
|
BIN
public/openssl/openssl.exe
Normal file
BIN
public/openssl/ssleay32.dll
Normal file
75
public/regedit-vbs/ArchitectureAgnosticRegistry.vbs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
' Notes: wanted to implement this using a class but:
|
||||||
|
' 1. No matter what I did I could not assign the result of GetObject to a private member
|
||||||
|
' 2. It looks as if all methods were treated as subs from the outside world which is not good since
|
||||||
|
' some of these need to return a value
|
||||||
|
'
|
||||||
|
|
||||||
|
Set private_oReg = GetObject("winmgmts:\root\default:StdRegProv")
|
||||||
|
|
||||||
|
Function SetStringValue(constHive, strSubKey, strValueName, strValue)
|
||||||
|
SetStringValue = private_oReg.SetStringValue(constHive, strSubKey, strValueName, strValue)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Sub GetStringValue(constHive, strKey, strValueName, strValue)
|
||||||
|
private_oReg.GetStringValue constHive, strKey, strValueName, strValue
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Function SetExpandedStringValue(constHive, strSubKey, strValueName, strValue)
|
||||||
|
SetExpandedStringValue = private_oReg.SetExpandedStringValue(constHive, strSubKey, strValueName, strValue)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Sub GetExpandedStringValue(constHive, strKey, strValueName, strValue)
|
||||||
|
private_oReg.GetExpandedStringValue constHive, strKey, strValueName, strValue
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Function SetMultiStringValue(constHive, strSubKey, strValueName, arrValue)
|
||||||
|
SetMultiStringValue = private_oReg.SetMultiStringValue(constHive, strSubKey, strValueName, arrValue)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Sub GetMultiStringValue(constHive, strKey, strValueName, arrStrValue)
|
||||||
|
private_oReg.GetMultiStringValue constHive, strKey, strValueName, arrStrValue
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Function SetDWORDValue(constHive, strSubKey, strValueName, arrValue)
|
||||||
|
SetDWORDValue = private_oReg.SetDWORDValue(constHive, strSubKey, strValueName, arrValue)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Sub GetDWORDValue(constHive, strKey, strValueName, intDWordValue)
|
||||||
|
private_oReg.GetDWORDValue constHive, strKey, strValueName, intDWordValue
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Function SetQWORDValue(constHive, strSubKey, strValueName, strQWordValue)
|
||||||
|
SetQWORDValue = private_oReg.SetQWORDValue(constHive, strSubKey, strValueName, strQWordValue)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Sub GetQWORDValue(constHive, strKey, strValueName, intQWordValue)
|
||||||
|
private_oReg.GetQWORDValue constHive, strKey, strValueName, intQWordValue
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Function SetBinaryValue(constHive, strSubKey, strValueName, arrValue)
|
||||||
|
SetBinaryValue = private_oReg.SetBinaryValue(constHive, strSubKey, strValueName, arrValue)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Sub GetBinaryValue(constHive, strKey, strValueName, arrBinaryValue)
|
||||||
|
private_oReg.GetBinaryValue constHive, strKey, strValueName, arrBinaryValue
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Function EnumKey(constHive, strSubKey, arrKeyNames)
|
||||||
|
EnumKey = private_oReg.EnumKey(constHive, strSubKey, arrKeyNames)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function EnumValues(constHive, strSubKey, arrValueNames, arrValueTypes)
|
||||||
|
EnumValues = private_oReg.EnumValues(constHive, strSubKey, arrValueNames, arrValueTypes)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function CreateKey(constHive, strSubKey)
|
||||||
|
CreateKey = private_oReg.CreateKey(constHive, strSubKey)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function DeleteKey(constHive, strSubKey)
|
||||||
|
DeleteKey = private_oReg.DeleteKey(constHive, strSubKey)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function DeleteValue(constHive, strSubKey, strValue)
|
||||||
|
DeleteValue = private_oReg.DeleteValue(constHive, strSubKey, strValue)
|
||||||
|
End Function
|
358
public/regedit-vbs/ArchitectureSpecificRegistry.vbs
Normal file
@ -0,0 +1,358 @@
|
|||||||
|
' Notes: wanted to implement this using a class but:
|
||||||
|
' 1. No matter what I did I could not assign the result of GetObject to a private member
|
||||||
|
' 2. It looks as if all methods were treated as subs from the outside world which is not good since
|
||||||
|
' some of these need to return a value
|
||||||
|
|
||||||
|
' should be removed when migration is complete
|
||||||
|
Set private_oReg = GetObject("winmgmts:\root\default:StdRegProv")
|
||||||
|
|
||||||
|
Set private_oCtx = CreateObject("WbemScripting.SWbemNamedValueSet")
|
||||||
|
private_oCtx.Add "__ProviderArchitecture", CInt(OSArchitecture)
|
||||||
|
|
||||||
|
Set private_oLocator = CreateObject("Wbemscripting.SWbemLocator")
|
||||||
|
Set private_oServices = private_oLocator.ConnectServer(".", "root\default","","",,,,private_oCtx)
|
||||||
|
Set private_oRegSpecific = private_oServices.Get("StdRegProv")
|
||||||
|
|
||||||
|
Function CheckAccess(hDefKey,sSubKeyName,uRequired, bGranted )
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("CheckAccess").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
Inparams.uRequired = uRequired
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("CheckAccess", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
bGranted = Outparams.bGranted
|
||||||
|
|
||||||
|
|
||||||
|
CheckAccess = 0
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function CreateKey(hDefKey,sSubKeyName)
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("CreateKey").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("CreateKey", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
|
||||||
|
CreateKey = 0
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function DeleteKey(hDefKey,sSubKeyName)
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("DeleteKey").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("DeleteKey", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
|
||||||
|
DeleteKey = 0
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function DeleteValue(hDefKey,sSubKeyName,sValueName)
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("DeleteValue").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
Inparams.sValueName = sValueName
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("DeleteValue", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
|
||||||
|
DeleteValue = 0
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function EnumKey(hDefKey,sSubKeyName, sNames )
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("EnumKey").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("EnumKey", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
sNames = Outparams.sNames
|
||||||
|
|
||||||
|
|
||||||
|
EnumKey = 0
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function EnumValues(hDefKey,sSubKeyName, sNames,Types )
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("EnumValues").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("EnumValues", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
sNames = Outparams.sNames
|
||||||
|
|
||||||
|
Types = Outparams.Types
|
||||||
|
|
||||||
|
|
||||||
|
EnumValues = 0
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function GetBinaryValue(hDefKey,sSubKeyName,sValueName, uValue )
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("GetBinaryValue").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
Inparams.sValueName = sValueName
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("GetBinaryValue", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
uValue = Outparams.uValue
|
||||||
|
|
||||||
|
|
||||||
|
GetBinaryValue = 0
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function GetDWORDValue(hDefKey,sSubKeyName,sValueName, uValue )
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("GetDWORDValue").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
Inparams.sValueName = sValueName
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("GetDWORDValue", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
uValue = Outparams.uValue
|
||||||
|
|
||||||
|
|
||||||
|
GetDWORDValue = 0
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function GetExpandedStringValue(hDefKey,sSubKeyName,sValueName, sValue )
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("GetExpandedStringValue").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
Inparams.sValueName = sValueName
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("GetExpandedStringValue", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
sValue = Outparams.sValue
|
||||||
|
|
||||||
|
|
||||||
|
GetExpandedStringValue = 0
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function GetMultiStringValue(hDefKey,sSubKeyName,sValueName, sValue )
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("GetMultiStringValue").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
Inparams.sValueName = sValueName
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("GetMultiStringValue", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
sValue = Outparams.sValue
|
||||||
|
|
||||||
|
|
||||||
|
GetMultiStringValue = 0
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function GetQWORDValue(hDefKey,sSubKeyName,sValueName, uValue )
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("GetQWORDValue").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
Inparams.sValueName = sValueName
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("GetQWORDValue", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
uValue = Outparams.uValue
|
||||||
|
|
||||||
|
|
||||||
|
GetQWORDValue = 0
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function GetSecurityDescriptor(hDefKey,sSubKeyName, Descriptor )
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("GetSecurityDescriptor").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("GetSecurityDescriptor", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
Descriptor = Outparams.Descriptor
|
||||||
|
|
||||||
|
|
||||||
|
GetSecurityDescriptor = 0
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function GetStringValue(hDefKey,sSubKeyName,sValueName, sValue )
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("GetStringValue").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
Inparams.sValueName = sValueName
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("GetStringValue", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
sValue = Outparams.sValue
|
||||||
|
|
||||||
|
|
||||||
|
GetStringValue = 0
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function SetBinaryValue(hDefKey,sSubKeyName,sValueName,uValue)
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("SetBinaryValue").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
Inparams.sValueName = sValueName
|
||||||
|
|
||||||
|
Inparams.uValue = uValue
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("SetBinaryValue", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
|
||||||
|
SetBinaryValue = 0
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function SetDWORDValue(hDefKey,sSubKeyName,sValueName,uValue)
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("SetDWORDValue").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
Inparams.sValueName = sValueName
|
||||||
|
|
||||||
|
Inparams.uValue = uValue
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("SetDWORDValue", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
|
||||||
|
SetDWORDValue = 0
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function SetExpandedStringValue(hDefKey,sSubKeyName,sValueName,sValue)
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("SetExpandedStringValue").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
Inparams.sValueName = sValueName
|
||||||
|
|
||||||
|
Inparams.sValue = sValue
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("SetExpandedStringValue", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
|
||||||
|
SetExpandedStringValue = 0
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function SetMultiStringValue(hDefKey,sSubKeyName,sValueName,sValue)
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("SetMultiStringValue").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
Inparams.sValueName = sValueName
|
||||||
|
|
||||||
|
Inparams.sValue = sValue
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("SetMultiStringValue", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
|
||||||
|
SetMultiStringValue = 0
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function SetQWORDValue(hDefKey,sSubKeyName,sValueName,uValue)
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("SetQWORDValue").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
Inparams.sValueName = sValueName
|
||||||
|
|
||||||
|
Inparams.uValue = uValue
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("SetQWORDValue", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
|
||||||
|
SetQWORDValue = 0
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function SetSecurityDescriptor(hDefKey,sSubKeyName,Descriptor)
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("SetSecurityDescriptor").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
Inparams.Descriptor = Descriptor
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("SetSecurityDescriptor", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
|
||||||
|
SetSecurityDescriptor = 0
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function SetStringValue(hDefKey,sSubKeyName,sValueName,sValue)
|
||||||
|
Set Inparams = private_oRegSpecific.Methods_("SetStringValue").Inparameters
|
||||||
|
|
||||||
|
Inparams.hDefKey = hDefKey
|
||||||
|
|
||||||
|
Inparams.sSubKeyName = sSubKeyName
|
||||||
|
|
||||||
|
Inparams.sValueName = sValueName
|
||||||
|
|
||||||
|
Inparams.sValue = sValue
|
||||||
|
|
||||||
|
set Outparams = private_oRegSpecific.ExecMethod_("SetStringValue", Inparams,,private_oCtx)
|
||||||
|
|
||||||
|
|
||||||
|
SetStringValue = 0
|
||||||
|
|
||||||
|
End Function
|
7
public/regedit-vbs/JsonSafeTest.wsf
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<job id="JsonSafeStreamTest">
|
||||||
|
<script language="VBScript" src="util.vbs" />
|
||||||
|
<script language="VBScript">
|
||||||
|
str = """" & vbcrlf & "测试\"
|
||||||
|
Write("{ ""a"": """ & JsonSafe(str) & """}" & vbcrlf)
|
||||||
|
</script>
|
||||||
|
</job>
|
32
public/regedit-vbs/regCreateKey.wsf
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<job id="createKeyStream">
|
||||||
|
<script language="VBScript" src="util.vbs" />
|
||||||
|
<script language="VBScript" src="regUtil.vbs" />
|
||||||
|
<script language="VBScript">
|
||||||
|
|
||||||
|
CheckZeroArgs("usage: cscript regCreateKey.wsf architecture")
|
||||||
|
DetermineOSArchitecture()
|
||||||
|
LoadRegistryImplementationByOSArchitecture()
|
||||||
|
|
||||||
|
Do While Not stdin.AtEndOfLine
|
||||||
|
strLine = stdin.ReadLine()
|
||||||
|
strLine = unescape(trim(strLine))
|
||||||
|
|
||||||
|
If IsNull(strLine) or strLine = "" Then
|
||||||
|
WScript.Quit 25127
|
||||||
|
End If
|
||||||
|
|
||||||
|
ParseHiveAndSubKey strLine, constHive, strSubKey
|
||||||
|
|
||||||
|
if IsNull(constHive) Then
|
||||||
|
WriteLineErr "unsupported hive " & strLine
|
||||||
|
WScript.Quit 25122
|
||||||
|
End If
|
||||||
|
|
||||||
|
Result = CreateKey(constHive, strSubKey)
|
||||||
|
|
||||||
|
If Not Result = 0 Then
|
||||||
|
WScript.Quit Result
|
||||||
|
End If
|
||||||
|
Loop
|
||||||
|
</script>
|
||||||
|
</job>
|
29
public/regedit-vbs/regDeleteKey.wsf
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<job id="deleteKey">
|
||||||
|
<script language="VBScript" src="util.vbs" />
|
||||||
|
<script language="VBScript" src="regUtil.vbs" />
|
||||||
|
<script language="VBScript">
|
||||||
|
|
||||||
|
CheckZeroArgs("usage: cscript regDeleteKey.wsf architecture")
|
||||||
|
DetermineOSArchitecture()
|
||||||
|
LoadRegistryImplementationByOSArchitecture()
|
||||||
|
|
||||||
|
Do While Not stdin.AtEndOfLine
|
||||||
|
|
||||||
|
strLine = stdin.ReadLine()
|
||||||
|
strLine = unescape(trim(strLine))
|
||||||
|
|
||||||
|
ParseHiveAndSubKey strLine, constHive, strSubKey
|
||||||
|
|
||||||
|
if IsNull(constHive) Then
|
||||||
|
WriteLineErr "unsupported hive " & strLine
|
||||||
|
WScript.Quit 25122
|
||||||
|
End If
|
||||||
|
|
||||||
|
Result = DeleteKey(constHive, strSubKey)
|
||||||
|
|
||||||
|
If Not Result = 0 Then
|
||||||
|
WScript.Quit Result
|
||||||
|
End If
|
||||||
|
Loop
|
||||||
|
</script>
|
||||||
|
</job>
|
29
public/regedit-vbs/regDeleteValue.wsf
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<job id="deleteValue">
|
||||||
|
<script language="VBScript" src="util.vbs" />
|
||||||
|
<script language="VBScript" src="regUtil.vbs" />
|
||||||
|
<script language="VBScript">
|
||||||
|
|
||||||
|
CheckZeroArgs("usage: cscript regDeleteValue.wsf architecture")
|
||||||
|
DetermineOSArchitecture()
|
||||||
|
LoadRegistryImplementationByOSArchitecture()
|
||||||
|
|
||||||
|
Do While Not stdin.AtEndOfLine
|
||||||
|
|
||||||
|
strLine = stdin.ReadLine()
|
||||||
|
strLine = unescape(trim(strLine))
|
||||||
|
|
||||||
|
ParseHiveAndSubKeyAndValue strLine, constHive, strSubKey, strValue
|
||||||
|
|
||||||
|
if IsNull(constHive) Then
|
||||||
|
WriteLineErr "unsupported hive " & strLine
|
||||||
|
WScript.Quit 25122
|
||||||
|
End If
|
||||||
|
|
||||||
|
Result = DeleteValue(constHive, strSubKey, strValue)
|
||||||
|
|
||||||
|
If Not Result = 0 Then
|
||||||
|
WScript.Quit Result
|
||||||
|
End If
|
||||||
|
Loop
|
||||||
|
</script>
|
||||||
|
</job>
|
49
public/regedit-vbs/regList.wsf
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
'
|
||||||
|
' Lists the sub keys and values of a given registry key
|
||||||
|
'
|
||||||
|
' cscript regList.wsg HKLM\Software
|
||||||
|
'
|
||||||
|
' Will Yield:
|
||||||
|
'
|
||||||
|
' {
|
||||||
|
' "hklm\software": {
|
||||||
|
' "keys": [ .. array of sub keys .. ],
|
||||||
|
' "values": {
|
||||||
|
' "moo": {
|
||||||
|
' "type": "REG_SZ",
|
||||||
|
' "value": "bar"
|
||||||
|
' }
|
||||||
|
' }
|
||||||
|
' }
|
||||||
|
' }
|
||||||
|
<job id="list">
|
||||||
|
<script language="VBScript" src="util.vbs" />
|
||||||
|
<script language="VBScript" src="regUtil.vbs" />
|
||||||
|
<script language="VBScript">
|
||||||
|
CheckZeroArgs("usage: cscript regList.wsf architecture regpath1 [regpath2] ... [regpathN]")
|
||||||
|
DetermineOSArchitecture()
|
||||||
|
LoadRegistryImplementationByOSArchitecture()
|
||||||
|
|
||||||
|
Write "{"
|
||||||
|
On Error Resume Next
|
||||||
|
For v = 1 To args.Count - 1
|
||||||
|
If (v > 1) Then
|
||||||
|
Write ","
|
||||||
|
End If
|
||||||
|
|
||||||
|
Dim key: key = trim(args(v))
|
||||||
|
|
||||||
|
Write """" & JsonSafe(key) & """: "
|
||||||
|
|
||||||
|
ParseHiveAndSubKey key, constHive, strSubKey
|
||||||
|
|
||||||
|
If IsNull(constHive) Then
|
||||||
|
WriteLineErr "unsupported hive " & args(v)
|
||||||
|
WScript.Quit 25122
|
||||||
|
End If
|
||||||
|
|
||||||
|
ListChildrenAsJson constHive, strSubKey
|
||||||
|
Next
|
||||||
|
Write "}"
|
||||||
|
</script>
|
||||||
|
</job>
|
46
public/regedit-vbs/regListStream.wsf
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
'
|
||||||
|
' Lists the sub keys and values of a given registry key, this script is slightly different
|
||||||
|
' than regList because it reads stdin for the keys to list
|
||||||
|
'
|
||||||
|
' echo HKLM\Software | cscript regListStream.wsf A
|
||||||
|
'
|
||||||
|
' Will Yield:
|
||||||
|
'
|
||||||
|
' {
|
||||||
|
' "hklm\software": {
|
||||||
|
' "keys": [ .. array of sub keys .. ],
|
||||||
|
' "values": {
|
||||||
|
' "moo": {
|
||||||
|
' "type": "REG_SZ",
|
||||||
|
' "value": "bar"
|
||||||
|
' }
|
||||||
|
' }
|
||||||
|
' }
|
||||||
|
' }
|
||||||
|
<job id="listStream">
|
||||||
|
<script language="VBScript" src="util.vbs" />
|
||||||
|
<script language="VBScript" src="regUtil.vbs" />
|
||||||
|
<script language="VBScript">
|
||||||
|
CheckZeroArgs("usage: echo KEY | cscript regListStream.wsf architecture")
|
||||||
|
DetermineOSArchitecture()
|
||||||
|
LoadRegistryImplementationByOSArchitecture()
|
||||||
|
|
||||||
|
Do While Not stdin.AtEndOfLine
|
||||||
|
|
||||||
|
strLine = stdin.ReadLine()
|
||||||
|
strLine = unescape(trim(strLine))
|
||||||
|
|
||||||
|
ParseHiveAndSubKey strLine, constHive, strSubKey
|
||||||
|
|
||||||
|
if IsNull(constHive) Then
|
||||||
|
WriteLineErr "unsupported hive " & strLine
|
||||||
|
WScript.Quit 25122
|
||||||
|
End If
|
||||||
|
|
||||||
|
Write "{ ""key"" : """ & JsonSafe(strLine) & """, ""data"": "
|
||||||
|
ListChildrenAsJson constHive, strSubKey
|
||||||
|
Write "}" & vbcrlf
|
||||||
|
Loop
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</job>
|
56
public/regedit-vbs/regPutValue.wsf
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<job id="putValue">
|
||||||
|
<script language="VBScript" src="util.vbs" />
|
||||||
|
<script language="VBScript" src="regUtil.vbs" />
|
||||||
|
<script language="VBScript">
|
||||||
|
usage = "usage: cscript regPutValue.wsf architecture" & vbNewLine _
|
||||||
|
& "types: REG_SZ, REG_EXPAND_SZ, REG_BINARY, REG_DWORD, REG_MULTI_SZ, REG_QWORD"
|
||||||
|
|
||||||
|
CheckZeroArgs(usage)
|
||||||
|
DetermineOSArchitecture()
|
||||||
|
LoadRegistryImplementationByOSArchitecture()
|
||||||
|
|
||||||
|
ReadCount = 0
|
||||||
|
Dim lineArgs(3)
|
||||||
|
|
||||||
|
Do While Not stdin.AtEndOfLine
|
||||||
|
strLine = stdin.ReadLine()
|
||||||
|
strLine = unescape(trim(strLine))
|
||||||
|
|
||||||
|
If IsNull(strLine) or strLine = "" Then
|
||||||
|
WScript.Quit 25127
|
||||||
|
End If
|
||||||
|
|
||||||
|
lineArgs(ReadCount) = strLine
|
||||||
|
|
||||||
|
ReadCount = ReadCount + 1
|
||||||
|
|
||||||
|
If ReadCount = 4 Then
|
||||||
|
|
||||||
|
ParseHiveAndSubKey lineArgs(0), constHive, strSubKey
|
||||||
|
|
||||||
|
if IsNull(constHive) Then
|
||||||
|
WriteLineErr "unsupported hive " & lineArgs(0)
|
||||||
|
WScript.Quit 25122
|
||||||
|
End If
|
||||||
|
|
||||||
|
strValueName = lineArgs(1)
|
||||||
|
strValue = lineArgs(2)
|
||||||
|
strType = lineArgs(3)
|
||||||
|
|
||||||
|
Result = PutValue(constHive, strSubKey, strValueName, strValue, strType)
|
||||||
|
|
||||||
|
If Not Result = 0 Then
|
||||||
|
WriteLineErr "error while putting value: " & result
|
||||||
|
WScript.Quit Result
|
||||||
|
End If
|
||||||
|
|
||||||
|
ReadCount = 0
|
||||||
|
Erase lineArgs
|
||||||
|
End If
|
||||||
|
Loop
|
||||||
|
|
||||||
|
If ReadCount <> 0 Then
|
||||||
|
WScript.Quit 25123
|
||||||
|
End If
|
||||||
|
</script>
|
||||||
|
</job>
|
358
public/regedit-vbs/regUtil.vbs
Normal file
@ -0,0 +1,358 @@
|
|||||||
|
' TODO: consider incorporating a json writer of some sort instead of adhoc solution like the following
|
||||||
|
' e.g: http://demon.tw/my-work/vbs-json.html
|
||||||
|
|
||||||
|
const HKEY_CLASSES_ROOT = &H80000000
|
||||||
|
const HKEY_CURRENT_USER = &H80000001
|
||||||
|
const HKEY_LOCAL_MACHINE = &H80000002
|
||||||
|
const HKEY_USERS = &H80000003
|
||||||
|
const HKEY_CURRENT_CONFIG = &H80000005
|
||||||
|
|
||||||
|
Sub LoadRegistryImplementationByOSArchitecture()
|
||||||
|
If IsNull(OSArchitecture) Then
|
||||||
|
WriteLineErr "missing OSArchitecture global. did not call util.DetermineOSArchitecture? or Forgot to load util.vbs?"
|
||||||
|
WScript.Quit 25125
|
||||||
|
End If
|
||||||
|
|
||||||
|
If OSArchitecture = "A" Then
|
||||||
|
Include "ArchitectureAgnosticRegistry.vbs"
|
||||||
|
Else
|
||||||
|
Include "ArchitectureSpecificRegistry.vbs"
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Function PutValue(constHive, strSubKey, strValueName, strValue, strType)
|
||||||
|
Select Case UCase(strType)
|
||||||
|
|
||||||
|
Case "REG_SZ"
|
||||||
|
PutValue = SetStringValue(constHive, strSubKey, strValueName, strValue)
|
||||||
|
|
||||||
|
Case "REG_EXPAND_SZ"
|
||||||
|
PutValue = SetExpandedStringValue(constHive, strSubKey, strValueName, strValue)
|
||||||
|
|
||||||
|
Case "REG_BINARY"
|
||||||
|
PutValue = SetBinaryValue(constHive, strSubKey, strValueName, ToBinaryValue(strValue))
|
||||||
|
|
||||||
|
Case "REG_NONE"
|
||||||
|
PutValue = SetBinaryValue(constHive, strSubKey, strValueName, ToBinaryValue(strValue))
|
||||||
|
|
||||||
|
' TODO: need to check that indeed int is the right type here
|
||||||
|
Case "REG_DWORD"
|
||||||
|
PutValue = SetDWORDValue(constHive, strSubKey, strValueName, CDbl(strValue))
|
||||||
|
|
||||||
|
Case "REG_MULTI_SZ"
|
||||||
|
PutValue = SetMultiStringValue(constHive, strSubKey, strValueName, Split(strValue, ","))
|
||||||
|
|
||||||
|
Case "REG_QWORD"
|
||||||
|
PutValue = SetQWORDValue(constHive, strSubKey, strValueName, strValue)
|
||||||
|
|
||||||
|
Case "REG_DEFAULT"
|
||||||
|
PutValue = SetStringValue(constHive, strSubKey, "", strValue)
|
||||||
|
|
||||||
|
Case Else
|
||||||
|
PutValue = SetStringValue(constHive, strSubKey, strValueName, strValue)
|
||||||
|
|
||||||
|
End Select
|
||||||
|
End Function
|
||||||
|
|
||||||
|
' render the child of a sub path strSubKey in hive constHive
|
||||||
|
' as json.
|
||||||
|
Sub ListChildrenAsJson(constHive, strSubKey)
|
||||||
|
' start outputting json to stdout
|
||||||
|
Write "{"
|
||||||
|
|
||||||
|
Dim e1: e1 = EnumKey (constHive, strSubKey, arrKeyNames)
|
||||||
|
If e1 <> 0 Then
|
||||||
|
Write """exists"": false,"
|
||||||
|
Dim arrValueNames: arrValueNames = null
|
||||||
|
Else
|
||||||
|
Write """exists"": true,"
|
||||||
|
|
||||||
|
Dim e2: e2 = EnumValues (constHive, strSubKey, arrValueNames, arrValueTypes)
|
||||||
|
If e2 <> 0 Then
|
||||||
|
WScript.Quit e2
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
|
||||||
|
Write """keys"": ["
|
||||||
|
If Not IsNull(arrKeyNames) Then
|
||||||
|
For x = 0 To UBound(arrKeyNames)
|
||||||
|
If (x > 0) Then
|
||||||
|
Write ","
|
||||||
|
End If
|
||||||
|
|
||||||
|
Write """" & JsonSafe(arrKeyNames(x)) & """"
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
Write "],"
|
||||||
|
' TODO: some duplicity of code between the two paths of this condition, this needs to be address at some point
|
||||||
|
Write """values"":{"
|
||||||
|
If Not IsNull(arrValueNames) Then
|
||||||
|
For y = 0 To UBound(arrValueNames)
|
||||||
|
If y > 0 Then
|
||||||
|
Write ","
|
||||||
|
End If
|
||||||
|
|
||||||
|
strValueName = arrValueNames(y)
|
||||||
|
intValueType = arrValueTypes(y)
|
||||||
|
|
||||||
|
' assign the value to varValue
|
||||||
|
GetValueByType constHive, strSubKey, strValueName, intValueType, varValue
|
||||||
|
|
||||||
|
WriteValue strValueName, intValueType, varValue
|
||||||
|
Next
|
||||||
|
Else
|
||||||
|
' fix for keys with only default values in them
|
||||||
|
' see http://stackoverflow.com/questions/8840343/how-to-read-the-default-value-from-registry-in-vbscript
|
||||||
|
GetStringValue constHive, strSubKey, "", strDefaultValue
|
||||||
|
|
||||||
|
If IsNull(strDefaultValue) = false and strDefaultValue <> "" Then
|
||||||
|
' write the default value with REG_SZ
|
||||||
|
WriteValue "", 1, strDefaultValue
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Write "}}"
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Sub WriteValue (strValueName, intValueType, varValue)
|
||||||
|
Write """"
|
||||||
|
Write JsonSafe(strValueName)
|
||||||
|
Write """:{"
|
||||||
|
Write """type"": """
|
||||||
|
Write RenderType(intValueType)
|
||||||
|
Write ""","
|
||||||
|
Write """value"":"
|
||||||
|
Write RenderValueByType(intValueType, varValue)
|
||||||
|
Write "}"
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
' give a raw HKLM\something\somewhere
|
||||||
|
' output the hive constant and the subkey, in this case:
|
||||||
|
' HKEY_LOCAL_MACHINE will be assigned to outConstHive
|
||||||
|
' and something\somewhere will be assigned to outStrSubKey
|
||||||
|
Sub ParseHiveAndSubKey(strRawKey, outConstHive, outStrSubKey)
|
||||||
|
' split into two parts to deduce the hive and the sub key
|
||||||
|
arrSplitted = Split(strRawKey, "\", 2, 1)
|
||||||
|
|
||||||
|
If UBound(arrSplitted) > 0 Then
|
||||||
|
strHive = arrSplitted(0)
|
||||||
|
outStrSubKey = arrSplitted(1)
|
||||||
|
Else
|
||||||
|
strHive = strRawKey
|
||||||
|
outStrSubKey = ""
|
||||||
|
End If
|
||||||
|
|
||||||
|
outConstHive = StringToHiveConst(UCase(strHive))
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Function ArrayRemoveAt(arr, pos)
|
||||||
|
Dim i
|
||||||
|
If IsArray(arr) Then
|
||||||
|
If pos >= 0 And pos <= UBound(arr) Then
|
||||||
|
For i = pos To UBound(arr) - 1
|
||||||
|
arr(i) = arr(i + 1)
|
||||||
|
Next
|
||||||
|
ReDim Preserve arr(UBound(arr) - 1)
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Sub ParseHiveAndSubKeyAndValue(strRawKey, outConstHive, outStrSubKey, outStrValue)
|
||||||
|
' split into two parts to deduce the hive and the sub key
|
||||||
|
arrSplitted = Split(strRawKey, "\", -1, 1)
|
||||||
|
|
||||||
|
If UBound(arrSplitted) > 0 Then
|
||||||
|
strHive = arrSplitted(0)
|
||||||
|
outStrValue = arrSplitted(UBound(arrSplitted))
|
||||||
|
test = ArrayRemoveAt(arrSplitted, UBound(arrSplitted))
|
||||||
|
test = ArrayRemoveAt(arrSplitted, 0)
|
||||||
|
outStrSubKey = Join(arrSplitted, "\")
|
||||||
|
Else
|
||||||
|
strHive = strRawKey
|
||||||
|
outStrSubKey = ""
|
||||||
|
End If
|
||||||
|
|
||||||
|
outConstHive = StringToHiveConst(UCase(strHive))
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Function StringToHiveConst(strHive)
|
||||||
|
|
||||||
|
Select Case strHive
|
||||||
|
Case "HKCR"
|
||||||
|
StringToHiveConst = HKEY_CLASSES_ROOT
|
||||||
|
Case "HKCU"
|
||||||
|
StringToHiveConst = HKEY_CURRENT_USER
|
||||||
|
Case "HKLM"
|
||||||
|
StringToHiveConst = HKEY_LOCAL_MACHINE
|
||||||
|
Case "HKU"
|
||||||
|
StringToHiveConst = HKEY_USERS
|
||||||
|
Case "HKCC"
|
||||||
|
StringToHiveConst = HKEY_CURRENT_CONFIG
|
||||||
|
Case Else
|
||||||
|
StringToHiveConst = Null
|
||||||
|
End Select
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
' TODO: this entire "by type" should be transformed into OOP style
|
||||||
|
' where each type will have a class with render(), getValue() etc...
|
||||||
|
|
||||||
|
' convert a value type number into a string label
|
||||||
|
Function RenderType(intType)
|
||||||
|
RenderType = "REG_UNKNOWN"
|
||||||
|
|
||||||
|
Select Case intType
|
||||||
|
Case 0
|
||||||
|
RenderType = "REG_NONE"
|
||||||
|
Case 1
|
||||||
|
RenderType = "REG_SZ"
|
||||||
|
Case 2
|
||||||
|
RenderType = "REG_EXPAND_SZ"
|
||||||
|
Case 3
|
||||||
|
RenderType = "REG_BINARY"
|
||||||
|
Case 4
|
||||||
|
RenderType = "REG_DWORD"
|
||||||
|
Case 7
|
||||||
|
RenderType = "REG_MULTI_SZ"
|
||||||
|
Case 11
|
||||||
|
RenderType = "REG_QWORD"
|
||||||
|
Case Else
|
||||||
|
' TODO: should report / throw an error here
|
||||||
|
WriteErr("invalid Registry Value Type " & intType)
|
||||||
|
|
||||||
|
End Select
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
' render by value type:
|
||||||
|
' string will return as a string with double quotes, e.g "value"
|
||||||
|
' multi string values which return as an array ot strings "["1", "2"]" (double quotes included ofc)
|
||||||
|
' numeric values like DWORD and QWORD just return as the number e.g. 1
|
||||||
|
' byte arrays such as reg_binary return as an array of ints, e.g [1,2,3]
|
||||||
|
Function RenderValueByType(intType, varValue)
|
||||||
|
|
||||||
|
Select Case intType
|
||||||
|
' REG_NONE
|
||||||
|
Case 0
|
||||||
|
RenderValueByType = "0"
|
||||||
|
|
||||||
|
' REG_SZ
|
||||||
|
Case 1
|
||||||
|
RenderValueByType = """" & JsonSafe(varValue) & """"
|
||||||
|
|
||||||
|
' REG_EXPAND_SZ
|
||||||
|
Case 2
|
||||||
|
RenderValueByType = """" & JsonSafe(varValue) & """"
|
||||||
|
|
||||||
|
' REG_BINARY
|
||||||
|
Case 3
|
||||||
|
RenderValueByType = RenderByteArray(varValue)
|
||||||
|
|
||||||
|
' REG_DWORD
|
||||||
|
Case 4
|
||||||
|
RenderValueByType= varValue
|
||||||
|
|
||||||
|
' REG_MULYI_SZ'
|
||||||
|
Case 7
|
||||||
|
|
||||||
|
RenderValueByType = RenderStringArray(varValue)
|
||||||
|
' REG_QWORD
|
||||||
|
Case 11
|
||||||
|
RenderValueByType = varValue
|
||||||
|
Case Else
|
||||||
|
' TODO: should report / throw an error here
|
||||||
|
WriteErr("invalid Registry Value Type " & intType)
|
||||||
|
End Select
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
' get the value of a registry based on its value type and assign it to out parameter outVarValue
|
||||||
|
Sub GetValueByType(constHive, strKey, strValueName, intType, outVarValue)
|
||||||
|
|
||||||
|
Select Case intType
|
||||||
|
' REG_NONE
|
||||||
|
Case 0
|
||||||
|
GetStringValue constHive, strKey, strValueName, "0"
|
||||||
|
Exit Sub
|
||||||
|
|
||||||
|
' REG_SZ
|
||||||
|
Case 1
|
||||||
|
GetStringValue constHive, strKey, strValueName, outVarValue
|
||||||
|
Exit Sub
|
||||||
|
|
||||||
|
' REG_EXPAND_SZ
|
||||||
|
Case 2
|
||||||
|
GetExpandedStringValue constHive, strKey, strValueName, outVarValue
|
||||||
|
Exit Sub
|
||||||
|
|
||||||
|
' REG_BINARY
|
||||||
|
Case 3
|
||||||
|
GetBinaryValue constHive, strKey, strValueName, outVarValue
|
||||||
|
Exit Sub
|
||||||
|
|
||||||
|
' REG_DWORD
|
||||||
|
Case 4
|
||||||
|
GetDWORDValue constHive, strKey, strValueName, outVarValue
|
||||||
|
|
||||||
|
' #21 - VBS does not support UInt32. This is the workaround
|
||||||
|
If outVarValue < 0 Then outVarValue = 4294967296 + outVarValue
|
||||||
|
|
||||||
|
Exit Sub
|
||||||
|
|
||||||
|
' REG_MULYI_SZ'
|
||||||
|
Case 7
|
||||||
|
GetMultiStringValue constHive, strKey, strValueName, outVarValue
|
||||||
|
Exit Sub
|
||||||
|
|
||||||
|
' REG_QWORD
|
||||||
|
Case 11
|
||||||
|
GetQWORDValue constHive, strKey, strValueName, outVarValue
|
||||||
|
Exit Sub
|
||||||
|
|
||||||
|
Case Else
|
||||||
|
' TODO: should report / throw an error here
|
||||||
|
WriteErr("invalid Registry Value Type " & intType)
|
||||||
|
End Select
|
||||||
|
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
' render a byte array as a json array of numbers
|
||||||
|
Function RenderByteArray(arr)
|
||||||
|
RenderByteArray = "[]"
|
||||||
|
|
||||||
|
If Not IsNull(arr) Then
|
||||||
|
RenderByteArray = "[" & Join(arr, ",") & "]"
|
||||||
|
End If
|
||||||
|
End Function
|
||||||
|
|
||||||
|
' render a string array as json string array
|
||||||
|
Function RenderStringArray(arr)
|
||||||
|
Result = "["
|
||||||
|
If Not IsNull(arr) Then
|
||||||
|
For t = 0 To UBound(arr)
|
||||||
|
If (t > 0) Then
|
||||||
|
Result = Result & ","
|
||||||
|
End If
|
||||||
|
|
||||||
|
Result = Result & """" & JsonSafe(arr(t)) & """"
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
Result = Result & "]"
|
||||||
|
|
||||||
|
RenderStringArray = Result
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function ToBinaryValue(strValue)
|
||||||
|
|
||||||
|
arrValue = Split(strValue, ",")
|
||||||
|
|
||||||
|
If IsNull(arrValue) Then
|
||||||
|
ToBinaryValue = Array()
|
||||||
|
Exit Function
|
||||||
|
End If
|
||||||
|
|
||||||
|
For i = 0 To UBound(arrValue)
|
||||||
|
arrValue(i) = CInt(arrValue(i))
|
||||||
|
Next
|
||||||
|
|
||||||
|
ToBinaryValue = arrValue
|
||||||
|
End Function
|
162
public/regedit-vbs/util.vbs
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
Set stdout = WScript.StdOut
|
||||||
|
Set stderr = WScript.StdErr
|
||||||
|
Set stdin = WScript.StdIn
|
||||||
|
Set args = WScript.Arguments
|
||||||
|
Set fs = CreateObject("scripting.filesystemobject")
|
||||||
|
Dim OSArchitecture
|
||||||
|
|
||||||
|
Sub WriteErr(message)
|
||||||
|
stderr.Write message
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Sub WriteLineErr(message)
|
||||||
|
stderr.WriteLine message
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Sub Write(message)
|
||||||
|
stdout.Write message
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Sub WriteLine(message)
|
||||||
|
stdout.WriteLine message
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Function IndexOf(varNeedle, arrHaystack)
|
||||||
|
IndexOf = -1
|
||||||
|
|
||||||
|
If Not IsArray(arrHaystack) Then
|
||||||
|
Exit Function
|
||||||
|
End If
|
||||||
|
|
||||||
|
For xyz = 0 To UBound(arrHaystack)
|
||||||
|
If arrHaystack(xyz) = varNeedle Then
|
||||||
|
IndexOf = xyz
|
||||||
|
Exit Function
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Sub CheckZeroArgs(message)
|
||||||
|
' bail if args are missing
|
||||||
|
If args.Count = 0 Then
|
||||||
|
WriteLineErr message
|
||||||
|
WScript.Quit 25121
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Dim ALLOWED_OS_ARCHITECTURE_VALUES: ALLOWED_OS_ARCHITECTURE_VALUES = Array("S", "A", "32", "64")
|
||||||
|
|
||||||
|
'
|
||||||
|
' determine the architecture of the operating system, that will be used. there are 4 possibilities:
|
||||||
|
' A - means agnostic
|
||||||
|
' S - means that we want to use a specific architecture, but auto detect Item
|
||||||
|
' 32 - explicitly use 32 bit architecture
|
||||||
|
' 64 - explicitly use 64 bit architecture
|
||||||
|
'
|
||||||
|
Sub DetermineOSArchitecture()
|
||||||
|
strArchitecture = args(0)
|
||||||
|
|
||||||
|
If IsNull(strArchitecture) Then
|
||||||
|
WriteLineErr "missing architecture argument"
|
||||||
|
WScript.Quit 25124
|
||||||
|
End If
|
||||||
|
|
||||||
|
strArchitecture = UCase(strArchitecture)
|
||||||
|
|
||||||
|
If IndexOf(strArchitecture, ALLOWED_OS_ARCHITECTURE_VALUES) = -1 Then
|
||||||
|
WriteLineErr "invalid architecture argument"
|
||||||
|
WScript.Quit 25124
|
||||||
|
End If
|
||||||
|
|
||||||
|
If (strArchitecture = "S") Then
|
||||||
|
OSArchitecture = GetOSArchitecture()
|
||||||
|
If OSArchitecture = -1 Then
|
||||||
|
WriteLineErr "invalid os architecture detected " & OSArchitecture
|
||||||
|
WScript.Quit 25126
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
OSArchitecture = strArchitecture
|
||||||
|
End If
|
||||||
|
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Sub Include(sPath)
|
||||||
|
' TODO this is fragile, but should work for "modules" nested relatively to script root
|
||||||
|
include_ScriptPath = Left(WScript.ScriptFullName, InStr(WScript.ScriptFullName, WScript.ScriptName) - 2)
|
||||||
|
sPath = include_ScriptPath & "\" & sPath
|
||||||
|
|
||||||
|
include_code = fs.OpenTextFile(sPath).ReadAll
|
||||||
|
ExecuteGlobal include_code
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Function GetOSArchitecture()
|
||||||
|
|
||||||
|
Dim ObjWMI, ColSettings, ObjProcessor
|
||||||
|
Dim StrComputer, ObjNetwork
|
||||||
|
|
||||||
|
Set ObjWMI = GetObject("winmgmts:\Root\CIMV2")
|
||||||
|
Set ColSettings = ObjWMI.ExecQuery ("SELECT DataWidth, AddressWidth, Architecture FROM Win32_Processor")
|
||||||
|
|
||||||
|
' TODO: I make two assumptions here:
|
||||||
|
' 1. Eveyone will have CPU0 device
|
||||||
|
' 2. There is only one cpu defined in the wmi database (and if not, then they are all of the same architecture)
|
||||||
|
Set ObjProcessor = ColSettings.Item("Win32_Processor.DeviceID=""CPU0""")
|
||||||
|
|
||||||
|
If ObjProcessor.Architecture = 0 AND ObjProcessor.AddressWidth = 32 Then
|
||||||
|
GetOSArchitecture = 32
|
||||||
|
ElseIf (ObjProcessor.Architecture = 6 OR ObjProcessor.Architecture = 9) AND ObjProcessor.DataWidth = 64 AND ObjProcessor.AddressWidth = 32 Then
|
||||||
|
GetOSArchitecture = 32
|
||||||
|
ElseIf (ObjProcessor.Architecture = 6 OR ObjProcessor.Architecture = 9) AND ObjProcessor.DataWidth = 64 AND ObjProcessor.AddressWidth = 64 Then
|
||||||
|
GetOSArchitecture = 64
|
||||||
|
Else
|
||||||
|
GetOSArchitecture = -1
|
||||||
|
End If
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Function JsonSafe(inStrText)
|
||||||
|
If inStrText = "" Then
|
||||||
|
JsonSafe = ""
|
||||||
|
Exit Function
|
||||||
|
End If
|
||||||
|
Dim outStrText: outStrText = inStrText
|
||||||
|
outStrText = Replace(outStrText, "\", "\\")
|
||||||
|
outStrText = Replace(outStrText, vbcrlf, "\\r\\n")
|
||||||
|
outStrText = Replace(outStrText, vblf, "\\n")
|
||||||
|
outStrText = Replace(outStrText, vbcr, "\\r")
|
||||||
|
outStrText = Replace(outStrText, """", "\""")
|
||||||
|
outStrText = JsonU(outStrText)
|
||||||
|
JsonSafe = outStrText
|
||||||
|
End Function
|
||||||
|
|
||||||
|
'TODO: need to change this function's name to something more appropriate
|
||||||
|
Function JsonU(astr)
|
||||||
|
|
||||||
|
If isNull(astr) Then
|
||||||
|
JsonU = ""
|
||||||
|
Exit Function
|
||||||
|
End If
|
||||||
|
|
||||||
|
Dim c
|
||||||
|
Dim utftext: utftext = ""
|
||||||
|
|
||||||
|
For n = 1 To Len(astr)
|
||||||
|
c = CLng(AscW(Mid(astr, n, 1)))
|
||||||
|
|
||||||
|
If c < 0 Then
|
||||||
|
c = &H10000 + c
|
||||||
|
End If
|
||||||
|
|
||||||
|
If c < &H80 Then
|
||||||
|
utftext = utftext & Mid(astr, n, 1)
|
||||||
|
ElseIf c < &H100 Then
|
||||||
|
utftext = utftext & "\u00" & Hex(c)
|
||||||
|
ElseIf c < &H1000 Then
|
||||||
|
utftext = utftext & "\u0" & Hex(c)
|
||||||
|
Else
|
||||||
|
utftext = utftext & "\u" & Hex(c)
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
|
||||||
|
JsonU = utftext
|
||||||
|
End Function
|
52
public/regedit-vbs/wsRegReadList.wsf
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
'
|
||||||
|
' Lists the values of a given registry path, this script takes its input from stdin
|
||||||
|
'
|
||||||
|
' cscript regListStream.wsf A "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\AppData"
|
||||||
|
'
|
||||||
|
' Will Yield:
|
||||||
|
'
|
||||||
|
' {
|
||||||
|
' "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\AppData": "value here"
|
||||||
|
' }
|
||||||
|
<job id="regRead">
|
||||||
|
<script language="VBScript" src="util.vbs" />
|
||||||
|
<script language="VBScript" src="regUtil.vbs" />
|
||||||
|
<script language="VBScript">
|
||||||
|
CheckZeroArgs("usage: cscript wsRegRead.wsf architecture path1...pathN")
|
||||||
|
DetermineOSArchitecture()
|
||||||
|
LoadRegistryImplementationByOSArchitecture()
|
||||||
|
|
||||||
|
set ws = createobject("Wscript.shell")
|
||||||
|
|
||||||
|
Write "["
|
||||||
|
On Error Resume Next
|
||||||
|
For v = 1 To args.Count - 1
|
||||||
|
If (v > 1) Then
|
||||||
|
Write ","
|
||||||
|
End If
|
||||||
|
|
||||||
|
Dim key: key = trim(args(v))
|
||||||
|
|
||||||
|
' not really needed except for validation
|
||||||
|
ParseHiveAndSubKeyAndValue key, constHive, strSubKey, strValue
|
||||||
|
|
||||||
|
if IsNull(constHive) Then
|
||||||
|
WriteLineErr "unsupported hive " & args(v)
|
||||||
|
WScript.Quit 25122
|
||||||
|
End If
|
||||||
|
|
||||||
|
Write "{ ""path"" : """ & JsonSafe(key) & """, "
|
||||||
|
|
||||||
|
Dim result: result = ws.RegRead(args(v))
|
||||||
|
Dim exists: exists = "true"
|
||||||
|
|
||||||
|
If Err.Number <> 0 Then
|
||||||
|
exists = "false"
|
||||||
|
End if
|
||||||
|
|
||||||
|
Write """exists"": " & exists & ", "
|
||||||
|
Write """value"": """ & JsonSafe(result) & """}" & vbcrlf
|
||||||
|
Next
|
||||||
|
Write "]"
|
||||||
|
</script>
|
||||||
|
</job>
|
47
public/regedit-vbs/wsRegReadListStream.wsf
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
'
|
||||||
|
' Lists the values of a given registry path, this script takes its input from stdin
|
||||||
|
'
|
||||||
|
' echo HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\AppData | cscript regListStream.wsf A
|
||||||
|
'
|
||||||
|
' Will Yield:
|
||||||
|
'
|
||||||
|
' {
|
||||||
|
' "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\AppData": "value here"
|
||||||
|
' }
|
||||||
|
<job id="regRead">
|
||||||
|
<script language="VBScript" src="util.vbs" />
|
||||||
|
<script language="VBScript" src="regUtil.vbs" />
|
||||||
|
<script language="VBScript">
|
||||||
|
CheckZeroArgs("usage: echo KEY | cscript wsRegRead.wsf architecture")
|
||||||
|
DetermineOSArchitecture()
|
||||||
|
LoadRegistryImplementationByOSArchitecture()
|
||||||
|
|
||||||
|
set ws = createobject("Wscript.shell")
|
||||||
|
|
||||||
|
Do While Not stdin.AtEndOfLine
|
||||||
|
|
||||||
|
strLine = stdin.ReadLine()
|
||||||
|
strLine = unescape(trim(strLine))
|
||||||
|
|
||||||
|
' not really needed except for validation
|
||||||
|
ParseHiveAndSubKeyAndValue strLine, constHive, strSubKey, strValue
|
||||||
|
|
||||||
|
if IsNull(constHive) Then
|
||||||
|
WriteLineErr "unsupported hive " & strLine
|
||||||
|
WScript.Quit 25122
|
||||||
|
End If
|
||||||
|
|
||||||
|
Write "{ ""path"" : """ & JsonSafe(strLine) & """, "
|
||||||
|
|
||||||
|
Dim result: result = ws.RegRead(strLine)
|
||||||
|
Dim exists: exists = "true"
|
||||||
|
|
||||||
|
If Err.Number <> 0 Then
|
||||||
|
exists = "false"
|
||||||
|
End if
|
||||||
|
|
||||||
|
Write """exists"": " & exists & ", "
|
||||||
|
Write """value"": """ & JsonSafe(result) & """}" & vbcrlf
|
||||||
|
Loop
|
||||||
|
</script>
|
||||||
|
</job>
|
BIN
public/w_c.exe
Normal file
154
src/App.jsx
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
import { useMachine } from '@xstate/react';
|
||||||
|
import { Table, Button, Progress, Alert } from 'antd';
|
||||||
|
import { shell } from 'electron';
|
||||||
|
import {
|
||||||
|
DownloadOutlined,
|
||||||
|
PlaySquareOutlined,
|
||||||
|
ClearOutlined,
|
||||||
|
GithubOutlined,
|
||||||
|
EyeOutlined,
|
||||||
|
FormatPainterOutlined,
|
||||||
|
RedoOutlined,
|
||||||
|
} from '@ant-design/icons';
|
||||||
|
import fsm from './fsm';
|
||||||
|
|
||||||
|
import './App.less';
|
||||||
|
function App() {
|
||||||
|
const [state, send] = useMachine(fsm);
|
||||||
|
const { captureList, currentUrl, downloadProgress } = state.context;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="App">
|
||||||
|
{state.matches('检测初始化') ? <div>检测中……</div> : null}
|
||||||
|
{state.matches('初始化完成') ? (
|
||||||
|
<div className="App-inited">
|
||||||
|
<Button
|
||||||
|
className="App-inited-clear"
|
||||||
|
icon={<ClearOutlined />}
|
||||||
|
onClick={() => send('e_清空捕获记录')}
|
||||||
|
>
|
||||||
|
清空
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
className="App-inited-github"
|
||||||
|
icon={<GithubOutlined />}
|
||||||
|
onClick={() => shell.openExternal('https://github.com/lecepin/WeChatVideoDownloader')}
|
||||||
|
type="primary"
|
||||||
|
ghost
|
||||||
|
>
|
||||||
|
Star
|
||||||
|
</Button>
|
||||||
|
<Table
|
||||||
|
sticky
|
||||||
|
dataSource={captureList}
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
title: '视频地址(捕获中……)',
|
||||||
|
dataIndex: 'url',
|
||||||
|
key: 'url',
|
||||||
|
render: value => value,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '大小',
|
||||||
|
dataIndex: 'prettySize',
|
||||||
|
key: 'prettySize',
|
||||||
|
width: '100px',
|
||||||
|
render: value => value,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'action',
|
||||||
|
key: 'action',
|
||||||
|
width: '200px',
|
||||||
|
render: (_, { url, fullFileName }) => (
|
||||||
|
<div>
|
||||||
|
{fullFileName ? (
|
||||||
|
<Button
|
||||||
|
icon={<EyeOutlined />}
|
||||||
|
type="primary"
|
||||||
|
onClick={() => {
|
||||||
|
shell.openPath(fullFileName);
|
||||||
|
}}
|
||||||
|
size="small"
|
||||||
|
ghost
|
||||||
|
>
|
||||||
|
查看
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Button
|
||||||
|
icon={<DownloadOutlined />}
|
||||||
|
type="primary"
|
||||||
|
onClick={() => {
|
||||||
|
send({ type: 'e_下载', url });
|
||||||
|
}}
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
下载
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Button
|
||||||
|
icon={<PlaySquareOutlined />}
|
||||||
|
onClick={() => {
|
||||||
|
send({ type: 'e_预览', url });
|
||||||
|
}}
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
预览
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
pagination={{ position: ['none', 'none'] }}
|
||||||
|
></Table>
|
||||||
|
|
||||||
|
{state.matches('初始化完成.预览') ? (
|
||||||
|
<div
|
||||||
|
className="App-inited-preview"
|
||||||
|
onClick={e => {
|
||||||
|
e.target == e.currentTarget && send('e_关闭');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<video src={currentUrl} controls autoPlay></video>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{state.matches('初始化完成.下载.下载中') ? (
|
||||||
|
<div className="App-inited-download">
|
||||||
|
<Progress type="circle" percent={downloadProgress} />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{state.matches('未初始化') ? (
|
||||||
|
<div className="App-uninit">
|
||||||
|
<Alert message="首次进入,请先初始化~" type="warning" showIcon closable={false} />
|
||||||
|
<Button
|
||||||
|
size="large"
|
||||||
|
onClick={() => send('e_开始初始化')}
|
||||||
|
type="primary"
|
||||||
|
icon={<FormatPainterOutlined />}
|
||||||
|
>
|
||||||
|
初始化
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button size="large" onClick={() => send('e_重新检测')} icon={<RedoOutlined />}>
|
||||||
|
重新检测
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{state.matches('开启服务失败') ? (
|
||||||
|
<div className="App-uninit">
|
||||||
|
<Alert message="开启服务失败,请允许开启" type="error" showIcon closable={false} />
|
||||||
|
<Button size="large" onClick={() => send('e_重试')} type="primary">
|
||||||
|
尝试开启
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App;
|
52
src/App.less
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
.App {
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
&-uninit{
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
& button{
|
||||||
|
margin-top: 50px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-inited {
|
||||||
|
&-clear {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-github {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-preview {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 9999999999;
|
||||||
|
|
||||||
|
& > video {
|
||||||
|
max-width: 90%;
|
||||||
|
max-height: 90%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&-download {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 9999999999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
262
src/fsm.js
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
import { createMachine, actions } from 'xstate';
|
||||||
|
import { ipcRenderer } from 'electron';
|
||||||
|
import prettyBytes from 'pretty-bytes';
|
||||||
|
import { uniqBy } from 'lodash';
|
||||||
|
import { message } from 'antd';
|
||||||
|
|
||||||
|
export default createMachine(
|
||||||
|
{
|
||||||
|
id: '微信视频号下载工具',
|
||||||
|
context: {
|
||||||
|
captureList: [],
|
||||||
|
currentUrl: '',
|
||||||
|
savePath: '',
|
||||||
|
downloadProgress: 0,
|
||||||
|
},
|
||||||
|
initial: '检测初始化',
|
||||||
|
states: {
|
||||||
|
检测初始化: {
|
||||||
|
id: '检测初始化',
|
||||||
|
invoke: {
|
||||||
|
src: 'invoke_初始化信息',
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
e_初始化完成: {
|
||||||
|
target: '初始化完成',
|
||||||
|
},
|
||||||
|
e_未初始化: {
|
||||||
|
target: '未初始化',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
未初始化: {
|
||||||
|
initial: '空闲',
|
||||||
|
on: {
|
||||||
|
e_重新检测: {
|
||||||
|
target: '检测初始化',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
states: {
|
||||||
|
空闲: {
|
||||||
|
on: {
|
||||||
|
e_开始初始化: {
|
||||||
|
target: '开始初始化',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
开始初始化: {
|
||||||
|
invoke: {
|
||||||
|
src: 'invoke_开始初始化',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
初始化完成: {
|
||||||
|
initial: '空闲',
|
||||||
|
id: '初始化完成',
|
||||||
|
invoke: {
|
||||||
|
src: 'invoke_启动服务',
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
e_视频捕获: {
|
||||||
|
actions: 'action_视频捕获',
|
||||||
|
},
|
||||||
|
e_开启服务失败: {
|
||||||
|
target: '开启服务失败',
|
||||||
|
},
|
||||||
|
e_清空捕获记录: {
|
||||||
|
actions: 'action_清空捕获记录',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
states: {
|
||||||
|
空闲: {
|
||||||
|
on: {
|
||||||
|
e_下载: {
|
||||||
|
actions: 'action_设置当前地址',
|
||||||
|
target: '下载',
|
||||||
|
},
|
||||||
|
e_预览: {
|
||||||
|
actions: 'action_设置当前地址',
|
||||||
|
target: '预览',
|
||||||
|
},
|
||||||
|
e_改变规则: {
|
||||||
|
actions: 'action_改变规则',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
下载: {
|
||||||
|
initial: '选择位置',
|
||||||
|
states: {
|
||||||
|
选择位置: {
|
||||||
|
on: {
|
||||||
|
e_确认位置: { actions: 'action_存储下载位置', target: '下载中' },
|
||||||
|
e_取消: { target: '#初始化完成.空闲' },
|
||||||
|
},
|
||||||
|
invoke: {
|
||||||
|
src: 'invoke_选择下载位置',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
下载中: {
|
||||||
|
on: {
|
||||||
|
e_进度变化: {
|
||||||
|
actions: 'action_进度变化',
|
||||||
|
},
|
||||||
|
e_下载完成: {
|
||||||
|
target: '#初始化完成.空闲',
|
||||||
|
actions: 'action_下载完成',
|
||||||
|
},
|
||||||
|
e_下载失败: {
|
||||||
|
target: '#初始化完成.空闲',
|
||||||
|
actions: 'action_下载失败',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
invoke: {
|
||||||
|
src: 'invoke_下载视频',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
下载完成: {
|
||||||
|
on: {
|
||||||
|
e_取消: { target: '#初始化完成.空闲' },
|
||||||
|
e_打开文件位置: {
|
||||||
|
actions: 'action_打开文件位置',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
预览: {
|
||||||
|
on: {
|
||||||
|
e_关闭: {
|
||||||
|
target: '空闲',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
开启服务失败: {
|
||||||
|
on: {
|
||||||
|
e_重试: {
|
||||||
|
target: '初始化完成',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
services: {
|
||||||
|
invoke_初始化信息: () => send => {
|
||||||
|
ipcRenderer.invoke('invoke_初始化信息').then(data => {
|
||||||
|
if (data === true) {
|
||||||
|
send('e_初始化完成');
|
||||||
|
} else {
|
||||||
|
send('e_未初始化');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
invoke_开始初始化: (context, event) => send => {
|
||||||
|
ipcRenderer
|
||||||
|
.invoke('invoke_开始初始化')
|
||||||
|
.catch(() => {})
|
||||||
|
.finally(() => send('e_重新检测'));
|
||||||
|
},
|
||||||
|
invoke_启动服务: (context, event) => send => {
|
||||||
|
const fnDealVideoCapture = (eName, { url, size }) => {
|
||||||
|
send({ type: 'e_视频捕获', url, size });
|
||||||
|
};
|
||||||
|
|
||||||
|
ipcRenderer
|
||||||
|
.invoke('invoke_启动服务')
|
||||||
|
.then(() => {
|
||||||
|
ipcRenderer.on('VIDEO_CAPTURE', fnDealVideoCapture);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
send('e_开启服务失败');
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
ipcRenderer.removeListener('VIDEO_CAPTURE', fnDealVideoCapture);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
invoke_选择下载位置: (context, event) => send => {
|
||||||
|
ipcRenderer
|
||||||
|
.invoke('invoke_选择下载位置')
|
||||||
|
.then(data => {
|
||||||
|
send({
|
||||||
|
type: 'e_确认位置',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => send('e_取消'));
|
||||||
|
},
|
||||||
|
invoke_下载视频:
|
||||||
|
({ currentUrl, savePath }) =>
|
||||||
|
send => {
|
||||||
|
ipcRenderer
|
||||||
|
.invoke('invoke_下载视频', {
|
||||||
|
url: currentUrl,
|
||||||
|
savePath,
|
||||||
|
})
|
||||||
|
.then(({ fullFileName }) => {
|
||||||
|
send({ type: 'e_下载完成', fullFileName, currentUrl });
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
send('e_下载失败');
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcRenderer.on('e_进度变化', (event, arg) => {
|
||||||
|
send({
|
||||||
|
type: 'e_进度变化',
|
||||||
|
data: arg,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
ipcRenderer.removeAllListeners('e_进度变化');
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
action_视频捕获: actions.assign(({ captureList }, { size, url }) => {
|
||||||
|
captureList.push({ size, url, prettySize: prettyBytes(+size) });
|
||||||
|
|
||||||
|
return {
|
||||||
|
captureList: uniqBy(captureList, 'url'),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
action_清空捕获记录: actions.assign(() => {
|
||||||
|
return {
|
||||||
|
captureList: [],
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
action_设置当前地址: actions.assign((_, { url }) => {
|
||||||
|
return {
|
||||||
|
currentUrl: url,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
action_存储下载位置: actions.assign((_, { data }) => {
|
||||||
|
return {
|
||||||
|
savePath: data,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
action_进度变化: actions.assign((_, { data }) => {
|
||||||
|
return {
|
||||||
|
downloadProgress: ~~(data * 100),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
action_下载完成: actions.assign(({ captureList }, { fullFileName, currentUrl }) => {
|
||||||
|
return {
|
||||||
|
captureList: captureList.map(item => {
|
||||||
|
if (item.url === currentUrl) {
|
||||||
|
item.fullFileName = fullFileName;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
action_下载失败: actions.log(() => {
|
||||||
|
message.error('网络错误,请重试');
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
12
src/index.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom/client';
|
||||||
|
import App from './App';
|
||||||
|
|
||||||
|
import 'antd/dist/antd.css';
|
||||||
|
|
||||||
|
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||||
|
root.render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>,
|
||||||
|
);
|
BIN
src/logo.png
Normal file
After Width: | Height: | Size: 194 KiB |
18
webpack.electron.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
entry: path.resolve(__dirname, './electron/index.js'),
|
||||||
|
output: {
|
||||||
|
filename: 'index.js',
|
||||||
|
path: path.resolve(__dirname, './build-electron'),
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [],
|
||||||
|
},
|
||||||
|
devtool: 'source-map',
|
||||||
|
target: 'electron-main',
|
||||||
|
node: false,
|
||||||
|
stats: {
|
||||||
|
errorDetails: true,
|
||||||
|
},
|
||||||
|
};
|