[Fix VC runtime detection] [Remote mount changes]

This commit is contained in:
2019-10-07 16:18:03 -05:00
parent 52cd85ca6f
commit 522626e808
5 changed files with 101 additions and 62 deletions

View File

@@ -9,27 +9,27 @@
"@fortawesome/free-solid-svg-icons": "^5.11.2", "@fortawesome/free-solid-svg-icons": "^5.11.2",
"@fortawesome/react-fontawesome": "^0.1.5", "@fortawesome/react-fontawesome": "^0.1.5",
"auto-launch": "^5.0.5", "auto-launch": "^5.0.5",
"axios": "^0.18.1", "axios": "^0.19.0",
"electron-debug": "^2.2.0", "electron-debug": "^3.0.1",
"font-awesome": "^4.7.0", "font-awesome": "^4.7.0",
"node-schedule": "^1.3.2", "node-schedule": "^1.3.2",
"randomstring": "^1.1.5", "randomstring": "^1.1.5",
"react": "^16.10.1", "react": "^16.10.2",
"react-dom": "^16.10.1", "react-dom": "^16.10.2",
"react-loader-spinner": "^2.3.0", "react-loader-spinner": "^3.1.4",
"react-redux": "^7.1.1", "react-redux": "^7.1.1",
"react-scripts": "2.1.8", "react-scripts": "2.1.8",
"react-tooltip": "^3.11.1", "react-tooltip": "^3.11.1",
"redux": "^4.0.4", "redux": "^4.0.4",
"redux-starter-kit": "^0.5.1", "redux-starter-kit": "^0.7.0",
"redux-thunk": "^2.3.0", "redux-thunk": "^2.3.0",
"unzipper": "^0.9.15", "unzipper": "^0.10.5",
"winreg": "^1.2.4" "winreg": "^1.2.4"
}, },
"devDependencies": { "devDependencies": {
"cross-env": "^5.2.1", "cross-env": "^6.0.3",
"electron": "^4.2.11", "electron": "^6.0.11",
"electron-builder": "^20.44.4", "electron-builder": "^21.2.0",
"extract-text-webpack-plugin": "^3.0.2", "extract-text-webpack-plugin": "^3.0.2",
"typescript": "^3.6.3", "typescript": "^3.6.3",
"webpack-browser-plugin": "^1.0.20" "webpack-browser-plugin": "^1.0.20"

View File

@@ -34,6 +34,11 @@ const StateIPC = require('../src/renderer/ipc/StateIPC');
const SystemIPC = require('../src/renderer/ipc/SystemIPC'); const SystemIPC = require('../src/renderer/ipc/SystemIPC');
const UpgradeIPC = require('../src/renderer/ipc/UpgradeIPC'); const UpgradeIPC = require('../src/renderer/ipc/UpgradeIPC');
const dimensions = {
height: ((os.platform() === 'darwin') ? 294 : 274) + ((os.platform() === 'win32') ? 30 : -20),
width: 428 + ((os.platform() === 'win32') ? 40 : (os.platform() === 'darwin') ? 150 : 160),
};
let isShutdown = false; let isShutdown = false;
let isQuiting = false; let isQuiting = false;
let isInstalling = false; let isInstalling = false;
@@ -77,19 +82,20 @@ const createWindow = () => {
} }
// Create the browser window. // Create the browser window.
const height = (process.env.ELECTRON_START_URL || (os.platform() === 'darwin') ? 294 : 274) + ((os.platform() === 'win32') ? 30 : -20);
mainWindow = new BrowserWindow({ mainWindow = new BrowserWindow({
width: 428 + ((os.platform() === 'win32') ? 40 : (os.platform() === 'darwin') ? 150 : 160), height: dimensions.height,
height: height, width: dimensions.width,
fullscreen: false, fullscreen: false,
resizable: false, resizable: false,
show: !launchHidden, show: !launchHidden,
title: 'Repertory UI', title: 'Repertory UI',
...extra, ...extra,
webPreferences: { webPreferences: {
nodeIntegration: true,
webSecurity: !process.env.ELECTRON_START_URL webSecurity: !process.env.ELECTRON_START_URL
} }
}); });
mainWindow.removeMenu();
if ((os.platform() === 'darwin') && launchHidden) { if ((os.platform() === 'darwin') && launchHidden) {
app.dock.hide(); app.dock.hide();
@@ -170,15 +176,15 @@ const createWindow = () => {
mainWindowTray = new Tray(image); mainWindowTray = new Tray(image);
autoLauncher autoLauncher
.isEnabled() .isEnabled()
.then((enabled) => { .then((enabled) => {
trayContextMenu.items[1].checked = enabled; trayContextMenu.items[1].checked = enabled;
mainWindowTray.setToolTip('Repertory UI'); mainWindowTray.setToolTip('Repertory UI');
mainWindowTray.setContextMenu(trayContextMenu) mainWindowTray.setContextMenu(trayContextMenu)
}) })
.catch(() => { .catch(() => {
closeApplication(); closeApplication();
}); });
mainWindow.loadURL(startUrl); mainWindow.loadURL(startUrl);
}; };

View File

@@ -37,12 +37,14 @@ export default connect(null, mapDispatchToProps)(props => {
switch (props.template.type) { switch (props.template.type) {
case "bool": case "bool":
data = <input checked={JSON.parse(props.value)} data = <input checked={JSON.parse(props.value)}
disabled={props.readOnly}
onChange={e=>handleChanged(e)} onChange={e=>handleChanged(e)}
type={'checkbox'}/>; type={'checkbox'}/>;
break; break;
case "double": case "double":
data = <input min={0.0} data = <input min={0.0}
disabled={props.readOnly}
onChange={e=>handleChanged(e)} onChange={e=>handleChanged(e)}
step={"0.01"} step={"0.01"}
className={'ConfigurationItemInput'} className={'ConfigurationItemInput'}
@@ -60,6 +62,7 @@ export default connect(null, mapDispatchToProps)(props => {
data = ( data = (
<select onChange={e=>handleChanged(e)} <select onChange={e=>handleChanged(e)}
className={'ConfigurationItemSelect'} className={'ConfigurationItemSelect'}
disabled={props.readOnly}
value={props.value}> value={props.value}>
{options} {options}
</select> </select>
@@ -69,6 +72,7 @@ export default connect(null, mapDispatchToProps)(props => {
case "string": case "string":
data = <input onChange={e=>handleChanged(e)} data = <input onChange={e=>handleChanged(e)}
className={'ConfigurationItemInput'} className={'ConfigurationItemInput'}
disabled={props.readOnly}
type={'text'} type={'text'}
value={props.value}/>; value={props.value}/>;
break; break;
@@ -76,6 +80,7 @@ export default connect(null, mapDispatchToProps)(props => {
case "uint8": case "uint8":
data = <input max={255} data = <input max={255}
min={0} min={0}
disabled={props.readOnly}
onChange={e=>handleChanged(e)} onChange={e=>handleChanged(e)}
className={'ConfigurationItemInput'} className={'ConfigurationItemInput'}
type={'number'} type={'number'}
@@ -85,6 +90,7 @@ export default connect(null, mapDispatchToProps)(props => {
case "uint16": case "uint16":
data = <input max={65535} data = <input max={65535}
min={0} min={0}
disabled={props.readOnly}
onChange={e=>handleChanged(e)} onChange={e=>handleChanged(e)}
className={'ConfigurationItemInput'} className={'ConfigurationItemInput'}
type={'number'} type={'number'}
@@ -94,6 +100,7 @@ export default connect(null, mapDispatchToProps)(props => {
case "uint32": case "uint32":
data = <input max={4294967295} data = <input max={4294967295}
min={0} min={0}
disabled={props.readOnly}
onChange={e=>handleChanged(e)} onChange={e=>handleChanged(e)}
className={'ConfigurationItemInput'} className={'ConfigurationItemInput'}
type={'number'} type={'number'}
@@ -103,6 +110,7 @@ export default connect(null, mapDispatchToProps)(props => {
case "uint64": case "uint64":
data = <input max={18446744073709551615} data = <input max={18446744073709551615}
min={0} min={0}
disabled={props.readOnly}
onChange={e=>handleChanged(e)} onChange={e=>handleChanged(e)}
className={'ConfigurationItemInput'} className={'ConfigurationItemInput'}
type={'number'} type={'number'}

View File

@@ -20,6 +20,7 @@ class Configuration extends IPCContainer {
ObjectLookup: {}, ObjectLookup: {},
OriginalItemList: [], OriginalItemList: [],
OriginalObjectLookup: {}, OriginalObjectLookup: {},
IsRemoteMount: false,
ItemList: [], ItemList: [],
Saving: false, Saving: false,
ShowAdvanced: false, ShowAdvanced: false,
@@ -87,6 +88,7 @@ class Configuration extends IPCContainer {
.map(key => { .map(key => {
return { return {
advanced: template[key] ? template[key].advanced : false, advanced: template[key] ? template[key].advanced : false,
hide_remote: template[key] ? template[key].hide_remote : false,
label: key, label: key,
remote: template[key] ? template[key].remote : false, remote: template[key] ? template[key].remote : false,
value: (template[key] && (template[key].type === 'object')) ? value: (template[key] && (template[key].type === 'object')) ?
@@ -143,8 +145,20 @@ class Configuration extends IPCContainer {
const list2 = this.createItemList(obj.value, this.state.Template[obj.label].template); const list2 = this.createItemList(obj.value, this.state.Template[obj.label].template);
objectLookup[obj.label] = list2.ItemList; objectLookup[obj.label] = list2.ItemList;
} }
const isRemoteMount = this.props.remoteSupported &&
JSON.parse(objectLookup['RemoteMount'].find(s => s.label === 'IsRemoteMount').value);
if (isRemoteMount) {
for (const obj of list.ObjectList) {
if (obj.hide_remote) {
delete objectLookup[obj.label];
}
}
}
const objectLookupCopy = JSON.parse(JSON.stringify(objectLookup)); const objectLookupCopy = JSON.parse(JSON.stringify(objectLookup));
this.setState({ this.setState({
IsRemoteMount: isRemoteMount,
ItemList: list.ItemList, ItemList: list.ItemList,
ObjectLookup: objectLookup, ObjectLookup: objectLookup,
OriginalItemList: itemListCopy, OriginalItemList: itemListCopy,
@@ -250,7 +264,7 @@ class Configuration extends IPCContainer {
const configurationItems = this.state.ItemList const configurationItems = this.state.ItemList
.map((k, i) => { .map((k, i) => {
return ( return (
(!k.advanced || (this.state.ShowAdvanced && k.advanced)) ? ((!this.state.IsRemoteMount || !k.hide_remote) && (!k.advanced || (this.state.ShowAdvanced && k.advanced))) ?
<ConfigurationItem advanced={k.advanced} <ConfigurationItem advanced={k.advanced}
changed={e=>this.handleItemChanged(e, i)} changed={e=>this.handleItemChanged(e, i)}
grouping={'Settings'} grouping={'Settings'}
@@ -278,6 +292,7 @@ class Configuration extends IPCContainer {
items={this.state.Template[key].template[k.label].items} items={this.state.Template[key].template[k.label].items}
key={i} key={i}
label={k.label} label={k.label}
readOnly={this.state.IsRemoteMount && ((k.label === 'RemoteHostNameOrIp') || (k.label === 'RemotePort'))}
template={this.state.Template[key].template[k.label]} template={this.state.Template[key].template[k.label]}
value={k.value}/> : value={k.value}/> :
null) null)

View File

@@ -488,46 +488,56 @@ module.exports.getMissingDependencies = dependencies => {
}; };
const Registry = require('winreg'); const Registry = require('winreg');
for (const dep of dependencies) { const checkRegistry = (dep, index) => {
let hive = null; if (index >= dep.registry.length) {
const hiveName = dep.registry[0].split('\\')[0]; missing.push(dep);
switch (hiveName) { resolveIfComplete();
case 'HKEY_CLASSES_ROOT': } else {
hive = Registry.HKCR; let hive = null;
break; const hiveName = dep.registry[index].split('\\')[0];
case 'HKEY_CURRENT_CONFIG': switch (hiveName) {
hive = Registry.HKCC; case 'HKEY_CLASSES_ROOT':
break; hive = Registry.HKCR;
case 'HKEY_CURRENT_USER': break;
hive = Registry.HKCU; case 'HKEY_CURRENT_CONFIG':
break; hive = Registry.HKCC;
case 'HKEY_LOCAL_MACHINE': break;
hive = Registry.HKLM; case 'HKEY_CURRENT_USER':
break; hive = Registry.HKCU;
case 'HKEY_USERS': break;
hive = Registry.HKU; case 'HKEY_LOCAL_MACHINE':
break; hive = Registry.HKLM;
default: break;
throw Error('Invalid registry hive: ' + hiveName); case 'HKEY_USERS':
} hive = Registry.HKU;
break;
const key = dep.registry[0].substr(hiveName.length); default:
const regKey = new Registry({ throw Error('Invalid registry hive: ' + hiveName);
hive: hive,
key: key
});
regKey.valueExists('DisplayName', (err, exists) => {
if (err || !exists) {
regKey.valueExists('ProductName', (err, exists) => {
if (err || !exists) {
missing.push(dep);
}
resolveIfComplete();
});
} else {
resolveIfComplete();
} }
});
const key = dep.registry[index].substr(hiveName.length);
const regKey = new Registry({
hive: hive,
key: key
});
regKey.valueExists('DisplayName', (err, exists) => {
if (err || !exists) {
regKey.valueExists('ProductName', (err, exists) => {
if (err || !exists) {
checkRegistry(dep, ++index);
} else {
resolveIfComplete();
}
});
} else {
resolveIfComplete();
}
});
}
};
for (const dependency of dependencies) {
checkRegistry(dependency,0);
} }
} else { } else {
for (const dep of dependencies) { for (const dep of dependencies) {