Перейти к основному контенту

Custome Applet structure for RemoteApp

<h5 id="bkmrk-%D0%A7%D1%82%D0%BE-%D1%82%D0%B0%D0%BA%D0%BE%D0%B9-%D0%B0%D0%BF%D0%BF%D0%BB%D0%B5%D1%82%3F"><strong>What is an applet?</strong></h5>
<p id="bkmrk-%D0%90%D0%BF%D0%BF%D0%BB%D0%B5%D1%82-%D0%BF%D1%80%D0%B5%D0%B4%D1%81%D1%82%D0%B0%D0%B2%D0%BB%D1%8F%D0%B5%D1%82-">An applet is a set of files that describe the process of installing and launching an application on Microsoft RDS via RemoteApp. This is necessary for JumpServer to initiate an access session to this application, automatically log in, and hide the authorization parameters from the user.</p>
<h5 id="bkmrk-%D0%A1%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D0%B0-%D0%B0%D0%BF%D0%BF%D0%BB%D0%B5%D1%82%D0%B0"><strong>Applet Structure</strong></h5>
<p id="bkmrk-%D0%9A%D0%B0%D0%B6%D0%B4%D1%8B%D0%B9-%D0%B0%D0%BF%D0%BF%D0%BB%D0%B5%D1%82-%D0%BE%D0%B1%D1%8F%D0%B7%D0%B0%D1%82">Each applet must include the following files:</p>
<pre id="bkmrk-%E2%94%9C%E2%94%80%E2%94%80-i18n.yml-%E2%94%9C%E2%94%80%E2%94%80-ico"><code class="language-markdown">AppletName
  ├── i18n.yml
  ├── icon.png
  ├── main.py
  ├── manifest.yml
  └── setup.yml
</code></pre>
<p id="bkmrk-main.py%C2%A0--%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82-%D0%B7%D0%B0%D0%BF"><span style="background-color: rgb(255, 255, 255);"><span style="color: rgba(0, 0, 0, 0.87); font-family: _, -apple-system, BlinkMacSystemFont, Helvetica, Arial, sans-serif; font-size: 14.08px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-indent: 0px; text-transform: none; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; display: inline !important; float: none; background-color: rgb(255, 255, 255);">main.py</span>&nbsp;- script for launching and logging into the application</span><br></p>
<p id="bkmrk-icon.png---%D0%B7%D0%BD%D0%B0%D1%87%D0%BE%D0%BA-%D0%B0%D0%BF"><span style="background-color: rgb(255, 255, 255);">icon.png - applet icon</span></p>
<p id="bkmrk-manifest.yml---%D0%BC%D0%B5%D1%82%D0%B0%D0%B4"><span style="background-color: rgb(255, 255, 255);"><span style="color: rgb(54, 70, 78); font-family: _, SFMono-Regular, Consolas, Menlo, monospace; font-size: 11.968px; font-style: normal; font-variant-ligatures: none; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: pre; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; display: inline !important; float: none; background-color: rgb(255, 255, 255);">manifest.yml</span> - metadata, i.e., applet description</span><br></p>
<p id="bkmrk-setup.yml---%D1%84%D0%B0%D0%B9%D0%BB-%D1%81-%D0%BE"><span style="background-color: rgb(255, 255, 255);"><span style="color: rgb(54, 70, 78); font-family: _, SFMono-Regular, Consolas, Menlo, monospace; font-size: 11.968px; font-style: normal; font-variant-ligatures: none; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: pre; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; display: inline !important; float: none; background-color: rgb(255, 255, 255);">setup.yml</span> - file describing the installation process</span><br></p>
<p id="bkmrk-i18n.yml---%D1%84%D0%B0%D0%B9%D0%BB-%D0%BF%D0%B5%D1%80%D0%B5"><span style="background-color: rgb(255, 255, 255);"><span style="color: rgba(0, 0, 0, 0.87); font-family: _, -apple-system, BlinkMacSystemFont, Helvetica, Arial, sans-serif; font-size: 14.08px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-indent: 0px; text-transform: none; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; display: inline !important; float: none; background-color: rgb(255, 255, 255);">i18n.yml</span> - file for translation into various languages</span><span style="background-color: rgb(255, 255, 255);"><span style="background-color: rgb(255, 255, 255);"> </span></span></p>
<h4 id="bkmrk-%D0%A4%D0%B0%D0%B9%D0%BB-manifest.yml"><strong><span style="background-color: rgb(255, 255, 255);">File manifest.yml</span></strong></h4>
<p id="bkmrk-%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80-%D0%BD%D0%B0-%D0%B1%D0%B0%D0%B7%D0%B5-%D0%B0%D0%BF%D0%BF%D0%BB%D0%B5"><span style="background-color: rgb(255, 255, 255);">Example based on the MySQL Workbench applet</span></p>
<p id="bkmrk-%D0%92-%D1%84%D0%B0%D0%B9%D0%BB%D0%B5-manifest.yml"><span style="background-color: rgb(255, 255, 255);">The file manifest.yml contains general information about the applet and specifies its type and protocol.</span></p>
<pre id="bkmrk-%23-%28%D0%BE%D0%B1%D1%8F%D0%B7%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%29-name"><code class="language-python"># (required)
name: mysql_workbench8
display_name: "{{ 'MySQL Workbench' | trans }}"
comment: "{{ 'A tool for working with MySQL, to execute SQL and design tables' | trans }}"
# (required)
version: 0.1.1
# (required)
exec_type: python
# (required)
author: Eric
# general or web (required)
type: general
update_policy: always
edition: community
# (required)
tags:
  - database
# (required)
protocols:
  - mysqlworkbench

# translations into other languages
i18n:
  MySQL Workbench:
    en: MySQL Workbench
    zh: MySQL Workbench
    ja: MySQL Workbench

  A tool for working with MySQL, to execute SQL and design tables:
    en: A tool for working with MySQL, to execute SQL and design tables
    zh: 用于与MySQL一起工作的工具,用于执行SQL和设计表
    ja: MySQLでSQLを実行し、テーブルを設計するためのツール</code></pre>
<p id="bkmrk-%C2%A0"></p>
<h5 id="bkmrk-%D0%A4%D0%B0%D0%B9%D0%BB-setup.yml"><strong><span style="background-color: rgb(255, 255, 255);">File setup.yml</span></strong></h5>
<p id="bkmrk-%D0%A4%D0%B0%D0%B9%D0%BB-setup.yml-%D0%BE%D0%BF%D0%B8%D1%81%D1%8B"><span style="background-color: rgb(255, 255, 255);">The file setup.yml describes the parameters for installing the applet on the RDS server.</span></p>
<pre id="bkmrk-%23-%D1%82%D0%B8%D0%BF-%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B8-%D0%9F%D0%9E--"><code class="language-python"># software installation type - msi, exe, zip, manual
type: msi
# URL to download the software distribution or file name if the distribution is included with the applet archive
source: mysql-workbench-community-8.0.31-winx64.msi
# installation arguments
arguments:
  - /qn
  - /norestart
# installation directory
destination: C:\Program Files\MySQL\MySQL Workbench 8.0 CE
# path and name of the executable file
program: C:\Program Files\MySQL\MySQL Workbench 8.0 CE\MySQLWorkbench.exe
md5: d628190252133c06dad399657666974a</code></pre>
<h5 id="bkmrk-%D0%A1%D0%BA%D1%80%D0%B8%D0%BF%D1%82-main.py"><strong>Script main.py</strong></h5>
<p id="bkmrk-main.py---%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D0%BE%D0%B9-%D1%81"><strong>main.py - the main script of the applet</strong></p>
<p id="bkmrk-%D0%97%D0%B0%D0%BF%D1%83%D1%81%D0%BA-%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F-%D0%BE%D1%81"><strong>The application is launched by running the command:</strong></p>
<pre id="bkmrk-python-main.py-base6"><code class="language-">python main.py base64_json_data</code></pre>
<p id="bkmrk-%D0%A2%D0%BE-%D0%B5%D1%81%D1%82%D1%8C-%D0%B7%D0%B0%D0%BF%D1%83%D1%81%D0%BA%D0%B0%D0%B5%D1%82%D1%81%D1%8F-">That is, the main.py script is launched, and the launch parameters are passed to it. The <strong>base64_json_data</strong> structure looks approximately as follows:</p>
<pre id="bkmrk-%7B-%22app_name%22%3A-%22mysql"><code class="language-json">{
  "app_name": "mysql_workbench8",
  "protocol": "mysql",
  "user": {
    "id": "2647CA35-5CAD-4DDF-8A88-6BD88F39BB30",
    "name": "Administrator",
    "username": "admin"
  },
  "asset": {
    "asset_id": "46EE5F50-F1C1-468C-97EE-560E3436754C",
    "asset_name": "test_mysql",
    "address": "192.168.1.1",
    "protocols": [
      {
        "id": 2,
        "name": "mysql",
        "port": 3306
      }
    ]
  },
  "account": {
    "account_id": "9D5585DE-5132-458C-AABE-89A83C112A83",
    "username": "root",
    "secret": "test"
  },
  "platform": {
    "charset": "UTF-8"
  }
}</code></pre>
<h5 id="bkmrk-%C2%A0-2"><strong>Contents of main.py<br></strong></h5>
<pre id="bkmrk-import-sys-from-comm"><code class="language-python">import sys

from common import (block_input, unblock_input)  # Import functions for blocking/unblocking input
from common import convert_base64_to_dict  # Import function to convert Base64 string to a dictionary (array)
from app import AppletApplication  # Import main application

def main():
    base64_str = sys.argv[1]  # Get the Base64 string from command-line arguments
    data = convert_base64_to_dict(base64_str)  # Convert Base64 string to a dictionary
    # The data dictionary contains all the parameters for launching the application: account, server name, database name, etc., depending on the application type
    applet_app = AppletApplication(**data)  # Pass dictionary data to the application launch function
    block_input()  # Block user input
    applet_app.run()  # Launch the application
    unblock_input()  # Unblock user input
    applet_app.wait()  # Wait for the application to complete

if __name__ == '__main__':
    try:
        main()  # Launch the main function
    except Exception as e:
        print(e)  # Output the error if it occurs
</code></pre>
<p id="bkmrk-%C2%A0-1"></p>
<h5 id="bkmrk-%C2%A0-3"><strong>Contents of app.py</strong></h5>
<p id="bkmrk-app.py-%D0%BE%D0%B1%D1%8B%D1%87%D0%BD%D0%BE-%D1%81%D0%BE%D0%B4%D0%B5%D1%80%D0%B6">App.py typically contains all the main code for launching the application with the required parameters, making it the most important and complex part when developing a new applet. It is easier to base it on one of the scripts of existing applets that are similar in structure/type to the new applet being developed.</p>
<pre id="bkmrk-import-sys-%23-%D0%98%D0%BC%D0%BF%D0%BE%D1%80%D1%82%D0%B8"><code class="language-python">import sys  # Import the sys module to work with system functions

if sys.platform == 'win32':  # Check if the operating system is Windows
    from pywinauto import Application  # Import library for automating Windows GUI applications
    from pywinauto.controls.uia_controls import (ButtonWrapper, EditWrapper, MenuItemWrapper,
                                                 MenuWrapper, ComboBoxWrapper, ToolbarWrapper)
    # Import various controls for interacting with the application interface

from common import (BaseApplication, wait_pid, )  # Import the