使用Electron在iFrame中运行Powershell

时间:2018-02-02 21:03:36

标签: javascript html node.js powershell electron

我正在尝试创建一个名为my-app的简单Electron应用程序,其中包含一个标准的main.js,它创建一个指向index.html的新浏览器窗口。

index.html内部是一个加载另一个名为iframe.html的本地文件的iframe。

iframe.html内部是一些单击时调用Javascript函数launchPowershell()的文本。

此函数位于renderer.js中,将创建一个新的Powershell对象,添加命令并调用该对象。

但是,每当我运行my-app并点击iframe.html中的文本时,我会收到一条错误,指出" require未定义"。

Error thrown

如果我将代码从iframe.html移到index.html并删除iframe,一切正常。

所以我相信我错过了一些让Electron使用iframe正常工作的东西。也许与我的Javascript变量范围有关。

有人可以提供任何建议吗?

的package.json:

{
  "name": "my-app",
  "version": "0.1.0",
  "main": "main.js"
}

的index.html:

<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" src="renderer.js" ></script>
    </head>
    <body>  
        <iframe id="iframe" src="iframe.html"></iframe>
    </body>
</html>

Iframe.html的:

<html>
<head>
    <script type="text/javascript" src="renderer.js" ></script>
</head>
<body>
    <a onclick="launchPowershell();">Launch powershell</a>
</body>
</html>

renderer.js:

function launchPowershell() {
    const powershell = require('node-powershell');

    // Create the PS Instance
    let ps = new powershell({
        executionPolicy: 'Bypass',
        noProfile: true
    })

    // Load the gun
    ps.addCommand("Powershell success!")

    // Pull the Trigger
    ps.invoke()
    .then(output => {
        console.log(output)
    })
    .catch(err => {
        console.error(err)
        ps.dispose()
    })
}

main.js:

const electron = require('electron')

// Module to control application life.
// const app = electron.app
const {app, Menu, dialog} = electron

// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow

const path = require('path')
const url = require('url')

// Declare some global variables
global.sharedObj = {
  cred: null
};

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow

function createMenu() {
  const template = [
    {
        label: 'View',
        submenu: [
          {
            role: 'reload'
          },
          {
            role: 'forcereload'
          },
          {
            role: 'toggledevtools'
          }
        ]
    },
    {
      label: 'Tools',
      submenu: [
        {
          label: 'Check Cred',
            click () {
                let user = (global.sharedObj.cred) ? global.sharedObj.cred.user : "Default"
                dialog.showMessageBox({
                    type: "info",
                    title: "Current Cred",
                    message: `The current user is: ${user}.`
                })
            }
        }
      ]
    }
  ]

  const menu = Menu.buildFromTemplate(template)
  Menu.setApplicationMenu(menu)
}

function createWindow () {
  // Use custom menu
  createMenu()

  // Create the browser window.
  mainWindow = new BrowserWindow({width: 800, height: 600})

  // and load the index.html of the app.
  mainWindow.loadURL(url.format({
    pathname: path.join(__dirname, 'index.html'),
    protocol: 'file:',
    slashes: true
  }))

  // Open the DevTools.
  mainWindow.webContents.openDevTools()

  // Emitted when the window is closed.
  mainWindow.on('closed', function () {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null
  })
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)

// Quit when all windows are closed.
app.on('window-all-closed', function () {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', function () {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    createWindow()
  }
})

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

1 个答案:

答案 0 :(得分:0)

弄清楚我的问题。基本上iFrame与Electron不兼容。最好使用webview。但是,由于加载外部网站(甚至是本地文件)时的安全限制,webview不能用于我的目的。

我的解决方案是将我的所有本地HTML文件简单地移动到我的主index.html文件中的div中,然后根据需要简单地切换它们的可行性。