---
title: "桌面自動化"
description: "EMILY.RPA 桌面自動化模組：以電腦視覺分析螢幕找出參考圖案座標，操作滑鼠與鍵盤自動化桌面應用軟體。"
source: https://docs.emily.tips/wap/desktop
---

# 桌面自動化 - Desktop Automation

這個模組使用電腦視覺技術分析螢幕找出參考圖案座標，操作滑鼠與鍵盤來達成桌面應用軟體的自動化。在部署內含桌面自動化技能時，電腦螢幕設定(如解析度、顏色深度、文字放大比例等)應與訓練模式時的電腦一致，建議最好是直接在部署電腦上設計流程，並避免於執行期間操作電腦造成滑鼠與鍵盤的干擾。

![](https://docs.emily.tips/img/zh/wap-901.png)

## 設定權限

由於需要分析螢幕，因此第一次打開這個模組時使用者需要同意「**螢幕錄影**」的權限；另外需要控制滑鼠與鍵盤因此使用者也要同意「**輔助使用**」相關的權限。

![](https://docs.emily.tips/img/zh/wap-902.png)

![](https://docs.emily.tips/img/zh/wap-904.png)

## 注意事項

1. Windows 作業系統需要 Windows 10 64bit 以上版本，並事前安裝微軟 [VC++ 函式庫](https://docs.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170)。
2. DA 技能運作時會占用滑鼠與鍵盤，如果自動化過程中移動滑鼠或使用鍵盤，自動化的結果有可能受到影響而產生錯誤。
3. 使用者要確保輸入法(IME)的狀態與訓練時一致。有時系統對於不同的應用程式會出現輸入法自動切換，有可能導致錯誤的文字輸入。

## 訓練面板

點擊「**TRAINER**」可以啟動在桌面右上方的訓練面板，直接在本機進行桌面流程設計。當訓練面板出現後，建議將主界面與模組視窗最小化，這樣可以將空間騰出給訓練面板使用。

![](https://docs.emily.tips/img/zh/wap-905.png)

訓練面板分為三種模式：「**桌面**」，「**No-Code 編輯器**」，以及 「**Low-Code 編輯器**」。

**桌面模式** - 是用來直接手動調整桌面或應用程式的操作狀態，我們可以自由的將桌面調整到流程開始時所需的狀態，然後點擊快門按鈕為 No-Code 模式取得螢幕快照；也可以利用 Ctrl/Cmd+0 的快捷鍵執行快照，或是 Ctrl/Cmd+5 快捷鍵執行延遲5秒的快照。

![](https://docs.emily.tips/img/zh/wap-906.png)

**No-Code 編輯器** - 利用滑鼠操作帶出選單以選擇流程的新指令，然後將指令對應的程式碼寫入 Low-Code 編輯器。

![](https://docs.emily.tips/img/zh/wap-907.png)

**Low-Code 編輯器** - 用來手動調整 No-Code 模式產生的程式碼，以達到最大化的設計彈性。

![](https://docs.emily.tips/img/zh/wap-908.png)

## No-Code 編輯器

選單指令包含：「OPEN FILE」、「INPUT TEXT」、「SEND KEYS」、「SLEEP」、「COPY XY」、「CLICK LEFT」、「CLICK RIGHT」 等。其中 「OPEN FILE」 除了可以如同滑鼠雙擊指定檔案以啟動關聯的應用程式外，也可以選擇應用程式執行檔直接啟動應用程式。

![](https://docs.emily.tips/img/zh/wap-909.png)

例如，點選 「OPEN FILE」 新增一個指令打開會計軟體 `Accounting.app`。

![](https://docs.emily.tips/img/zh/wap-910.png)

當指令在 No-Code 編輯器產生後，會如下圖提醒使用者：

![](https://docs.emily.tips/img/zh/wap-911.png)

## Low-Code 編輯器

切換到 Low-Code 編輯器可以檢查或調整程式碼，以這個例子是剛才新增指令 「OPEN FILE」 產生的。

![](https://docs.emily.tips/img/zh/wap-912.png)

在訓練面板上點擊「**▶︎**」執行鍵，EMILY.RPA 就會自動切換到桌面模式並開始執行 Low-Code 程式碼，按「**■**」 停止鍵或「**Shift+ESC**」可以中斷執行。

![](https://docs.emily.tips/img/zh/wap-913.png)

接著可以執行一次快照，取得最新螢幕畫面後切換回 No-Code 編輯器，繼續增加下一個指令，以滑鼠拖曳螢幕畫面上的按鈕區域，放開滑鼠後帶出指令選單，選取「**CLICK CROP**」增加指令，這個指令是讓 EMILY.RPA 在螢幕找到選取的參考圖案(CROP)再進行滑鼠點擊。需要找到螢幕上指定圖案的指令都會產生參考圖案在工作資料夾，檔案命名形式為 `CROP-xxx.png`。

![](https://docs.emily.tips/img/zh/wap-914.png)

當指令逐漸增加後，除了訓練面板的「**▶︎**」執行鍵可以循序執行全部步驟指令外，也可以在程式碼編輯區選取想要執行的程式碼區段，點擊編輯區上方的「**RUN SELECTED CODE**」執行選取行數的程式碼，下方的範例是執行第 6 行到第 16 行。

![](https://docs.emily.tips/img/zh/wap-915.png)

完成 Low-Code 程式碼後，一定要記得在 Low-Code 編輯器的訓練面板點擊執行鍵左邊的「**COMMIT**」鍵。第一次點擊「**COMMIT**」程式碼會從 TRIAL 區推送到 FINAL 區，第二次點擊才會把 FINAL 區的程式碼推送回模組視窗。

![](https://docs.emily.tips/img/zh/wap-916.png)

最後按下「**SAVE**」 才算完成桌面自動化並儲存。如果萬一忘了儲存，可以打開訓練模式的工作資料夾，剛才在 FINAL 區的程式碼會被儲存在 code-final-xxxx.js 的檔案中：

![](https://docs.emily.tips/img/zh/wap-917.png)

### api.screen 物件

api.screen 提供螢幕資訊與螢幕分析相關非同步函式。

```javascript
// 取得螢幕長寬
let size = await api.screen.size()
console.log(size)

// 在螢幕上指定區域內(可忽略)尋找與指定圖檔最相似位置 
let found1 = await api.screen.find('crop-1234.png', {left:0,top:0,width:600,height:600})
console.log(found1)

// 在螢幕上需找與指定圖檔有95%以上相似的所有可能位置 
let found2 = await api.screen.find('crop-1234.png', {confidence:0.95, all:true})
console.log(found2)

// 最長10秒等待螢幕上指定區域(可忽略)出現與指定圖檔最相似的位置
let found3 = await api.screen.waitFor('crop-5678', 10000, {left:0,top:0,width:600,height:600,confidence:0.95})

// 從螢幕(0,0)截取長寬都是100像素的圖片
await api.screen.capture('snapshot.png', 0, 0, 100, 100)
```

### api.mouse 物件

api.mouse 提供滑鼠操作相關非同步函式。

```javascript
// 設定滑鼠控制參數：點擊間延遲/移動速度/移動段數
const msDelay = 0  // 0 ms between clicks/scrolls
const mouseSpeed = 2000 // 2000 pixels per second of moving mouse
const mouseSteps = 30  // 30 how many steps in a mouse movement
api.mouse.config(msDelay, mouseSpeed, mouseSteps)

// 移動滑鼠游標至(x,y)
await api.mouse.move(x, y)

// 取得滑鼠游標位置 {x,y}
let pos = await api.mouse.getPosition()
console.log(pos)

// 點擊滑鼠左鍵後左鍵雙擊再點擊右鍵
await api.mouse.clickLeft()
await api.mouse.doubleClick()
await api.mouse.clickRight()
// 滑鼠點擊再釋放
await api.mouse.press()
await api.mouse.release()

// 將滑鼠游標從現在位置按住左鍵拖曳到(x,y)
const button = 0 // 0:左鍵, 1:滾輪鍵, 2:右鍵
await api.mouse.drag(x, y, button)

// 操作滑鼠滾輪往：上/下/左/右
await api.mouse.scrollUp(n)
await api.mouse.scrollDown(n)
await api.mouse.scrollLeft(n)
await api.mouse.scrollRight(n)ode
```

### api.keyboard 物件

api.keyboard 提供鍵盤輸入相關非同步函式。

```javascript
// 從鍵盤發送 hello
await api.keyboard.type('hello')

// 按住與釋放按鍵
await api.keyboard.press(api.key.A)
await api.keyboard.release(api.key.A)

// 發送鍵盤常用控制鍵 ENTER/ESC/BACK/TAB
await api.keyboard.enter()
await api.keyboard.escape()
await api.keyboard.backspace()
await api.keyboard.tab()

// 發送鍵盤組合鍵 ALT+F4
await api.keyboard.keys(api.key.LeftAlt, api.key.F4)

// 發送鍵盤：全選/複製/貼上
await api.ctrlA()
await api.ctrlC()
await api.ctrlV()
```

### api 物件

提供其他簡化流程設計與操作 shell 的非同步函式。

```javascript
// 找到與crop-2345最相似位置(信心程度95%)後點擊相對位移(x,y)並等待500ms後繼續下個指令, 找到後立即移動滑鼠游標無需軌跡 (instant： true)
await api.clickCrop('crop-2345', x, y, {confidence:0.95, wait:500, instant: true})

// 找到與crop-3456最相似位置(信心程度95%)後將滑鼠游標移到相對位移(x,y)並等待500ms後再繼續下個指令
await api.moveToCrop('crop-3456', x, y, {confidence:0.95, wait:500})

// 從found3(上方範例)相對位移(x,y)擷取長寬wxh螢幕截圖做OCR
// searchLine為搜尋文字結果的正規表達式,與下方moveCursor合併使用
// moveCursor為布林值,代表是否將滑鼠游標移至找到的searchLine在螢幕上的中心位置
// language為OCR的辨識語言: 'eng','chi_tra'
let result = await api.captureToOcr(found2, x, y, w, h, searchLine, moveCursor, language)
console.log(result.text)

// 貼上文字快捷鍵
await api.pasteText('hello')

// 讀寫剪貼簿同步函式
api.clipboard.writeText('hello')
console.log(api.clipboard.readText())

// 讀CSV檔API，分隔符號為逗點，讀取表頭須從檔頭略過0列
let rows = await api.readCSV('input.csv', ',', 0)
// 寫CSV檔API，表頭依序為name,age
await api.writeCSV('output.csv', [{name:'Alice',age:20},{name:'Bob',age:25}], ['name','age'])

// 等待5秒鐘
await api.sleep(5000)

// 執行其他技能
await api.run('bed383cd-ec5b-497e-ae4d-b9ad906e0abe')

// 開啟工作資料夾檔案
await api.shell.openPath('output.csv')
// 開啟任意檔案
await api.shell.openPath('/Users/emily/Desktop/input.xlsx')
// 開啟檔案總管並選取檔案
await api.shell.showItemInFolder('/Users/emily/Desktop/input.xlsx')
// 將檔案移至資源回收桶
await api.shell.trashItem('/Users/emily/Desktop/input.xlsx')
// 開啟網頁連結
await api.shell.openExternal('https://google.com')

// 執行 PowerShell 腳本
let result1 = await api.powerShell('Get-Process')

// 執行 PowerShell PS1 檔案腳本
let result2 = await api.powerShell('./myscript.ps1')
```

提供 Desktop Use Agent 操作桌面的非同步函式。

```javascript
// 讓 AI Agent 看螢幕操作滑鼠或鍵盤達成目標，可限制最大執行步驟數，預設 10
await api.desktopUse('點擊「新增交易」按鈕', { maxActions: 10 })
```

## api.key 物件

下表為所有按鍵列表，例如空白鍵為 api.key.Space

**`Space` `Escape` `Tab` `Backspace` `Enter`**

**`LeftAlt` `RightAlt` `LeftControl` `RightControl` `LeftShift` `RightShift` `LeftSuper` `RightSuper`**

**`F1` `F2` `F3` `F4` `F5` `F6` `F7` `F8` `F9` `F10` `F11` `F12`**

**`Num0` `Num1` `Num2` `Num3` `Num4` `Num5` `Num6` `Num7` `Num8` `Num9`**

**`A` `B` `C` `D` `E` `F` `G` `H` `I` `J` `K` `L` `M` `N` `O` `P` `Q` `R` `S` `T` `U` `V` `W` `X` `Y` `Z`**

**`Grave` `Minus` `Equal` `LeftBracket` `RightBracket` `Backslash` `Semicolon` `Quote` `Comma` `Period` `Slash`**

**`Left` `Up` `Right` `Down`**

**`Print` `Pause` `Insert` `Delete` `Home` `End` `PageUp` `PageDown`**

**`NumPad0` `NumPad1` `NumPad2` `NumPad3` `NumPad4` `NumPad5` `NumPad6` `NumPad7` `NumPad8` `NumPad9`**

**`Add` `Subtract` `Multiply` `Divide` `Decimal`**

**`CapsLock` `ScrollLock` `NumLock`**
