diff --git a/OpenRPA.FileWatcher/Views/FileWatcherView.xaml.cs b/OpenRPA.FileWatcher/Views/FileWatcherView.xaml.cs
index 6f7e6a48..06a88455 100644
--- a/OpenRPA.FileWatcher/Views/FileWatcherView.xaml.cs
+++ b/OpenRPA.FileWatcher/Views/FileWatcherView.xaml.cs
@@ -23,6 +23,7 @@ public partial class FileWatcherView : UserControl, INotifyPropertyChanged
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
+ Entity.isDirty = true;
PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
public FileWatcherView(FileWatcherDetectorPlugin plugin)
diff --git a/OpenRPA.Interfaces/Views/KeyboardDetectorView.xaml.cs b/OpenRPA.Interfaces/Views/KeyboardDetectorView.xaml.cs
index e44a882f..f8bdcfb7 100644
--- a/OpenRPA.Interfaces/Views/KeyboardDetectorView.xaml.cs
+++ b/OpenRPA.Interfaces/Views/KeyboardDetectorView.xaml.cs
@@ -24,6 +24,7 @@ public partial class KeyboardDetectorView : UserControl, INotifyPropertyChanged
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
+ Entity.isDirty = true;
PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
public KeyboardDetectorView(KeyboardDetectorPlugin plugin)
diff --git a/OpenRPA.Java/Views/JavaClickDetectorView.xaml.cs b/OpenRPA.Java/Views/JavaClickDetectorView.xaml.cs
index 9f75446a..ab9484a8 100644
--- a/OpenRPA.Java/Views/JavaClickDetectorView.xaml.cs
+++ b/OpenRPA.Java/Views/JavaClickDetectorView.xaml.cs
@@ -28,6 +28,7 @@ public partial class JavaClickDetectorView : UserControl, INotifyPropertyChanged
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
+ Entity.isDirty = true;
PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
public JavaClickDetectorView(JavaClickDetectorPlugin plugin)
diff --git a/OpenRPA.NM/NMHook.cs b/OpenRPA.NM/NMHook.cs
index fc0fc428..e30a2c46 100644
--- a/OpenRPA.NM/NMHook.cs
+++ b/OpenRPA.NM/NMHook.cs
@@ -8,6 +8,7 @@
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
+using System.Text.RegularExpressions;
namespace OpenRPA.NM
{
@@ -519,6 +520,7 @@ private static void tabcreated(NativeMessagingMessage msg)
try
{
tabs.Add(msg.tab);
+ DetectorCheck(tab);
}
finally
{
@@ -526,6 +528,53 @@ private static void tabcreated(NativeMessagingMessage msg)
}
}
}
+ private static DateTime lastURLDetector = DateTime.Now;
+ private static void DetectorCheck(NativeMessagingMessageTab tab)
+ {
+ try
+ {
+ TimeSpan ts = DateTime.Now.Subtract(lastURLDetector);
+ if (ts.TotalSeconds < 2) return;
+ if (tab == null || string.IsNullOrEmpty(tab.url)) return;
+ URLDetectorPlugin plugin = null;
+ foreach (var p in Plugins.detectorPlugins)
+ {
+ if (p is URLDetectorPlugin _plugin)
+ {
+ plugin = _plugin;
+ }
+ }
+ if (plugin == null || string.IsNullOrEmpty(plugin.URL)) return;
+ RegexOptions options = RegexOptions.None;
+ if(plugin.IgnoreCase)
+ {
+ options = RegexOptions.IgnoreCase;
+ }
+ var ma = Regex.Match(tab.url, plugin.URL, options);
+ if (!ma.Success) return;
+ lastURLDetector = DateTime.Now;
+ var e = new URLDetectorEvent(tab.url);
+ plugin.RaiseDetector(e);
+ foreach (var wi in Plugin.client.WorkflowInstances.ToList())
+ {
+ if (wi.isCompleted) continue;
+ if (wi.Bookmarks != null)
+ {
+ foreach (var b in wi.Bookmarks)
+ {
+ if (b.Key == "DownloadDetectorPlugin")
+ {
+ wi.ResumeBookmark(b.Key, e, true);
+ }
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex.ToString());
+ }
+ }
private static void tabupdated(NativeMessagingMessage msg)
{
var tab = FindTabById(msg.browser, msg.tab.id);
@@ -551,6 +600,7 @@ private static void tabupdated(NativeMessagingMessage msg)
tab.url = msg.tab.url;
tab.width = msg.tab.width;
tab.windowId = msg.tab.windowId;
+ DetectorCheck(tab);
}
private static void tabremoved(NativeMessagingMessage msg)
{
diff --git a/OpenRPA.NM/OpenRPA.NM.csproj b/OpenRPA.NM/OpenRPA.NM.csproj
index ea36fe1c..2aeadaf0 100644
--- a/OpenRPA.NM/OpenRPA.NM.csproj
+++ b/OpenRPA.NM/OpenRPA.NM.csproj
@@ -102,6 +102,7 @@
+
@@ -145,6 +146,10 @@
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
diff --git a/OpenRPA.NM/Resources/strings.Designer.cs b/OpenRPA.NM/Resources/strings.Designer.cs
index f5bec512..00b4fd3a 100644
--- a/OpenRPA.NM/Resources/strings.Designer.cs
+++ b/OpenRPA.NM/Resources/strings.Designer.cs
@@ -402,6 +402,42 @@ public static string debug_console_output_help {
}
}
+ ///
+ /// Looks up a localized string similar to Open Selector.
+ ///
+ public static string detector_button_open_selector {
+ get {
+ return ResourceManager.GetString("detector_button_open_selector", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Select.
+ ///
+ public static string detector_button_select {
+ get {
+ return ResourceManager.GetString("detector_button_select", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Name.
+ ///
+ public static string detector_name {
+ get {
+ return ResourceManager.GetString("detector_name", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to URL.
+ ///
+ public static string detector_url {
+ get {
+ return ResourceManager.GetString("detector_url", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Detect html table.
///
@@ -420,6 +456,33 @@ public static string plugin_detect_html_table_help {
}
}
+ ///
+ /// Looks up a localized string similar to Ignore lower and uppercase doing match ?.
+ ///
+ public static string plugin_ignore_case {
+ get {
+ return ResourceManager.GetString("plugin_ignore_case", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Ignore Case.
+ ///
+ public static string plugin_ignore_case_help {
+ get {
+ return ResourceManager.GetString("plugin_ignore_case_help", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Type a url or use Select button to grab by clicking a page. URL can also be a regular expression for more complex cases..
+ ///
+ public static string plugin_urldetector_general_help {
+ get {
+ return ResourceManager.GetString("plugin_urldetector_general_help", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Wait after set value.
///
diff --git a/OpenRPA.NM/Resources/strings.resx b/OpenRPA.NM/Resources/strings.resx
index 9ededfdf..c48f9c1c 100644
--- a/OpenRPA.NM/Resources/strings.resx
+++ b/OpenRPA.NM/Resources/strings.resx
@@ -231,12 +231,33 @@
Write debug informtation to browser console
+
+ Open Selector
+
+
+ Select
+
+
+ Name
+
+
+ URL
+
Detect html table
Auto add Get Table if clicked on HTML table doing recording
+
+ Ignore lower and uppercase doing match ?
+
+
+ Ignore Case
+
+
+ Type a url or use Select button to grab by clicking a page. URL can also be a regular expression for more complex cases.
+
Wait after set value
diff --git a/OpenRPA.NM/URLDetectorPlugin.cs b/OpenRPA.NM/URLDetectorPlugin.cs
new file mode 100644
index 00000000..45b2c628
--- /dev/null
+++ b/OpenRPA.NM/URLDetectorPlugin.cs
@@ -0,0 +1,129 @@
+using Newtonsoft.Json;
+using OpenRPA.Input;
+using OpenRPA.Interfaces;
+using OpenRPA.Interfaces.entity;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+
+namespace OpenRPA.NM
+{
+ public class URLDetectorPlugin : ObservableObject, IDetectorPlugin
+ {
+ public IDetector Entity { get; set; }
+ public string Name
+ {
+ get
+ {
+ if (Entity != null && !string.IsNullOrEmpty(Entity.name)) return Entity.name;
+ return "URLDetector";
+ }
+ }
+ public string URL
+ {
+ get
+ {
+ if (Entity == null) return null;
+ if (!Entity.Properties.ContainsKey("URL")) return null;
+ var _val = Entity.Properties["URL"];
+ if (_val == null) return null;
+ return _val.ToString();
+ }
+ }
+ public bool IgnoreCase
+ {
+ get
+ {
+ if (Entity == null) return false;
+ if (!Entity.Properties.ContainsKey("IgnoreCase")) return false;
+ var _val = Entity.Properties["URL"];
+ if (_val == null) return IgnoreCase;
+ return _val.ToString().ToLower() == "true";
+ }
+ set
+ {
+ Entity.Properties["IgnoreCase"] = value.ToString();
+ NotifyPropertyChanged("IgnoreCase");
+ }
+ }
+ private Views.URLDetectorView view;
+ public UserControl editor
+ {
+ get
+ {
+ if (view == null)
+ {
+ view = new Views.URLDetectorView(this);
+ view.PropertyChanged += (s, e) =>
+ {
+ NotifyPropertyChanged("Entity");
+ NotifyPropertyChanged("Name");
+ NotifyPropertyChanged("URL");
+ };
+ }
+ return view;
+ }
+ }
+ public event DetectorDelegate OnDetector;
+ public void RaiseDetector(Download download)
+ {
+ if (!Running) return;
+ var e = new DetectorEvent(download);
+ OnDetector?.Invoke(this, e, EventArgs.Empty);
+ }
+ public void RaiseDetector(URLDetectorEvent e)
+ {
+ if (!Running) return;
+ OnDetector?.Invoke(this, e, EventArgs.Empty);
+ }
+ FileSystemWatcher watcher = null;
+ private IOpenRPAClient client = null;
+ public void Initialize(IOpenRPAClient client, IDetector InEntity)
+ {
+ this.client = client;
+ Entity = InEntity;
+ watcher = new FileSystemWatcher();
+ Start();
+ }
+ public bool Running { get; set; } = false;
+ public void Start()
+ {
+ try
+ {
+ Running = true;
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex.ToString());
+ }
+ }
+ public void Stop()
+ {
+ Running = false;
+ }
+ public void Initialize(IOpenRPAClient client)
+ {
+ }
+ }
+ public class URLDetectorEvent : IDetectorEvent
+ {
+ public IElement element { get; set; }
+ public string host { get; set; }
+ public string fqdn { get; set; }
+ public string url { get; set; }
+ public string result { get; set; }
+ public URLDetectorEvent(string url)
+ {
+ host = Environment.MachineName.ToLower();
+ fqdn = System.Net.Dns.GetHostEntry(Environment.MachineName).HostName.ToLower();
+ this.url = url;
+ result = url;
+ }
+
+ }
+
+}
diff --git a/OpenRPA.NM/Views/URLDetectorView.xaml b/OpenRPA.NM/Views/URLDetectorView.xaml
new file mode 100644
index 00000000..8253b131
--- /dev/null
+++ b/OpenRPA.NM/Views/URLDetectorView.xaml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenRPA.NM/Views/URLDetectorView.xaml.cs b/OpenRPA.NM/Views/URLDetectorView.xaml.cs
new file mode 100644
index 00000000..7fb5a1b9
--- /dev/null
+++ b/OpenRPA.NM/Views/URLDetectorView.xaml.cs
@@ -0,0 +1,195 @@
+using OpenRPA.Interfaces;
+using OpenRPA.Interfaces.entity;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace OpenRPA.NM.Views
+{
+ ///
+ /// Interaction logic for URLDetectorView.xaml
+ ///
+ public partial class URLDetectorView : UserControl, INotifyPropertyChanged
+ {
+ public event PropertyChangedEventHandler PropertyChanged;
+ public void NotifyPropertyChanged(string propertyName)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ Entity.isDirty = true;
+ }
+ public URLDetectorView(URLDetectorPlugin plugin)
+ {
+ InitializeComponent();
+ this.plugin = plugin;
+ DataContext = this;
+ }
+ private void value_Changed(object sender, RoutedEventArgs e)
+ {
+ // if (wait_for_tab_after_set_value.IsChecked == null) return;
+ Entity.Save();
+ }
+ private void plugin_ignore_caseChanged(object sender, RoutedEventArgs e)
+ {
+ if(plugin_ignore_case.IsChecked != null)
+ {
+ IgnoreCase = plugin_ignore_case.IsChecked.Value;
+ }
+ }
+
+ private IDetectorPlugin plugin;
+ public IDetector Entity
+ {
+ get
+ {
+ return plugin.Entity as IDetector;
+ }
+ }
+ public string Selector
+ {
+ get
+ {
+ if (Entity == null) return null;
+ if (!Entity.Properties.ContainsKey("Selector")) return null;
+ var _val = Entity.Properties["Selector"];
+ if (_val == null) return null;
+ return _val.ToString().Replace(Environment.NewLine, "");
+ }
+ set
+ {
+ Entity.Properties["Selector"] = value;
+ NotifyPropertyChanged("Selector");
+ }
+ }
+ public string EntityName
+ {
+ get
+ {
+ if (Entity == null) return string.Empty;
+ return Entity.name;
+ }
+ set
+ {
+ Entity.name = value;
+ NotifyPropertyChanged("EntityName");
+ }
+ }
+ public string URL
+ {
+ get
+ {
+ if (Entity == null) return null;
+ if (!Entity.Properties.ContainsKey("URL")) return null;
+ var _val = Entity.Properties["URL"];
+ if (_val == null) return null;
+ return _val.ToString();
+ }
+ set
+ {
+ Entity.Properties["URL"] = value;
+ NotifyPropertyChanged("URL");
+ }
+ }
+ public bool IgnoreCase
+ {
+ get
+ {
+ if (Entity == null) return false;
+ if (!Entity.Properties.ContainsKey("IgnoreCase")) return false;
+ var _val = Entity.Properties["URL"];
+ if (_val == null) return IgnoreCase;
+ return _val.ToString().ToLower() == "true";
+ }
+ set
+ {
+ Entity.Properties["IgnoreCase"] = value.ToString();
+ NotifyPropertyChanged("IgnoreCase");
+ }
+ }
+ private void Open_Selector_Click(object sender, RoutedEventArgs e)
+ {
+ //string SelectorString = Selector;
+ //Interfaces.Selector.SelectorWindow selectors;
+ //if (!string.IsNullOrEmpty(SelectorString))
+ //{
+ // var selector = new WindowsSelector(SelectorString);
+ // selectors = new Interfaces.Selector.SelectorWindow("Windows", selector, null, 10);
+ //}
+ //else
+ //{
+ // var selector = new WindowsSelector("[{Selector: 'Windows'}]");
+ // selectors = new Interfaces.Selector.SelectorWindow("Windows", selector, null, 10);
+ //}
+ //// selectors.Owner = GenericTools.MainWindow; -- Locks up and never returns ?
+ //if (selectors.ShowDialog() == true)
+ //{
+ // Selector = selectors.vm.json;
+ // NotifyPropertyChanged("EntityName");
+ // NotifyPropertyChanged("Selector");
+ //}
+ }
+
+ private void Select_Click(object sender, RoutedEventArgs e)
+ {
+ Interfaces.GenericTools.Minimize();
+ StartRecordPlugins();
+ }
+ private void StartRecordPlugins()
+ {
+ var p = Interfaces.Plugins.recordPlugins.Where(x => x.Name == "NM").First();
+ p.OnUserAction += OnUserAction;
+ p.Start();
+ }
+ private void StopRecordPlugins()
+ {
+ var p = Interfaces.Plugins.recordPlugins.Where(x => x.Name == "NM").First();
+ p.OnUserAction -= OnUserAction;
+ p.Stop();
+ }
+ public void OnUserAction(Interfaces.IRecordPlugin sender, Interfaces.IRecordEvent e)
+ {
+ StopRecordPlugins();
+ AutomationHelper.syncContext.Post(o =>
+ {
+ Interfaces.GenericTools.Restore();
+ foreach (var p in Interfaces.Plugins.recordPlugins)
+ {
+ if (p.Name != sender.Name)
+ {
+ if (p.ParseUserAction(ref e)) continue;
+ }
+ }
+ try
+ {
+ var url = "";
+ if(e is OpenRPA.NM.RecordEvent evt)
+ {
+ if(evt.Selector.Count > 0)
+ {
+ var s1 = evt.Selector[0] as NMSelectorItem;
+ if(s1 != null)
+ {
+ url = s1.url;
+ }
+
+ }
+ }
+ if (string.IsNullOrEmpty(url)) return;
+ Selector = e.Selector.ToString();
+ NotifyPropertyChanged("Selector");
+ NotifyPropertyChanged("URL");
+ URL = url;
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex.ToString());
+ }
+ }, null);
+ }
+
+ }
+}
diff --git a/OpenRPA.SetupProject/compMain.wxs b/OpenRPA.SetupProject/compMain.wxs
index 54817719..83821934 100644
--- a/OpenRPA.SetupProject/compMain.wxs
+++ b/OpenRPA.SetupProject/compMain.wxs
@@ -74,7 +74,7 @@
-
+
diff --git a/OpenRPA.Windows/Views/WindowsClickDetectorView.xaml.cs b/OpenRPA.Windows/Views/WindowsClickDetectorView.xaml.cs
index bd400caa..e70036ec 100644
--- a/OpenRPA.Windows/Views/WindowsClickDetectorView.xaml.cs
+++ b/OpenRPA.Windows/Views/WindowsClickDetectorView.xaml.cs
@@ -26,6 +26,7 @@ public partial class WindowsClickDetectorView : UserControl, INotifyPropertyChan
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
+ Entity.isDirty= true;
PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
public WindowsClickDetectorView(IDetectorPlugin plugin)
diff --git a/OpenRPA/OpenRPA.csproj b/OpenRPA/OpenRPA.csproj
index a75f264d..3db2201c 100644
--- a/OpenRPA/OpenRPA.csproj
+++ b/OpenRPA/OpenRPA.csproj
@@ -11,7 +11,7 @@
Base UI of OpenRPA, used as part of OpenRPA robot
MPL-2.0
https://github.com/open-rpa/openrpa
- 1.4.57.4
+ 1.4.57.5
openrpa.png
Debug;Release;ReleaseNuget;PrepInstaller