diff --git a/Sources/GuideSphinx/Tools/02_Defs.rst b/Sources/GuideSphinx/Tools/02_Defs.rst
new file mode 100644
index 00000000..e12fb213
--- /dev/null
+++ b/Sources/GuideSphinx/Tools/02_Defs.rst
@@ -0,0 +1,25 @@
+####################################
+2. Defs StopSafe
+####################################
+
+How to use StopSafe on the robot side
+
+.. code-block:: python
+ from pyOpenRPA.Tools import StopSafe
+ StopSafe.Init(inLogger=None)
+ StopSafe.IsSafeStop() # True - WM_CLOSE SIGNAL has come. taskkill /im someprocess.exe
+
+
+.. automodule:: pyOpenRPA.Tools.StopSafe
+ :members:
+ :autosummary:
+
+
+**********
+References
+**********
+
+`reStructuredText`_
+
+.. target-notes::
+.. _`reStructuredText`: http://docutils.sourceforge.net/rst.html
diff --git a/Sources/GuideSphinx/index.rst b/Sources/GuideSphinx/index.rst
index 9c27d257..01ad1aae 100644
--- a/Sources/GuideSphinx/index.rst
+++ b/Sources/GuideSphinx/index.rst
@@ -161,4 +161,11 @@ Guide content
:caption: AGENT
:glob:
- Agent/*
\ No newline at end of file
+ Agent/*
+
+.. toctree::
+ :maxdepth: 2
+ :caption: TOOLS
+ :glob:
+
+ Tools/*
\ No newline at end of file
diff --git a/Sources/pyOpenRPA/Orchestrator/Managers/Process.py b/Sources/pyOpenRPA/Orchestrator/Managers/Process.py
index 190858b3..cb0abba9 100644
--- a/Sources/pyOpenRPA/Orchestrator/Managers/Process.py
+++ b/Sources/pyOpenRPA/Orchestrator/Managers/Process.py
@@ -16,7 +16,6 @@ class Process():
- 4_STARTED
- 5_STARTED_MANUAL
-
.. code-block:: python
lProcess = Orchestrator.Managers.Process(inAgentHostNameStr="PCNAME",inAgentUserNameStr="USER",
inProcessNameWOExeStr="notepad",inStartCMDStr="notepad",inStopSafeTimeoutSecFloat=3)
@@ -26,6 +25,13 @@ class Process():
lProcess.StartCheck)
# OR (sync mode)
Orchestrator.OrchestratorScheduleGet().every(5).seconds.do(lProcess.StartCheck)
+
+ How to use StopSafe on the robot side
+
+ .. code-block:: python
+ from pyOpenRPA.Tools import StopSafe
+ StopSafe.Init(inLogger=None)
+ StopSafe.IsSafeStop() # True - WM_CLOSE SIGNAL has come. taskkill /im someprocess.exe
"""
mAgentHostNameStr = None
diff --git a/Sources/pyOpenRPA/Orchestrator/__Orchestrator__.py b/Sources/pyOpenRPA/Orchestrator/__Orchestrator__.py
index 5c027cc3..6e9ade98 100644
--- a/Sources/pyOpenRPA/Orchestrator/__Orchestrator__.py
+++ b/Sources/pyOpenRPA/Orchestrator/__Orchestrator__.py
@@ -148,6 +148,23 @@ def AgentOSCMD(inHostNameStr, inUserStr, inCMDStr, inRunAsyncBool=True, inSendOu
#Send item in AgentDict for the futher data transmition
return AgentActivityItemAdd(inGSettings=inGSettings, inHostNameStr=inHostNameStr, inUserStr=inUserStr, inActivityItemDict=lActivityItemDict)
+def AgentOSLogoff(inHostNameStr, inUserStr):
+ """
+ Logoff the agent user session
+
+ :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid!
+ """
+ inGSettings = GSettingsGet() # Set the global settings
+ lCMDStr = "shutdown /l"
+ lActivityItemDict = {
+ "Def":"OSCMD", # def alias (look pyOpeRPA.Agent gSettings["ProcessorDict"]["AliasDefDict"])
+ "ArgList":[], # Args list
+ "ArgDict":{"inCMDStr":lCMDStr,"inRunAsyncBool":False, "inSendOutputToOrchestratorLogsBool": True, "inCMDEncodingStr": "cp1251"}, # Args dictionary
+ "ArgGSettings": "inGSettings", # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
+ "ArgLogger": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
+ }
+ #Send item in AgentDict for the futher data transmition
+ return AgentActivityItemAdd(inGSettings=inGSettings, inHostNameStr=inHostNameStr, inUserStr=inUserStr, inActivityItemDict=lActivityItemDict)
def AgentOSFileSend(inHostNameStr, inUserStr, inOrchestratorFilePathStr, inAgentFilePathStr, inGSettings = None):
"""
@@ -373,6 +390,14 @@ def AgentProcessWOExeUpperUserListGet(inHostNameStr, inUserStr, inGSettings = No
return AgentActivityItemAdd(inGSettings=inGSettings, inHostNameStr=inHostNameStr, inUserStr=inUserStr, inActivityItemDict=lActivityItemDict)
# OS DEFS
+
+def OSLogoff():
+ """
+ Logoff the current orchestrator session
+ :return:
+ """
+ os.system("shutdown /l")
+
def OSCredentialsVerify(inUserStr, inPasswordStr, inDomainStr=""): ##
"""
Verify user credentials in windows. Return bool
diff --git a/Sources/pyOpenRPA/Tools/Terminator.py b/Sources/pyOpenRPA/Tools/StopSafe.py
similarity index 67%
rename from Sources/pyOpenRPA/Tools/Terminator.py
rename to Sources/pyOpenRPA/Tools/StopSafe.py
index 4ebe5929..8b350cf4 100644
--- a/Sources/pyOpenRPA/Tools/Terminator.py
+++ b/Sources/pyOpenRPA/Tools/StopSafe.py
@@ -1,8 +1,10 @@
+"""
# How to use
-# from pyOpenRPA.Tools import Terminator
-# Terminator.Init(inLogger=None)
-# Terminator.IsSignalClose() # True - WM_CLOSE SIGNAL has come
-# Terminator.SessionLogoff() # Logoff the session
+# from pyOpenRPA.Tools import StopSafe
+# StopSafe.Init(inLogger=None)
+# StopSafe.IsSafeStop() # True - WM_CLOSE SIGNAL has come. taskkill /im someprocess.exe
+"""
+
import win32con
import win32gui
@@ -12,33 +14,35 @@ gLogger = None
gWindowTitleStr = "PythonTerminator" # Title of the phantom window
gWindowDescriptionStr = "pyOpenRPA library for safe turn off the program (by send the WM_CLOSE signal from task kill)" # Description of the phantom window
-# Init the terminator
def Init(inLogger=None):
+ """
+ Init the StopSafe module. After that you can use def IsStopSafe() to check if close signal has come.
+
+ :param inLogger: Logger to log messages about StopSafe
+ :return:
+ """
global gLogger
global gIsSignalCloseBool
gIsSignalCloseBool = False # Init default
gLogger = inLogger
- #import sys
- #import time
- #import atexit
import threading
- #atexit.register(print, 'PYTHON SPAM APP: SHUTDOWN')
- shutdown_thread = threading.Thread(target=shutdown_monitor)
+ if gLogger: gLogger.info(f"StopSafe: Init termination catch thread")
+ shutdown_thread = threading.Thread(target=_shutdown_monitor)
shutdown_thread.start()
#shutdown_thread.join()
#shutdown_monitor()
-# Terminator.IsSignalClose() # True - WM_CLOSE SIGNAL has come
-def IsSignalClose():
+
+def IsStopSafe():
+ """
+ Check if stop signal has come.
+
+ :return:
+ """
global gIsSignalCloseBool # Init the global variable
return gIsSignalCloseBool # Return the result
-# Terminator.SessionLogoff() # Logoff the session
-def SessionLogoff():
- os.system("shutdown /l")
-
-# Technical function
-def shutdown_monitor():
+def _shutdown_monitor():
global gIsSignalCloseBool # Init the global variable
global gLogger
def wndproc(hwnd, msg, wparam, lparam):
@@ -58,5 +62,5 @@ def shutdown_monitor():
win32gui.PumpMessages()
gIsSignalCloseBool = True # WM_CLOSE message has come
if gLogger:
- gLogger.info(f"Terminator: Program has recieve the close signal - safe exit")
+ gLogger.info(f"StopSafe: Program has catch VM_CLOSE signal - do safe exit")
diff --git a/Wiki/ENG_Guide/html/01_HowToInstall.html b/Wiki/ENG_Guide/html/01_HowToInstall.html
index ba6e0828..6312cc36 100644
--- a/Wiki/ENG_Guide/html/01_HowToInstall.html
+++ b/Wiki/ENG_Guide/html/01_HowToInstall.html
@@ -121,6 +121,10 @@