【问题标题】:How to interact with controls in a pane with Javascript for Automation (Yosemite)如何使用 Javascript for Automation (Yosemite) 与窗格中的控件进行交互
【发布时间】:2014-12-25 11:55:38
【问题描述】:

我正在尝试将旧的 Applescript 转换为 Javascript。该脚本的目的是打开和关闭 Internet 共享。我已经能够打开共享窗格并找到 Internet 共享锚点,但无法弄清楚如何与窗格上的控件进行交互。在 Applescript 中,我让系统事件告诉系统首选项单击特定复选框,但到目前为止我使用 Javascript 尝试的所有内容都返回了钝错误。

这是我到目前为止所得到的:

prefs = Application('System Preferences')

sharePane = prefs.panes.byName('Sharing')

anchors = sharePane.anchors()

netAnchor = ""

for (i in anchors) {
    if (anchors[i].name().search('net') > -1) {
        netAnchor = anchors[i]
    }
}

【问题讨论】:

    标签: javascript applescript osx-yosemite


    【解决方案1】:

    给你。

    prefs = Application("System Preferences");
    prefs.activate();
    prefs.panes.byName("Sharing").reveal();
    
    SystemEvents = Application("System Events");
    procPref = SystemEvents.processes["System Preferences"];
    
    // option 1: fixed row number
    procPref.windows[0].groups[0].scrollAreas[0].tables[0].rows[6].checkboxes[0].click();
    

    或者,如果您更喜欢不依赖于知道确切行号的解决方案:

    prefs = Application("System Preferences");
    prefs.activate();
    prefs.panes.byName("Sharing").anchors.byName("Internet").reveal(); // achor needed for option #3
    
    SystemEvents = Application("System Events");
    procPref = SystemEvents.processes["System Preferences"];
    
    // option 2: select row by label
    procPref.windows[0].groups[0].scrollAreas[0].tables[0].rows().forEach(function(r) {
      if (r.staticTexts[0].name() === "Internet Sharing") r.checkboxes[0].click();
    });
    
    // option 3: let reveal select the correct row, then press space to toggle
    procPref.windows[0].groups[0].scrollAreas[0].focused = true;
    delay(1); // give it some time to get the window activated before pressing space
    SystemEvents.keystroke(" ");
    

    更新:添加选项 #2 和 #3 并列出详细信息。

    以下是可供选择的锚点列表:

    /* Internet */
    /* Services_PrinterSharing */
    /* Services_ARDService */
    /* Services_RemoteAppleEvent */
    /* Services_BluetoothSharing */
    /* Main */
    /* Services_DVDorCDSharing */
    /* Services_RemoteLogin */
    /* Services_ScreenSharing */
    /* Services_WindowsSharing */
    /* Services_PersonalFileSharing */
    

    以及显示行号和(英文)标签的行列表(在 Yosemite 10.10 中):

    /* 0: Screen Sharing */
    /* 1: File Sharing */
    /* 2: Printer Sharing */
    /* 3: Remote Login */
    /* 4: Remote Management */
    /* 5: Remote Apple Events */
    /* 6: Internet Sharing */
    /* 7: Bluetooth Sharing */
    

    【讨论】:

      【解决方案2】:

      我最终选择了 GUI 脚本,因为出于某种原因,它对我来说似乎更容易。我在下面发布我的脚本,但它是完整的脚本。然而,上面的内容在没有 GUI 脚本的情况下完成了我所要求的。

      startPrefs()
      
      Events = Application('System Events')
      
      Prefs = Events.processes['System Preferences']
      
      Prefs.windows[0].scrollAreas[0].buttons.byName("Sharing").click()
      
      delay(1)
      
      ShareWindow = Application("System Events").applicationProcesses.byName("System Preferences").windows.byName("Sharing")
      
      ShareWindow.groups.at(0).scrollAreas.at(0).tables.at(0).rows.at(7).select()
      
      ShareWindow.groups.at(0).popUpButtons.at(0).click().menus.at(0).menuItems.byName("Ethernet").click()
      
      delay(1)
      
      portRows = ShareWindow.groups.at(0).scrollAreas.at(1).tables.at(0).rows()
      
      for (i in portRows) {
          if (portRows[i].textFields.at(0).value() == "Wi-Fi") {
              if (portRows[i].checkboxes.at(0).value() == 0) {
                  portRows[i].select()
                  portRows[i].checkboxes.at(0).click()
              }
          }
          else {
              if (portRows[i].checkboxes.at(0).value() == 1) {
                  portRows[i].select()
                  portRows[i].checkboxes.at(0).click()
              }
          }
      }
      
      ShareWindow.groups.at(0).scrollAreas.at(0).tables.at(0).rows.at(7).select()
      
      ShareWindow.groups.at(0).scrollAreas.at(0).tables.at(0).rows.at(7).checkboxes.at(0).click()
      
      delay(1)
      
      ShareWindow.sheets.at(0).buttons.byName("Start").click()
      
      delay(30)
      
      ShareWindow.groups.at(0).scrollAreas.at(0).tables.at(0).rows.at(7).select()
      
      ShareWindow.groups.at(0).scrollAreas.at(0).tables.at(0).rows.at(7).checkboxes.at(0).click()
      
      Prefs.quit()
      
      Prefs = Application('System Preferences')
      
      Prefs.quit()
      
      function startPrefs() {
          Prefs = Application('System Preferences')
      
          Prefs.activate()
      
          delay(2)
      
          if (Prefs.windows[0].name() != "System Preferences") {
              Prefs.quit()
              startPrefs()
          }
      }
      

      【讨论】:

      • 可以肯定:我的答案也使用 GUI 脚本(所有 procpref 和 SystemEvents 项目)。一般来说,我会尽可能避免使用 GUI 脚本(更快、更可靠),这就是为什么在没有 GUI 脚本的情况下完成激活和显示的原因。
      猜你喜欢
      • 2014-12-05
      • 1970-01-01
      • 2016-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多