├── bin ├── Roro.Release.zip └── Test Workflows │ ├── cognitive-ocr.xml │ └── cognitive-speech.xml ├── roro-notepad-hello-automation.gif ├── roro-notepad-hello-automation.mp4 ├── src ├── Roro.Activities │ ├── FodyWeavers.xml │ ├── EndNodeActivity.cs │ ├── StartNodeActivity.cs │ ├── Roro.Activities.csproj.user │ ├── LoopEndNodeActivity.cs │ ├── LoopStartNodeActivity.cs │ ├── VariableNodeActivity.cs │ ├── DecisionNodeActivity.cs │ ├── ProcessNodeActivity.cs │ ├── LabelColumn.cs │ ├── DataTypeCell.cs │ ├── GhostTextBoxColumn.cs │ ├── VariableColumn.cs │ ├── DataTypeColumn.cs │ ├── Extensions.cs │ ├── LabelCell.cs │ ├── Arguments.cs │ ├── GhostTextBoxCell.cs │ ├── ProcessNode.cs │ ├── EndNode.cs │ ├── Page_KeyEvents.cs │ ├── StartNode.cs │ ├── Helper │ │ ├── XmlSerializerHelper.cs │ │ ├── PriorityQueue.cs │ │ ├── Cell.cs │ │ ├── Rect.cs │ │ └── CellLocation.cs │ ├── LoopStartNode.cs │ ├── LoopEndNode.cs │ ├── VariableCell.cs │ ├── DecisionNode.cs │ ├── VariableNode.cs │ ├── Port.cs │ ├── app.config │ ├── RenderOptions.cs │ ├── Node.cs │ ├── ActivityContext.cs │ ├── Expression.cs │ └── packages.config ├── Roro.Activities.Cognitive │ ├── FodyWeavers.xml │ ├── Roro.Activities.Cognitive.csproj.user │ ├── packages.config │ ├── SpeechToText.cs │ ├── TextToSpeech.cs │ ├── ScreenToText.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── app.config │ └── Roro.Activities.Cognitive.csproj ├── Roro.Activities.SharePoint │ ├── packages.config │ ├── CreateList.cs │ ├── UpdateListItem.cs │ ├── CreateListItem.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── app.config │ └── Roro.Activities.SharePoint.csproj ├── Roro.Activities.Apps │ ├── Roro.Activities.Apps.csproj.user │ ├── ElementExists.cs │ ├── Core │ │ ├── PropertyAttribute.cs │ │ ├── Context.cs │ │ ├── ElementQuery.cs │ │ ├── ElementPickerLinkCell.cs │ │ ├── Condition.cs │ │ ├── ElementHighlighterForm.cs │ │ ├── Element.cs │ │ ├── WinElementType.cs │ │ ├── ChromeContext.cs │ │ ├── SapElementType.cs │ │ ├── WinContext.cs │ │ ├── EdgeContext.cs │ │ ├── SapElement.cs │ │ ├── XObject.cs │ │ ├── IEContext.cs │ │ └── SapContext.cs │ ├── ElementClick.cs │ ├── ElementValueGet.cs │ ├── ElementValueSet.cs │ ├── GlobalKeyPress.cs │ ├── GlobalMouseClick.cs │ ├── ElementPropertyGet.cs │ ├── AppStart.cs │ ├── ElementBot.cs │ ├── Input │ │ ├── InputEventHandler.cs │ │ ├── MouseButton.cs │ │ ├── InputEventType.cs │ │ ├── InputEventArgs.cs │ │ └── Input.cs │ ├── app.config │ └── Roro.Activities.Apps.csproj ├── Roro.Activities.Excel │ ├── Roro.Activities.Excel.csproj.user │ ├── WorkbookCount.cs │ ├── WorkbookSave.cs │ ├── WorkbookCreate.cs │ ├── WorkbookRefreshAll.cs │ ├── WorksheetCount.cs │ ├── WorkbookSaveAs.cs │ ├── WorksheetDelete.cs │ ├── WorkbookOpen.cs │ ├── WorksheetCreate.cs │ ├── Exceptions.cs │ ├── WorksheetExists.cs │ ├── WorkbookClose.cs │ ├── WorkbookCloseAll.cs │ ├── CellValueCut.cs │ ├── CellValueCopy.cs │ ├── CellValueWrite.cs │ ├── CellValueRead.cs │ ├── CellValueClear.cs │ ├── MacroRun.cs │ ├── CellValuePaste.cs │ ├── app.config │ ├── Roro.Activities.Excel.csproj │ └── ExcelBot.cs ├── Roro │ ├── Properties │ │ ├── Settings.settings │ │ ├── Settings.Designer.cs │ │ ├── AssemblyInfo.cs │ │ └── Resources.Designer.cs │ ├── Program.cs │ ├── App.config │ ├── Form1.cs │ └── Roro.csproj ├── Roro.Activities.Files │ ├── FileDelete.cs │ ├── FileExists.cs │ ├── FolderDelete.cs │ ├── FolderExists.cs │ ├── FileCreateText.cs │ ├── FolderCreate.cs │ ├── FileWriteText.cs │ ├── FileAppendText.cs │ ├── FileMove.cs │ ├── FileCopy.cs │ ├── FolderMove.cs │ ├── FileInfoGet.cs │ ├── FolderInfoGet.cs │ ├── app.config │ └── Roro.Activities.Files.csproj └── Roro.Activities.Outlook │ ├── Properties │ └── AssemblyInfo.cs │ ├── Roro.Activities.Outlook.csproj │ └── MailSend.cs ├── .gitignore ├── README.md └── LICENSE /bin/Roro.Release.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviedelgado/roro/HEAD/bin/Roro.Release.zip -------------------------------------------------------------------------------- /roro-notepad-hello-automation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviedelgado/roro/HEAD/roro-notepad-hello-automation.gif -------------------------------------------------------------------------------- /roro-notepad-hello-automation.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviedelgado/roro/HEAD/roro-notepad-hello-automation.mp4 -------------------------------------------------------------------------------- /src/Roro.Activities/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/Roro.Activities.Cognitive/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/Roro.Activities/EndNodeActivity.cs: -------------------------------------------------------------------------------- 1 | namespace Roro.Activities 2 | { 3 | public sealed class EndNodeActivity : Activity 4 | { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/Roro.Activities/StartNodeActivity.cs: -------------------------------------------------------------------------------- 1 | namespace Roro.Activities 2 | { 3 | public sealed class StartNodeActivity : Activity 4 | { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/Roro.Activities.SharePoint/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/Roro.Activities/Roro.Activities.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ShowAllFiles 5 | 6 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Roro.Activities.Apps.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ShowAllFiles 5 | 6 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/Roro.Activities.Excel.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ShowAllFiles 5 | 6 | -------------------------------------------------------------------------------- /src/Roro.Activities.Cognitive/Roro.Activities.Cognitive.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ShowAllFiles 5 | 6 | -------------------------------------------------------------------------------- /src/Roro/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Roro.Activities.Cognitive/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/Roro.Activities/LoopEndNodeActivity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities 4 | { 5 | public sealed class LoopEndNodeActivity : Activity 6 | { 7 | public void Execute(ActivityContext context) 8 | { 9 | throw new NotImplementedException(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Roro.Activities/LoopStartNodeActivity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities 4 | { 5 | public sealed class LoopStartNodeActivity : Activity 6 | { 7 | public void Execute(ActivityContext context) 8 | { 9 | throw new NotImplementedException(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Roro.Activities/VariableNodeActivity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities 4 | { 5 | public sealed class VariableNodeActivity : Activity 6 | { 7 | public void Execute(ActivityContext context) 8 | { 9 | throw new NotImplementedException(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio. 3 | ################################################################################ 4 | 5 | .vs 6 | 7 | src/*/obj 8 | src/*/bin 9 | src/packages 10 | 11 | bin/* 12 | !bin/*.zip 13 | !bin/Test Workflows 14 | !bin/Test Workflows/*.xml -------------------------------------------------------------------------------- /src/Roro.Activities/DecisionNodeActivity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | 6 | namespace Roro.Activities 7 | { 8 | // Do not use [DataContract], so derived class cannot. 9 | public abstract class DecisionNodeActivity : Activity 10 | { 11 | public abstract bool Execute(ActivityContext context); 12 | } 13 | } -------------------------------------------------------------------------------- /src/Roro.Activities/ProcessNodeActivity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | 6 | namespace Roro.Activities 7 | { 8 | // Do not use [DataContract], so derived class cannot. 9 | public abstract class ProcessNodeActivity : Activity 10 | { 11 | public abstract void Execute(ActivityContext context); 12 | } 13 | } -------------------------------------------------------------------------------- /src/Roro.Activities.Cognitive/SpeechToText.cs: -------------------------------------------------------------------------------- 1 | namespace Roro.Activities.Cognitive 2 | { 3 | public class SpeechToText : ProcessNodeActivity 4 | { 5 | public Output Text { get; set; } 6 | 7 | public override void Execute(ActivityContext context) 8 | { 9 | var text = AIBot.SpeechToText(); 10 | 11 | context.Set(this.Text, text); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Roro.Activities.Cognitive/TextToSpeech.cs: -------------------------------------------------------------------------------- 1 | namespace Roro.Activities.Cognitive 2 | { 3 | public class TextToSpeech : ProcessNodeActivity 4 | { 5 | public Input Text { get; set; } 6 | 7 | public override void Execute(ActivityContext context) 8 | { 9 | var text = context.Get(this.Text); 10 | 11 | AIBot.TextToSpeech(text); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/ElementExists.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace Roro.Activities.Apps 5 | { 6 | public sealed class ElementExists : DecisionNodeActivity 7 | { 8 | public Input Element { get; set; } 9 | 10 | public override bool Execute(ActivityContext context) 11 | { 12 | return context.CountElements(this.Element) == 1; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Roro.Activities.Files/FileDelete.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Roro.Activities.Files 5 | { 6 | public class FileDelete : ProcessNodeActivity 7 | { 8 | public Input FilePath { get; set; } 9 | 10 | public override void Execute(ActivityContext context) 11 | { 12 | var filePath = context.Get(this.FilePath); 13 | File.Delete(filePath); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Roro.Activities/LabelColumn.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace Roro.Activities 5 | { 6 | public sealed class LabelColumn : DataGridViewTextBoxColumn 7 | { 8 | public override bool ReadOnly => true; 9 | 10 | public LabelColumn() 11 | { 12 | this.CellTemplate = new LabelCell(); 13 | this.SortMode = DataGridViewColumnSortMode.NotSortable; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/WorkbookCount.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities.Excel 4 | { 5 | public class WorkbookCount : ProcessNodeActivity 6 | { 7 | public Output Count { get; set; } 8 | 9 | public override void Execute(ActivityContext context) 10 | { 11 | var count = ExcelBot.Shared.GetApp().Workbooks.Count; 12 | 13 | context.Set(this.Count, count); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Roro.Activities.Files/FileExists.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Roro.Activities.Files 5 | { 6 | public class FileExists : DecisionNodeActivity 7 | { 8 | public Input FilePath { get; set; } 9 | 10 | public override bool Execute(ActivityContext context) 11 | { 12 | var filePath = context.Get(this.FilePath); 13 | return File.Exists(filePath); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Roro.Activities.Files/FolderDelete.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Roro.Activities.Files 5 | { 6 | public class FolderDelete : ProcessNodeActivity 7 | { 8 | public Input FolderPath { get; set; } 9 | 10 | public override void Execute(ActivityContext context) 11 | { 12 | var folderPath = context.Get(this.FolderPath); 13 | Directory.Delete(folderPath, true); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Roro.Activities.Files/FolderExists.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Roro.Activities.Files 5 | { 6 | public class FolderExists : DecisionNodeActivity 7 | { 8 | public Input FolderPath { get; set; } 9 | 10 | public override bool Execute(ActivityContext context) 11 | { 12 | var folderPath = context.Get(this.FolderPath); 13 | return Directory.Exists(folderPath); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/WorkbookSave.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities.Excel 4 | { 5 | public class WorkbookSave : ProcessNodeActivity 6 | { 7 | public Input WorkbookName { get; set; } 8 | 9 | public override void Execute(ActivityContext context) 10 | { 11 | var wbName = context.Get(this.WorkbookName); 12 | 13 | ExcelBot.Shared.GetWorkbookByName(wbName, true).Save(); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Roro.Activities.Files/FileCreateText.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Roro.Activities.Files 5 | { 6 | public class FileCreateText : ProcessNodeActivity 7 | { 8 | public Input FilePath { get; set; } 9 | 10 | public override void Execute(ActivityContext context) 11 | { 12 | var filePath = context.Get(this.FilePath); 13 | 14 | File.CreateText(filePath).Close(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Roro.Activities.Files/FolderCreate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Roro.Activities.Files 5 | { 6 | public class FolderCreate : ProcessNodeActivity 7 | { 8 | public Input FolderPath { get; set; } 9 | 10 | public override void Execute(ActivityContext context) 11 | { 12 | var folderPath = context.Get(this.FolderPath); 13 | Directory.CreateDirectory(folderPath); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/WorkbookCreate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities.Excel 4 | { 5 | public class WorkbookCreate : ProcessNodeActivity 6 | { 7 | public Output WorkbookName { get; set; } 8 | 9 | public override void Execute(ActivityContext context) 10 | { 11 | var wbName = ExcelBot.Shared.GetApp().Workbooks.Add().Name.ToString(); 12 | 13 | context.Set(this.WorkbookName, wbName); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/WorkbookRefreshAll.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities.Excel 4 | { 5 | public class WorkbookRefreshAll : ProcessNodeActivity 6 | { 7 | public Input WorkbookName { get; set; } 8 | 9 | public override void Execute(ActivityContext context) 10 | { 11 | var wbName = context.Get(this.WorkbookName); 12 | 13 | ExcelBot.Shared.GetWorkbookByName(wbName, true).RefreshAll(); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Core/PropertyAttribute.cs: -------------------------------------------------------------------------------- 1 | 2 | using System; 3 | 4 | namespace Roro.Activities.Apps 5 | { 6 | [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] 7 | public class Property : Attribute 8 | { 9 | public bool Enabled { get; } 10 | 11 | public bool Required { get; } 12 | 13 | public Property(bool Enabled = false, bool Required = false) 14 | { 15 | this.Enabled = Enabled; 16 | this.Required = Required; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Roro.Activities.Files/FileWriteText.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Roro.Activities.Files 5 | { 6 | public class FileWriteText : ProcessNodeActivity 7 | { 8 | public Input FilePath { get; set; } 9 | 10 | public Input Text { get; set; } 11 | 12 | public override void Execute(ActivityContext context) 13 | { 14 | var filePath = context.Get(this.FilePath); 15 | var text = context.Get(this.Text); 16 | 17 | File.WriteAllText(filePath, text); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/ElementClick.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace Roro.Activities.Apps 5 | { 6 | public sealed class ElementClick : ProcessNodeActivity 7 | { 8 | public Input Element { get; set; } 9 | 10 | public override void Execute(ActivityContext context) 11 | { 12 | var e = context.GetElement(this.Element); 13 | 14 | using (var input = new InputDriver()) 15 | { 16 | e.Focus(); 17 | e.Click(); 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/ElementValueGet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace Roro.Activities.Apps 5 | { 6 | public sealed class ElementValueGet : ProcessNodeActivity 7 | { 8 | public Input Element { get; set; } 9 | 10 | public Output Value { get; set; } 11 | 12 | public override void Execute(ActivityContext context) 13 | { 14 | var e = context.GetElement(this.Element); 15 | 16 | e.Focus(); 17 | 18 | context.Set(this.Value, e.Value); 19 | 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Roro.Activities.Files/FileAppendText.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Roro.Activities.Files 5 | { 6 | public class FileAppendText : ProcessNodeActivity 7 | { 8 | public Input FilePath { get; set; } 9 | 10 | public Input Text { get; set; } 11 | 12 | public override void Execute(ActivityContext context) 13 | { 14 | var filePath = context.Get(this.FilePath); 15 | 16 | var text = context.Get(this.Text); 17 | 18 | File.AppendAllText(filePath, text); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Core/Context.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Drawing; 3 | 4 | namespace Roro.Activities.Apps 5 | { 6 | public abstract class Context 7 | { 8 | public virtual Rectangle Viewport { get; protected set; } 9 | 10 | public virtual int ProcessId { get; protected set; } 11 | 12 | public abstract Element GetElementFromFocus(); 13 | 14 | public abstract Element GetElementFromPoint(int screenX, int screenY); 15 | 16 | public abstract IEnumerable GetElementsFromQuery(ElementQuery query); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Roro.Activities.Files/FileMove.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Roro.Activities.Files 5 | { 6 | public class FileMove : ProcessNodeActivity 7 | { 8 | public Input FromFilePath { get; set; } 9 | 10 | public Input ToFilePath { get; set; } 11 | 12 | public override void Execute(ActivityContext context) 13 | { 14 | var fromFilePath = context.Get(this.FromFilePath); 15 | var toFilePath = context.Get(this.ToFilePath); 16 | 17 | File.Move(fromFilePath, toFilePath); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Roro.Activities/DataTypeCell.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Windows.Forms; 4 | 5 | namespace Roro.Activities 6 | { 7 | public sealed class DataTypeCell : DataGridViewComboBoxCell 8 | { 9 | public void OnDataError(object sender, DataGridViewDataErrorEventArgs e) 10 | { 11 | this.DataSource = new List(this.DataSource as List) 12 | { 13 | DataType.CreateInstance(this.Value.ToString()) 14 | }; 15 | e.ThrowException = false; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/WorksheetCount.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities.Excel 4 | { 5 | public class WorksheetCount : ProcessNodeActivity 6 | { 7 | public Input WorkbookName { get; set; } 8 | 9 | public Output Count { get; set; } 10 | 11 | public override void Execute(ActivityContext context) 12 | { 13 | var wbName = context.Get(this.WorkbookName); 14 | 15 | var count = ExcelBot.Shared.GetWorkbookByName(wbName, true).Worksheets.Count; 16 | 17 | context.Set(this.Count, count); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Roro.Activities.Files/FileCopy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Roro.Activities.Files 5 | { 6 | public class FileCopy : ProcessNodeActivity 7 | { 8 | public Input FromFilePath { get; set; } 9 | 10 | public Input ToFilePath { get; set; } 11 | 12 | public override void Execute(ActivityContext context) 13 | { 14 | var fromFilePath = context.Get(this.FromFilePath); 15 | 16 | var toFilePath = context.Get(this.ToFilePath); 17 | 18 | File.Copy(fromFilePath, toFilePath, true); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/WorkbookSaveAs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities.Excel 4 | { 5 | public class WorkbookSaveAs : ProcessNodeActivity 6 | { 7 | public Input WorkbookName { get; set; } 8 | 9 | public Input WorkbookNameAs { get; set; } 10 | 11 | public override void Execute(ActivityContext context) 12 | { 13 | var wbName = context.Get(this.WorkbookName); 14 | var wbNameAs = context.Get(this.WorkbookNameAs); 15 | 16 | ExcelBot.Shared.GetWorkbookByName(wbName, true).SaveAs(wbNameAs); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/WorksheetDelete.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities.Excel 4 | { 5 | public class WorksheetDelete : ProcessNodeActivity 6 | { 7 | public Input WorkbookName { get; set; } 8 | 9 | public Input WorksheetName { get; set; } 10 | 11 | public override void Execute(ActivityContext context) 12 | { 13 | var wbName = context.Get(this.WorkbookName); 14 | var wsName = context.Get(this.WorksheetName); 15 | 16 | ExcelBot.Shared.GetWorksheetByName(wbName, wsName, true).Delete(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/WorkbookOpen.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities.Excel 4 | { 5 | public class WorkbookOpen : ProcessNodeActivity 6 | { 7 | public Input WorkbookName { get; set; } 8 | 9 | public override void Execute(ActivityContext context) 10 | { 11 | var wbName = context.Get(this.WorkbookName); 12 | 13 | ExcelBot.Shared.GetApp().Workbooks.Open(wbName); 14 | 15 | if (ExcelBot.Shared.GetApp().Workbooks.Count == 0) 16 | { 17 | ExcelBot.Shared.Dispose(); 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/WorksheetCreate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities.Excel 4 | { 5 | public class WorksheetCreate : ProcessNodeActivity 6 | { 7 | public Input WorkbookName { get; set; } 8 | 9 | public Input WorksheetName { get; set; } 10 | 11 | public override void Execute(ActivityContext context) 12 | { 13 | var wbName = context.Get(this.WorkbookName); 14 | var wsName = context.Get(this.WorksheetName); 15 | 16 | ExcelBot.Shared.GetWorkbookByName(wbName, true).Worksheets.Add(wsName); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Roro.Activities.Files/FolderMove.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Roro.Activities.Files 5 | { 6 | public class FolderMove : ProcessNodeActivity 7 | { 8 | public Input FromFolderPath { get; set; } 9 | 10 | public Input ToFolderPath { get; set; } 11 | 12 | public override void Execute(ActivityContext context) 13 | { 14 | var fromFolderPath = context.Get(this.FromFolderPath); 15 | var toFolderPath = context.Get(this.ToFolderPath); 16 | 17 | Directory.Move(fromFolderPath, toFolderPath); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/Exceptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Roro.Activities.Excel 8 | { 9 | public abstract class ExcelException : Exception 10 | { 11 | 12 | } 13 | 14 | public sealed class ExcelNotFoundException : ExcelException 15 | { 16 | 17 | } 18 | 19 | public sealed class ExcelWorkbookNotFoundException : ExcelException 20 | { 21 | 22 | } 23 | 24 | public sealed class ExcelWorksheetNotFoundException : ExcelException 25 | { 26 | 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/WorksheetExists.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities.Excel 4 | { 5 | public class WorksheetExists : DecisionNodeActivity 6 | { 7 | public Input WorkbookName { get; set; } 8 | 9 | public Input WorksheetName { get; set; } 10 | 11 | public override bool Execute(ActivityContext context) 12 | { 13 | var wbName = context.Get(this.WorkbookName); 14 | var wsName = context.Get(this.WorksheetName); 15 | 16 | return ExcelBot.Shared.GetWorksheetByName(wbName, wsName, false) != null; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/ElementValueSet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace Roro.Activities.Apps 5 | { 6 | public sealed class ElementValueSet : ProcessNodeActivity 7 | { 8 | public Input Element { get; set; } 9 | 10 | public Input Value { get; set; } 11 | 12 | public override void Execute(ActivityContext context) 13 | { 14 | var value = context.Get(this.Value, string.Empty); 15 | 16 | var e = context.GetElement(this.Element); 17 | 18 | e.Focus(); 19 | 20 | e.Value = value; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/WorkbookClose.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities.Excel 4 | { 5 | public class WorkbookClose : ProcessNodeActivity 6 | { 7 | public Input WorkbookName { get; set; } 8 | 9 | public override void Execute(ActivityContext context) 10 | { 11 | var wbName = context.Get(this.WorkbookName); 12 | 13 | ExcelBot.Shared.GetWorkbookByName(wbName, true).Close(); 14 | 15 | if (ExcelBot.Shared.GetApp().Workbooks.Count == 0) 16 | { 17 | ExcelBot.Shared.Dispose(); 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/WorkbookCloseAll.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities.Excel 4 | { 5 | public class WorkbookCloseAll : ProcessNodeActivity 6 | { 7 | public override void Execute(ActivityContext context) 8 | { 9 | var count = ExcelBot.Shared.GetApp().Workbooks.Count; 10 | for (var i = 0; i < count; i++) 11 | { 12 | ExcelBot.Shared.GetApp().Workbooks.Item(i).Close(); 13 | } 14 | 15 | if (ExcelBot.Shared.GetApp().Workbooks.Count == 0) 16 | { 17 | ExcelBot.Shared.Dispose(); 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/GlobalKeyPress.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Windows.Forms; 4 | 5 | namespace Roro.Activities.Apps 6 | { 7 | public sealed class GlobalKeyPress : ProcessNodeActivity 8 | { 9 | public Input Element { get; set; } 10 | 11 | public Input Text { get; set; } 12 | 13 | public override void Execute(ActivityContext context) 14 | { 15 | var e = context.GetElement(this.Element); 16 | 17 | var text = context.Get(this.Text, string.Empty); 18 | 19 | e.Focus(); 20 | 21 | SendKeys.SendWait(text); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/GlobalMouseClick.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace Roro.Activities.Apps 5 | { 6 | public sealed class GlobalMouseClick : ProcessNodeActivity 7 | { 8 | public Input Element { get; set; } 9 | 10 | public override void Execute(ActivityContext context) 11 | { 12 | var e = context.GetElement(this.Element); 13 | 14 | using (var input = new InputDriver()) 15 | { 16 | e.Focus(); 17 | var p = e.Bounds.Center; 18 | input.MouseMove(p.X, p.Y); 19 | input.Click(MouseButton.Left); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/CellValueCut.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities.Excel 4 | { 5 | public class CellValueCut : ProcessNodeActivity 6 | { 7 | public Input WorkbookName { get; set; } 8 | 9 | public Input WorksheetName { get; set; } 10 | 11 | public Input Cell { get; set; } 12 | 13 | public override void Execute(ActivityContext context) 14 | { 15 | var wbName = context.Get(this.WorkbookName); 16 | var wsName = context.Get(this.WorksheetName); 17 | var range = context.Get(this.Cell); 18 | 19 | ExcelBot.Shared.GetRange(wbName, wsName, range).Cut(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/CellValueCopy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities.Excel 4 | { 5 | public class CellValueCopy : ProcessNodeActivity 6 | { 7 | public Input WorkbookName { get; set; } 8 | 9 | public Input WorksheetName { get; set; } 10 | 11 | public Input Cell { get; set; } 12 | 13 | public override void Execute(ActivityContext context) 14 | { 15 | var wbName = context.Get(this.WorkbookName); 16 | var wsName = context.Get(this.WorksheetName); 17 | var range = context.Get(this.Cell); 18 | 19 | ExcelBot.Shared.GetRange(wbName, wsName, range).Copy(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Roro.Activities/GhostTextBoxColumn.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace Roro.Activities 5 | { 6 | public sealed class GhostTextBoxColumn : DataGridViewTextBoxColumn 7 | { 8 | public override bool ReadOnly 9 | { 10 | get => base.ReadOnly; 11 | set 12 | { 13 | if (!value) this.HeaderCell.Style.ForeColor = System.Drawing.Color.Blue; 14 | base.ReadOnly = value; 15 | } 16 | } 17 | 18 | public GhostTextBoxColumn() 19 | { 20 | this.CellTemplate = new GhostTextBoxCell(); 21 | this.SortMode = DataGridViewColumnSortMode.NotSortable; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/Roro.Activities/VariableColumn.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace Roro.Activities 5 | { 6 | public sealed class VariableColumn : DataGridViewComboBoxColumn 7 | { 8 | public override bool ReadOnly 9 | { 10 | get => base.ReadOnly; 11 | set 12 | { 13 | if (!value) this.HeaderCell.Style.ForeColor = System.Drawing.Color.Blue; 14 | base.ReadOnly = value; 15 | } 16 | } 17 | 18 | public VariableColumn() 19 | { 20 | this.CellTemplate = new VariableCell(); 21 | this.SortMode = DataGridViewColumnSortMode.NotSortable; 22 | this.DisplayStyleForCurrentCellOnly = true; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/Roro/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.Windows.Forms; 4 | 5 | namespace Roro 6 | { 7 | static class Program 8 | { 9 | [DllImport("user32.dll")] 10 | private static extern bool SetProcessDPIAware(); 11 | 12 | /// 13 | /// The main entry point for the application. 14 | /// 15 | [STAThread] 16 | static void Main() 17 | { 18 | SetProcessDPIAware(); 19 | Environment.CurrentDirectory = AppDomain.CurrentDomain.BaseDirectory; 20 | Application.EnableVisualStyles(); 21 | Application.SetCompatibleTextRenderingDefault(false); 22 | Application.Run(new Form1()); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Roro.Activities.Cognitive/ScreenToText.cs: -------------------------------------------------------------------------------- 1 | namespace Roro.Activities.Cognitive 2 | { 3 | public class ScreenToText : ProcessNodeActivity 4 | { 5 | public Input X { get; set; } 6 | 7 | public Input Y { get; set; } 8 | 9 | public Input Width { get; set; } 10 | 11 | public Input Height { get; set; } 12 | 13 | public Output Text { get; set; } 14 | 15 | public override void Execute(ActivityContext context) 16 | { 17 | var x = context.Get(this.X, 0); 18 | var y = context.Get(this.Y, 0); 19 | var w = context.Get(this.Width, 0); 20 | var h = context.Get(this.Height, 0); 21 | context.Set(this.Text, AIBot.ScreenToText(x, y, w, h)); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/CellValueWrite.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities.Excel 4 | { 5 | public class CellValueWrite : ProcessNodeActivity 6 | { 7 | public Input WorkbookName { get; set; } 8 | 9 | public Input WorksheetName { get; set; } 10 | 11 | public Input Cell { get; set; } 12 | 13 | public Input Value { get; set; } 14 | 15 | public override void Execute(ActivityContext context) 16 | { 17 | var wbName = context.Get(this.WorkbookName); 18 | var wsName = context.Get(this.WorksheetName); 19 | var range = context.Get(this.Cell); 20 | var value = context.Get(this.Value); 21 | 22 | ExcelBot.Shared.GetRange(wbName, wsName, range).Value = value; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/CellValueRead.cs: -------------------------------------------------------------------------------- 1 | namespace Roro.Activities.Excel 2 | { 3 | public class CellValueRead : ProcessNodeActivity 4 | { 5 | public Input WorkbookName { get; set; } 6 | 7 | public Input WorksheetName { get; set; } 8 | 9 | public Input Cell { get; set; } 10 | 11 | public Output Value { get; set; } 12 | 13 | public override void Execute(ActivityContext context) 14 | { 15 | var wbName = context.Get(this.WorkbookName); 16 | var wsName = context.Get(this.WorksheetName); 17 | var range = context.Get(this.Cell); 18 | 19 | var value = ExcelBot.Shared.GetRange(wbName, wsName, range).Value?.ToString() ?? string.Empty; 20 | 21 | context.Set(this.Value, value); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## *This is now an archived repository. To everyone, salamat sa pagsuporta.* 2 | 3 | [Roro](https://web.archive.org/web/20200223204002/http://www.roroscript.com/) is a free open-source [Robotic Process Automation](https://en.wikipedia.org/wiki/Robotic_process_automation) software. 4 | 5 | The software is released under BSD 2-Clause open-source [license](LICENSE). 6 | 7 | The C# source files are available [here](src) and the compiled binaries [here](bin). 8 | 9 | Watch our "Hello Automation!" example and see how it works! 10 | 11 | [![](roro-notepad-hello-automation.gif)](https://web.archive.org/web/20200223204002/http://www.roroscript.com/) 12 | 13 | ## Credits 14 | - [x] https://github.com/dotnet/roslyn 15 | - [x] https://github.com/Fody/Costura 16 | 17 | ## Need help? 18 | > Message me on [LinkedIn](https://linkedin.com/in/arviedelgado) 19 | -------------------------------------------------------------------------------- /src/Roro.Activities/DataTypeColumn.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace Roro.Activities 5 | { 6 | public sealed class DataTypeColumn : DataGridViewComboBoxColumn 7 | { 8 | public override bool ReadOnly 9 | { 10 | get => base.ReadOnly; 11 | set 12 | { 13 | if (!value) this.HeaderCell.Style.ForeColor = System.Drawing.Color.Blue; 14 | base.ReadOnly = value; 15 | } 16 | } 17 | 18 | public DataTypeColumn() 19 | { 20 | this.CellTemplate = new DataTypeCell(); 21 | this.SortMode = DataGridViewColumnSortMode.NotSortable; 22 | this.ValueMember = "Id"; 23 | this.DisplayMember = "Name"; 24 | this.DisplayStyleForCurrentCellOnly = true; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Roro.Activities/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Runtime.InteropServices; 4 | using System.Text.RegularExpressions; 5 | using System.Windows.Forms; 6 | 7 | namespace Roro.Activities 8 | { 9 | public static class Extensions 10 | { 11 | public static string Humanize(this string str) 12 | { 13 | return Regex.Replace(str.Split('.').Last(), "([a-z](?=[A-Z0-9])|[A-Z](?=[A-Z][a-z]))", "$1 "); 14 | } 15 | 16 | [DllImport("uxtheme.dll", CharSet = CharSet.Unicode)] 17 | private static extern int SetWindowTheme(IntPtr hwnd, string pszSubAppName, string pszSubIdList); 18 | 19 | public static void SetWindowTheme(this Control control, string pszSubAppName) 20 | { 21 | SetWindowTheme(control.Handle, pszSubAppName, null); 22 | } 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Roro.Activities/LabelCell.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Windows.Forms; 4 | 5 | namespace Roro.Activities 6 | { 7 | public sealed class LabelCell : DataGridViewTextBoxCell 8 | { 9 | public override bool ReadOnly => true; 10 | 11 | protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) 12 | { 13 | formattedValue = formattedValue.ToString().Humanize(); 14 | base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/Roro.Activities/Arguments.cs: -------------------------------------------------------------------------------- 1 | namespace Roro.Activities 2 | { 3 | public class Argument 4 | { 5 | public string Name { get; set; } 6 | 7 | internal string Type { get; set; } 8 | 9 | public string Value { get; set; } 10 | 11 | public Argument() 12 | { 13 | this.Name = string.Empty; 14 | this.Type = DataType.GetDefault().GetType().FullName; 15 | this.Value = string.Empty; 16 | } 17 | } 18 | 19 | public class Input : Argument 20 | { 21 | 22 | } 23 | 24 | public class Input : Input where T : DataType, new() 25 | { 26 | public Input() 27 | { 28 | this.Type = typeof(T).FullName; 29 | } 30 | } 31 | 32 | public class Output : Argument 33 | { 34 | 35 | } 36 | 37 | public class Output : Output where T : DataType, new() 38 | { 39 | public Output() 40 | { 41 | this.Type = typeof(T).FullName; 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/ElementPropertyGet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Reflection; 4 | 5 | namespace Roro.Activities.Apps 6 | { 7 | public sealed class ElementPropertyGet : ProcessNodeActivity 8 | { 9 | public Input Element { get; set; } 10 | 11 | public Input PropertyName { get; set; } 12 | 13 | public Output PropertyValue { get; set; } 14 | 15 | public override void Execute(ActivityContext context) 16 | { 17 | var e = context.GetElement(this.Element); 18 | 19 | var name = context.Get(this.PropertyName); 20 | 21 | if (e.GetType().GetProperty(name, BindingFlags.Public | BindingFlags.Instance) is PropertyInfo pi) 22 | { 23 | context.Set(this.PropertyValue, pi.GetValue(e)?.ToString() ?? string.Empty); 24 | } 25 | else 26 | { 27 | throw new Exception(string.Format("Element property '{0}' not found.", name)); 28 | } 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/AppStart.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Linq; 4 | 5 | namespace Roro.Activities.Apps 6 | { 7 | public sealed class AppStart : ProcessNodeActivity 8 | { 9 | public Input AppPath { get; set; } 10 | 11 | public Input Arguments { get; set; } 12 | 13 | public override void Execute(ActivityContext context) 14 | { 15 | var appPath = context.Get(this.AppPath); 16 | var appArgs = context.Get(this.Arguments, string.Empty); 17 | 18 | var p = Process.Start(appPath, appArgs); 19 | while (p.MainWindowHandle == IntPtr.Zero) 20 | { 21 | context.ThrowIfCancellationRequested(); 22 | try 23 | { 24 | p.WaitForInputIdle(1000); 25 | } 26 | catch (InvalidOperationException) 27 | { 28 | break; 29 | } 30 | p.Refresh(); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Roro.Activities.SharePoint/CreateList.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.SharePoint.Client; 2 | using System; 3 | 4 | namespace Roro.Activities.SharePoint 5 | { 6 | public class CreateList : ProcessNodeActivity 7 | { 8 | 9 | public Input SiteUrl { get; set; } 10 | 11 | public Input ListTitle { get; set; } 12 | 13 | public override void Execute(ActivityContext context) 14 | { 15 | 16 | ClientContext spContext = new ClientContext(context.Get(this.SiteUrl)); 17 | Web spWeb = spContext.Web; 18 | 19 | ListCreationInformation lci = new ListCreationInformation(); 20 | lci.Title = context.Get(this.ListTitle); 21 | lci.TemplateType = (int)ListTemplateType.DocumentLibrary; 22 | 23 | List newList = spWeb.Lists.Add(lci); 24 | 25 | try 26 | { 27 | spContext.ExecuteQuery(); 28 | } 29 | catch 30 | { 31 | throw new NotImplementedException(); 32 | } 33 | 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/CellValueClear.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities.Excel 4 | { 5 | public class CellValueClear : ProcessNodeActivity 6 | { 7 | public Input WorkbookName { get; set; } 8 | 9 | public Input WorksheetName { get; set; } 10 | 11 | public Input Cell { get; set; } 12 | 13 | public Input ClearContentsOnly { get; set; } 14 | 15 | public override void Execute(ActivityContext context) 16 | { 17 | var wbName = context.Get(this.WorkbookName); 18 | var wsName = context.Get(this.WorksheetName); 19 | var range = context.Get(this.Cell); 20 | var clearContentsOnly = context.Get(this.ClearContentsOnly, false); 21 | 22 | if (clearContentsOnly) 23 | { 24 | ExcelBot.Shared.GetRange(wbName, wsName, range).ClearContents(); 25 | } 26 | else 27 | { 28 | ExcelBot.Shared.GetRange(wbName, wsName, range).Clear(); 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Roro.Activities.SharePoint/UpdateListItem.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.SharePoint.Client; 2 | 3 | namespace Roro.Activities.SharePoint 4 | { 5 | class UpdateListItem : ProcessNodeActivity 6 | { 7 | public Input SiteUrl { get; set; } 8 | 9 | public Input ListTitle { get; set; } 10 | 11 | public Input ItemId { get; set; } 12 | 13 | public Input ColumnName { get; set; } 14 | 15 | public Input ColumnValue { get; set; } 16 | 17 | public override void Execute(ActivityContext context) 18 | { 19 | ClientContext clientContext = new ClientContext(context.Get(this.SiteUrl)); 20 | 21 | List list = clientContext.Web.Lists.GetByTitle(context.Get(this.ListTitle)); 22 | 23 | ListItem item = list.GetItemById(context.Get(this.ItemId)); 24 | clientContext.Load(item); 25 | clientContext.ExecuteQuery(); 26 | 27 | item[context.Get(this.ColumnName)] = context.Get(this.ColumnValue); 28 | item.Update(); 29 | 30 | clientContext.ExecuteQuery(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Roro.Activities/GhostTextBoxCell.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Windows.Forms; 4 | 5 | namespace Roro.Activities 6 | { 7 | public sealed class GhostTextBoxCell : DataGridViewTextBoxCell 8 | { 9 | protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) 10 | { 11 | if (formattedValue.ToString().Length == 0 && !elementState.HasFlag(DataGridViewElementStates.Selected)) 12 | { 13 | formattedValue = "Enter " + this.OwningColumn.HeaderText.ToLower(); 14 | cellStyle.Font = new Font(cellStyle.Font, FontStyle.Italic); 15 | cellStyle.ForeColor = Color.FromArgb(150, 150, 150); 16 | } 17 | base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/Roro.Activities.SharePoint/CreateListItem.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.SharePoint.Client; 2 | 3 | namespace Roro.Activities.SharePoint 4 | { 5 | class CreateListItem : ProcessNodeActivity 6 | { 7 | public Input SiteUrl { get; set; } 8 | 9 | public Input ListTitle { get; set; } 10 | 11 | public Input ItemTitle { get; set; } 12 | 13 | public Input FilePath { get; set; } 14 | 15 | public Input Overwrite { get; set; } 16 | 17 | public override void Execute(ActivityContext context) 18 | { 19 | //TODO: Handle fields other than the Title field. 20 | ClientContext clientContext = new ClientContext(context.Get(this.SiteUrl)); 21 | 22 | List list = clientContext.Web.Lists.GetByTitle(context.Get(this.ListTitle)); 23 | 24 | bool overwrite = context.Get(this.Overwrite, true); 25 | 26 | FileCreationInformation fci = new FileCreationInformation(); 27 | fci.Content = System.IO.File.ReadAllBytes(context.Get(FilePath)); 28 | fci.Overwrite = overwrite; 29 | 30 | clientContext.ExecuteQuery(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Roro/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Roro.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.5.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Roro.Activities/ProcessNode.cs: -------------------------------------------------------------------------------- 1 | 2 | using System; 3 | using System.Drawing; 4 | using System.Drawing.Drawing2D; 5 | using System.Linq; 6 | 7 | namespace Roro.Activities 8 | { 9 | public sealed class ProcessNode : Node 10 | { 11 | //public Guid Next { get; set; } 12 | 13 | private ProcessNode() 14 | { 15 | // required for XmlSerializer. 16 | } 17 | 18 | internal ProcessNode(Activity activity) : base(activity) 19 | { 20 | this.Ports.Add(new NextPort()); 21 | } 22 | 23 | public override Guid Execute(ActivityContext context) 24 | { 25 | (this.Activity as ProcessNodeActivity).Execute(context); 26 | return this.Ports.First().NextNodeId; 27 | } 28 | 29 | public override GraphicsPath Render(Graphics g, Rect r, NodeStyle o) 30 | { 31 | var path = new GraphicsPath(); 32 | path.StartFigure(); 33 | path.AddRectangle(r); 34 | path.CloseFigure(); 35 | // 36 | g.FillPath(o.BackBrush, path); 37 | g.DrawPath(o.BorderPen, path); 38 | return path; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Roro.Activities.Files/FileInfoGet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Roro.Activities.Files 5 | { 6 | public class FileInfoGet : ProcessNodeActivity 7 | { 8 | public Input FilePath { get; set; } 9 | 10 | public Output FileName { get; set; } 11 | 12 | public Output FileExtension { get; set; } 13 | 14 | public Output FileSize { get; set; } 15 | 16 | public Output CreationTime { get; set; } 17 | 18 | public Output LastAccessTime { get; set; } 19 | 20 | public Output LastWriteTime { get; set; } 21 | 22 | public override void Execute(ActivityContext context) 23 | { 24 | var filePath = context.Get(this.FilePath); 25 | 26 | var fileInfo = new FileInfo(filePath); 27 | 28 | context.Set(this.FileName, fileInfo.Name); 29 | context.Set(this.FileExtension, fileInfo.Extension); 30 | context.Set(this.FileSize, fileInfo.Length); 31 | context.Set(this.CreationTime, fileInfo.CreationTime); 32 | context.Set(this.LastAccessTime, fileInfo.LastAccessTime); 33 | context.Set(this.LastWriteTime, fileInfo.LastWriteTime); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Roro.Activities/EndNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Drawing.Drawing2D; 4 | 5 | namespace Roro.Activities 6 | { 7 | public sealed class EndNode : Node 8 | { 9 | private EndNode() 10 | { 11 | // required for XmlSerializer. 12 | } 13 | 14 | internal EndNode(Activity activity) : base(activity) 15 | { 16 | this.Ports.Clear(); 17 | } 18 | 19 | public override Guid Execute(ActivityContext context) 20 | { 21 | return Guid.Empty; 22 | } 23 | 24 | public override bool CanStartLink => false; 25 | 26 | public override GraphicsPath Render(Graphics g, Rect r, NodeStyle o) 27 | { 28 | var leftRect = new Rectangle(r.X, r.Y, r.Height, r.Height); 29 | var rightRect = new Rectangle(r.Right - r.Height, r.Y, r.Height, r.Height); 30 | var path = new GraphicsPath(); 31 | path.StartFigure(); 32 | path.AddArc(leftRect, 90, 180); 33 | path.AddArc(rightRect, -90, 180); 34 | path.CloseFigure(); 35 | // 36 | g.FillPath(o.BackBrush, path); 37 | g.DrawPath(o.BorderPen, path); 38 | return path; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Roro.Activities/Page_KeyEvents.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | 3 | namespace Roro.Activities 4 | { 5 | public partial class Page 6 | { 7 | private void Canvas_KeyDown(object sender, KeyEventArgs e) 8 | { 9 | if (e.KeyCode == Keys.Delete) 10 | { 11 | this.DeleteNode(); 12 | } 13 | else if (e.Modifiers == Keys.Control && e.KeyCode == Keys.A) 14 | { 15 | this.SelectAllNodes(); 16 | } 17 | } 18 | 19 | private void DeleteNode() 20 | { 21 | foreach (var selectedNode in this.SelectedNodes) 22 | { 23 | if (selectedNode == this.currentNode) 24 | { 25 | this.currentNode = null; 26 | } 27 | this.RemoveNode(selectedNode); 28 | } 29 | this.SelectedNodes.Clear(); 30 | this.Canvas.Invalidate(); 31 | } 32 | 33 | private void SelectAllNodes() 34 | { 35 | this.SelectedNodes.Clear(); 36 | foreach (var node in this.Nodes) 37 | { 38 | this.SelectedNodes.Add(node); 39 | } 40 | this.Canvas.Invalidate(); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /src/Roro.Activities.Files/FolderInfoGet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Roro.Activities.Files 5 | { 6 | public class FolderInfoGet : ProcessNodeActivity 7 | { 8 | public Input FolderPath { get; set; } 9 | 10 | public Output FolderName { get; set; } 11 | 12 | public Output FolderCount { get; set; } 13 | 14 | public Output FileCount { get; set; } 15 | 16 | public Output CreationTime { get; set; } 17 | 18 | public Output LastAccessTime { get; set; } 19 | 20 | public Output LastWriteTime { get; set; } 21 | 22 | public override void Execute(ActivityContext context) 23 | { 24 | var folderPath = context.Get(this.FolderPath); 25 | 26 | var folderInfo = new DirectoryInfo(folderPath); 27 | 28 | context.Set(this.FolderName, folderInfo.Name); 29 | context.Set(this.FolderCount, folderInfo.GetDirectories().Length); 30 | context.Set(this.FileCount, folderInfo.GetFiles().Length); 31 | context.Set(this.CreationTime, folderInfo.CreationTime); 32 | context.Set(this.LastAccessTime, folderInfo.LastAccessTime); 33 | context.Set(this.LastWriteTime, folderInfo.LastWriteTime); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/ElementBot.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Roro.Activities.Apps 6 | { 7 | public static class ElementBot 8 | { 9 | public static Element GetElement(this ActivityContext context, Input input) 10 | { 11 | var query = new ElementQuery(XmlSerializerHelper.ToObject>(input.Value)); 12 | if (query == null) 13 | throw new Exception("Input 'Element' is required."); 14 | 15 | var elements = WinContext.Shared.GetElementsFromQuery(query); 16 | 17 | if (elements.Count() == 0) 18 | throw new Exception("No element found."); 19 | if (elements.Count() > 1) 20 | throw new Exception("Too many elements found."); 21 | 22 | return elements.First(); 23 | } 24 | 25 | public static int CountElements(this ActivityContext context, Input input) 26 | { 27 | var query = new ElementQuery(XmlSerializerHelper.ToObject>(input.Value)); 28 | if (query == null) 29 | throw new Exception("Input 'Element' is required."); 30 | 31 | var elements = WinContext.Shared.GetElementsFromQuery(query); 32 | 33 | return elements.Count(); 34 | } 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2018, Arvie Delgado 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /src/Roro.Activities/StartNode.cs: -------------------------------------------------------------------------------- 1 | 2 | using System; 3 | using System.Drawing; 4 | using System.Drawing.Drawing2D; 5 | using System.Linq; 6 | 7 | namespace Roro.Activities 8 | { 9 | public sealed class StartNode : Node 10 | { 11 | //public Guid Next { get; set; } 12 | 13 | private StartNode() 14 | { 15 | // required for XmlSerializer. 16 | } 17 | 18 | public StartNode(Activity activity) : base(activity) 19 | { 20 | this.Ports.Add(new NextPort()); 21 | } 22 | 23 | public override Guid Execute(ActivityContext context) 24 | { 25 | return this.Ports.First().NextNodeId; 26 | } 27 | 28 | public override bool CanEndLink => false; 29 | 30 | public override GraphicsPath Render(Graphics g, Rect r, NodeStyle o) 31 | { 32 | var leftRect = new Rectangle(r.X, r.Y, r.Height, r.Height); 33 | var rightRect = new Rectangle(r.Right - r.Height, r.Y, r.Height, r.Height); 34 | var path = new GraphicsPath(); 35 | path.StartFigure(); 36 | path.AddArc(leftRect, 90, 180); 37 | path.AddArc(rightRect, -90, 180); 38 | path.CloseFigure(); 39 | // 40 | g.FillPath(o.BackBrush, path); 41 | g.DrawPath(o.BorderPen, path); 42 | return path; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Roro.Activities/Helper/XmlSerializerHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using System.Xml.Serialization; 5 | namespace Roro.Activities 6 | { 7 | public class XmlSerializerHelper 8 | { 9 | private static XmlSerializer GetSerializer() 10 | { 11 | Activity.GetAllActivities(); 12 | return new XmlSerializer(typeof(T), 13 | AppDomain.CurrentDomain.GetAssemblies() 14 | .Where(x => x.FullName.StartsWith(typeof(XmlSerializerHelper).Namespace)) 15 | .SelectMany(x => x.GetTypes()) 16 | .Where(t => 17 | typeof(Node).IsAssignableFrom(t) || 18 | typeof(Port).IsAssignableFrom(t) || 19 | typeof(Activity).IsAssignableFrom(t)).ToArray()); 20 | } 21 | 22 | public static string ToString(T obj) 23 | { 24 | using (var writer = new StringWriter()) 25 | { 26 | GetSerializer().Serialize(writer, obj); 27 | return writer.ToString(); 28 | } 29 | } 30 | 31 | public static T ToObject(string str) 32 | { 33 | using (var reader = new StringReader(str)) 34 | { 35 | return (T)GetSerializer().Deserialize(reader); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Core/ElementQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Windows.Forms; 5 | 6 | namespace Roro.Activities.Apps 7 | { 8 | public sealed class ElementQuery : DataType>, IEnumerable 9 | { 10 | public override DataGridViewCell CellTemplate => new ElementPickerLinkCell(); 11 | 12 | public ElementQuery() : this(new List()) { } 13 | 14 | public ElementQuery(string xml): this(XmlSerializerHelper.ToObject>(xml)) { } 15 | 16 | public ElementQuery(IEnumerable conditions) : base(new List(conditions)) { } 17 | 18 | public void Add(Condition condition) => this.Value.Add(condition); 19 | 20 | public void Clear() => this.Value.Clear(); 21 | 22 | public int Count => this.Value.Count; 23 | 24 | public IEnumerator GetEnumerator() => this.Value.GetEnumerator(); 25 | 26 | IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator(); 27 | 28 | public override void SetValue(object value) 29 | { 30 | throw new NotImplementedException(); 31 | } 32 | 33 | public override string ToExpression() 34 | { 35 | throw new NotImplementedException(); 36 | } 37 | 38 | public override string ToString() 39 | { 40 | return XmlSerializerHelper.ToString(this.Value); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Roro/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Roro")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Roro")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("b9565eb4-fad3-4b1e-bd5c-ce2d28b23a06")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Core/ElementPickerLinkCell.cs: -------------------------------------------------------------------------------- 1 | using System.Drawing; 2 | using System.Windows.Forms; 3 | 4 | namespace Roro.Activities.Apps 5 | { 6 | public sealed class ElementPickerLinkCell : DataGridViewLinkCell 7 | { 8 | public ElementPickerLinkCell() 9 | { 10 | this.TrackVisitedState = false; 11 | } 12 | 13 | protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) 14 | { 15 | if (formattedValue.ToString().Length == 0) 16 | { 17 | formattedValue = "Pick element"; 18 | cellStyle.Font = new Font(cellStyle.Font, FontStyle.Italic); 19 | } 20 | base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts); 21 | } 22 | 23 | protected override void OnClick(DataGridViewCellEventArgs e) 24 | { 25 | using (var f = new ElementPickerForm(this.Value)) 26 | { 27 | if (f.ShowDialog() == DialogResult.OK) 28 | { 29 | this.Value = f.Query.ToString(); 30 | } 31 | this.DataGridView.FindForm().Activate(); 32 | } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/Roro.Activities/Helper/PriorityQueue.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Roro.Activities 6 | { 7 | public sealed class PriorityQueue 8 | { 9 | private readonly SortedList> Priorities; 10 | 11 | public int Count => this.Priorities.Count; 12 | 13 | public PriorityQueue() 14 | { 15 | this.Priorities = new SortedList>(); 16 | } 17 | 18 | public void Enqueue(T item, int priority) 19 | { 20 | if (item == null) 21 | { 22 | throw new ArgumentNullException("item"); 23 | } 24 | if (this.Priorities.TryGetValue(priority, out Queue existingQueue)) 25 | { 26 | existingQueue.Enqueue(item); 27 | } 28 | else 29 | { 30 | var newQueue = new Queue(); 31 | this.Priorities.Add(priority, newQueue); 32 | newQueue.Enqueue(item); 33 | } 34 | } 35 | 36 | public T Dequeue() 37 | { 38 | var first = this.Priorities.First(); 39 | var queue = first.Value; 40 | var item = queue.Dequeue(); 41 | if (queue.Count == 0) 42 | { 43 | this.Priorities.Remove(first.Key); 44 | } 45 | return item; 46 | } 47 | 48 | public void Clear() 49 | { 50 | this.Priorities.Clear(); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /src/Roro.Activities/LoopStartNode.cs: -------------------------------------------------------------------------------- 1 | 2 | using System; 3 | using System.Drawing; 4 | using System.Drawing.Drawing2D; 5 | using System.Linq; 6 | 7 | namespace Roro.Activities 8 | { 9 | public sealed class LoopStartNode : Node 10 | { 11 | public Guid LoopEndNodeId { get; set; } 12 | 13 | private LoopStartNode() 14 | { 15 | // required for XmlSerializer. 16 | } 17 | 18 | internal LoopStartNode(Activity activity) : base(activity) 19 | { 20 | this.Ports.Add(new NextPort()); 21 | } 22 | 23 | public override Guid Execute(ActivityContext context) 24 | { 25 | return this.Ports.First().NextNodeId; 26 | } 27 | 28 | public override GraphicsPath Render(Graphics g, Rect r, NodeStyle o) 29 | { 30 | var path = new GraphicsPath(); 31 | path.StartFigure(); 32 | path.AddPolygon(new Point[] 33 | { 34 | new Point(r.X + PageRenderOptions.GridSize, r.Y), 35 | new Point(r.Right - PageRenderOptions.GridSize, r.Y), 36 | new Point(r.Right, r.Y + PageRenderOptions.GridSize), 37 | new Point(r.Right, r.Bottom), 38 | new Point(r.X, r.Bottom), 39 | new Point(r.X, r.Y + PageRenderOptions.GridSize) 40 | }); 41 | path.CloseFigure(); 42 | // 43 | g.FillPath(o.BackBrush, path); 44 | g.DrawPath(o.BorderPen, path); 45 | return path; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Roro.Activities/Helper/Cell.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities 4 | { 5 | public class Cell 6 | { 7 | public static readonly CellLocation MoveUp = new CellLocation(-1, 0); 8 | 9 | public static readonly CellLocation MoveDown = new CellLocation(+1, 0); 10 | 11 | public static readonly CellLocation MoveLeft = new CellLocation(0, -1); 12 | 13 | public static readonly CellLocation MoveRight = new CellLocation(0, +1); 14 | 15 | public static readonly CellLocation[] All = new CellLocation[] { MoveUp, MoveDown, MoveLeft, MoveRight }; 16 | 17 | public CellLocation Location { get; set; } 18 | 19 | public CellLocation Direction { get; set; } 20 | 21 | public Guid Session { get; set; } 22 | 23 | public Cell Parent { get; set; } 24 | 25 | public int Priority { get; set; } 26 | 27 | public int CurrentCost { get; set; } 28 | 29 | public int RowEffort { get; set; } 30 | 31 | public int ColEffort { get; set; } 32 | 33 | public bool IsWall { get; set; } 34 | 35 | public bool IsOpen { get; set; } 36 | 37 | public Cell(int row, int col) 38 | { 39 | this.Location = new CellLocation(row, col); 40 | this.IsWall = false; 41 | this.IsOpen = true; 42 | } 43 | 44 | public override string ToString() 45 | { 46 | return string.Format("[Cell Row={0}, Col={1}, IsWall={2}, IsOpen={3}]", this.Location.Row, this.Location.Col, this.IsWall, this.IsOpen); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Roro.Activities.Outlook/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Roro.Activities.Outlook")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Roro.Activities.Outlook")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("c4291815-8e69-4af4-bd7e-8a9db3b6d63f")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Core/Condition.cs: -------------------------------------------------------------------------------- 1 | 2 | using Microsoft.VisualBasic.CompilerServices; 3 | using System; 4 | 5 | namespace Roro.Activities.Apps 6 | { 7 | public sealed class Condition 8 | { 9 | public bool Use 10 | { 11 | get => this.Required || this.Enabled; 12 | set => this.Enabled = value; 13 | } 14 | 15 | public string Name { get; set; } 16 | 17 | public object Value { get; set; } 18 | 19 | public bool Enabled { get; set; } 20 | 21 | public bool Required { get; set; } 22 | 23 | private Condition() 24 | { 25 | 26 | } 27 | 28 | public Condition(string name, object value, bool enabled, bool required) 29 | { 30 | this.Name = name; 31 | this.Value = value; 32 | this.Enabled = enabled; 33 | this.Required = required; 34 | } 35 | 36 | public bool Compare(object otherValue, Type otherType) 37 | { 38 | var value = this.Value ?? string.Empty; 39 | otherValue = otherValue ?? string.Empty; 40 | if (otherType == typeof(string)) 41 | { 42 | return LikeOperator.LikeString( 43 | value.ToString(), 44 | otherValue.ToString().Replace("[", "[[]").Replace("#", "[#]").Replace("?", "[?]"), 45 | Microsoft.VisualBasic.CompareMethod.Binary); 46 | } 47 | else 48 | { 49 | return otherValue.Equals(value); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Roro.Activities.Cognitive/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Roro.Activities.Cognitive")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Roro.Activities.Cognitive")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("f4558562-7292-4521-aa1d-3d090b070b92")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/Roro.Activities.SharePoint/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Roro.Activities.SharePoint")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Roro.Activities.SharePoint")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("c4291815-8e69-4af4-bd7e-8a9db3b6d63f")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/Roro.Activities/LoopEndNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Drawing.Drawing2D; 4 | using System.Linq; 5 | 6 | namespace Roro.Activities 7 | { 8 | public sealed class LoopEndNode : Node 9 | { 10 | //public Guid Next { get; set; } 11 | 12 | public Guid LoopStartNodeId { get; set; } 13 | 14 | private LoopEndNode() 15 | { 16 | // required for XmlSerializer. 17 | } 18 | 19 | internal LoopEndNode(Activity activity) : base(activity) 20 | { 21 | this.Ports.Add(new NextPort()); 22 | } 23 | 24 | public override Guid Execute(ActivityContext context) 25 | { 26 | return this.Ports.First().NextNodeId; 27 | } 28 | 29 | public override GraphicsPath Render(Graphics g, Rect r, NodeStyle o) 30 | { 31 | var path = new GraphicsPath(); 32 | path.StartFigure(); 33 | path.AddPolygon(new Point[] 34 | { 35 | new Point(r.X, r.Y), 36 | new Point(r.Right, r.Y), 37 | new Point(r.Right, r.Bottom - PageRenderOptions.GridSize), 38 | new Point(r.Right - PageRenderOptions.GridSize, r.Bottom), 39 | new Point(r.X + PageRenderOptions.GridSize, r.Bottom), 40 | new Point(r.X, r.Bottom - PageRenderOptions.GridSize) 41 | }); 42 | path.CloseFigure(); 43 | // 44 | g.FillPath(o.BackBrush, path); 45 | g.DrawPath(o.BorderPen, path); 46 | return path; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Input/InputEventHandler.cs: -------------------------------------------------------------------------------- 1 | // BSD 2-Clause License 2 | 3 | // Copyright(c) 2017, Arvie Delgado 4 | // All rights reserved. 5 | 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are met: 8 | 9 | // * Redistributions of source code must retain the above copyright notice, this 10 | // list of conditions and the following disclaimer. 11 | 12 | // * Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation 14 | // and/or other materials provided with the distribution. 15 | 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | // DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | using System; 28 | 29 | namespace Roro 30 | { 31 | public delegate void InputEventHandler(InputEventArgs e); 32 | } 33 | -------------------------------------------------------------------------------- /src/Roro.Activities/VariableCell.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Windows.Forms; 5 | 6 | namespace Roro.Activities 7 | { 8 | public sealed class VariableCell : DataGridViewComboBoxCell 9 | { 10 | public void OnDataError(object sender, DataGridViewDataErrorEventArgs e) 11 | { 12 | this.DataSource = new List(this.DataSource as List) 13 | { 14 | this.Value.ToString() 15 | }; 16 | e.ThrowException = false; 17 | } 18 | 19 | protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) 20 | { 21 | if (formattedValue.ToString().Length > 0) 22 | { 23 | formattedValue = string.Format("[{0}]", formattedValue); 24 | } 25 | else if (formattedValue.ToString().Length == 0 && !elementState.HasFlag(DataGridViewElementStates.Selected)) 26 | { 27 | formattedValue = "Select " + this.OwningColumn.HeaderText.ToLower(); 28 | cellStyle.Font = new Font(cellStyle.Font, FontStyle.Italic); 29 | cellStyle.ForeColor = Color.FromArgb(150, 150, 150); 30 | } 31 | base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/Roro.Activities/DecisionNode.cs: -------------------------------------------------------------------------------- 1 | 2 | using System; 3 | using System.Drawing; 4 | using System.Drawing.Drawing2D; 5 | using System.Linq; 6 | 7 | namespace Roro.Activities 8 | { 9 | public sealed class DecisionNode : Node 10 | { 11 | //public Guid True { get; set; } 12 | 13 | //public Guid False { get; set; } 14 | 15 | private DecisionNode() 16 | { 17 | // required for XmlSerializer. 18 | } 19 | 20 | internal DecisionNode(Activity activity) : base(activity) 21 | { 22 | this.Ports.Add(new TruePort()); 23 | this.Ports.Add(new FalsePort()); 24 | } 25 | 26 | public override Guid Execute(ActivityContext context) 27 | { 28 | if ((this.Activity as DecisionNodeActivity).Execute(context)) 29 | { 30 | return this.Ports.Where(x => x is TruePort).First().NextNodeId; 31 | } 32 | else 33 | { 34 | return this.Ports.Where(x => x is FalsePort).First().NextNodeId; 35 | } 36 | } 37 | 38 | public override GraphicsPath Render(Graphics g, Rect r, NodeStyle o) 39 | { 40 | var path = new GraphicsPath(); 41 | path.StartFigure(); 42 | path.AddPolygon(new Point[] 43 | { 44 | r.CenterTop, 45 | r.CenterRight, 46 | r.CenterBottom, 47 | r.CenterLeft 48 | }); 49 | path.CloseFigure(); 50 | // 51 | g.FillPath(o.BackBrush, path); 52 | g.DrawPath(o.BorderPen, path); 53 | return path; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Input/MouseButton.cs: -------------------------------------------------------------------------------- 1 | // BSD 2-Clause License 2 | 3 | // Copyright(c) 2017, Arvie Delgado 4 | // All rights reserved. 5 | 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are met: 8 | 9 | // * Redistributions of source code must retain the above copyright notice, this 10 | // list of conditions and the following disclaimer. 11 | 12 | // * Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation 14 | // and/or other materials provided with the distribution. 15 | 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | // DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | using System; 28 | 29 | namespace Roro 30 | { 31 | [Flags] 32 | public enum MouseButton 33 | { 34 | None, 35 | 36 | Left, 37 | 38 | Right, 39 | 40 | Middle = 4 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Input/InputEventType.cs: -------------------------------------------------------------------------------- 1 | // BSD 2-Clause License 2 | 3 | // Copyright(c) 2017, Arvie Delgado 4 | // All rights reserved. 5 | 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are met: 8 | 9 | // * Redistributions of source code must retain the above copyright notice, this 10 | // list of conditions and the following disclaimer. 11 | 12 | // * Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation 14 | // and/or other materials provided with the distribution. 15 | 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | // DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | using System; 28 | 29 | namespace Roro 30 | { 31 | public enum InputEventType 32 | { 33 | KeyUp = 0x0101, 34 | 35 | KeyDown = 0x0100, 36 | 37 | MouseUp = 0x0202, 38 | 39 | MouseDown = 0x0201, 40 | 41 | MouseMove = 0x0200, 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Roro.Activities/Helper/Rect.cs: -------------------------------------------------------------------------------- 1 | using System.Drawing; 2 | using System.Xml.Serialization; 3 | 4 | namespace Roro.Activities 5 | { 6 | public struct Rect 7 | { 8 | [XmlAttribute] 9 | public int X { get; set; } 10 | 11 | [XmlAttribute] 12 | public int Y { get; set; } 13 | 14 | [XmlAttribute] 15 | public int Width { get; set; } 16 | 17 | [XmlAttribute] 18 | public int Height { get; set; } 19 | 20 | public Rect(int x, int y, int width, int height) 21 | { 22 | this.X = x; 23 | this.Y = y; 24 | this.Width = width; 25 | this.Height = height; 26 | } 27 | 28 | public static implicit operator Rectangle(Rect r) => new Rectangle(r.X, r.Y, r.Width, r.Height); 29 | 30 | public static implicit operator Rect(Rectangle r) => new Rect(r.X, r.Y, r.Width, r.Height); 31 | 32 | public static implicit operator RectangleF(Rect r) => new RectangleF(r.X, r.Y, r.Width, r.Height); 33 | 34 | public static implicit operator Rect(RectangleF r) => new Rect((int)r.X, (int)r.Y, (int)r.Width, (int)r.Height); 35 | 36 | public int Top => this.Y; 37 | 38 | public int Left => this.X; 39 | 40 | public int Right => this.X + this.Width; 41 | 42 | public int Bottom => this.Y + this.Height; 43 | 44 | public Point Center => new Point(this.X + this.Width / 2, this.Y + this.Height / 2); 45 | 46 | public Point CenterTop => new Point(this.Center.X, this.Top); 47 | 48 | public Point CenterLeft => new Point(this.Left, this.Center.Y); 49 | 50 | public Point CenterRight => new Point(this.Right, this.Center.Y); 51 | 52 | public Point CenterBottom => new Point(this.Center.X, this.Bottom); 53 | } 54 | } -------------------------------------------------------------------------------- /src/Roro.Activities/Helper/CellLocation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities 4 | { 5 | public struct CellLocation 6 | { 7 | public int Row { get; set; } 8 | 9 | public int Col { get; set; } 10 | 11 | public CellLocation(int row, int col) 12 | { 13 | this.Row = row; 14 | this.Col = col; 15 | } 16 | 17 | public CellLocation Translate(int row, int col) 18 | { 19 | this.Row += row; 20 | this.Col += col; 21 | return this; 22 | } 23 | 24 | public static bool operator ==(CellLocation a, CellLocation z) 25 | { 26 | return a.Equals(z); 27 | } 28 | 29 | public static bool operator !=(CellLocation a, CellLocation z) 30 | { 31 | return !a.Equals(z); 32 | } 33 | 34 | public CellLocation Scale(double scale) 35 | { 36 | this.Row = (int)(this.Row * scale); 37 | this.Col = (int)(this.Col * scale); 38 | return this; 39 | } 40 | 41 | public override bool Equals(object obj) 42 | { 43 | return obj is CellLocation other && this.Row == other.Row && this.Col == other.Col; 44 | } 45 | 46 | public override int GetHashCode() 47 | { 48 | return base.GetHashCode(); 49 | } 50 | 51 | public override string ToString() 52 | { 53 | return string.Format("[CellLocation Row={0}, Col={1}]", this.Row, this.Col); 54 | } 55 | 56 | public int GetRowEffort(CellLocation other) 57 | { 58 | return Math.Abs(this.Row - other.Row); 59 | } 60 | 61 | public int GetColEffort(CellLocation other) 62 | { 63 | return Math.Abs(this.Col - other.Col); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/MacroRun.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities.Excel 4 | { 5 | public class MacroRun : ProcessNodeActivity 6 | { 7 | public Input Macro { get; set; } 8 | 9 | public Input Param1 { get; set; } 10 | 11 | public Input Param2 { get; set; } 12 | 13 | public Input Param3 { get; set; } 14 | 15 | public Input Param4 { get; set; } 16 | 17 | public Output Result { get; set; } 18 | 19 | public override void Execute(ActivityContext context) 20 | { 21 | var macro = context.Get(this.Macro).ToString(); 22 | var param1 = context.Get(this.Param1, null); 23 | var param2 = context.Get(this.Param2, null); 24 | var param3 = context.Get(this.Param3, null); 25 | var param4 = context.Get(this.Param4, null); 26 | 27 | var result = string.Empty; 28 | 29 | // F*ck! The code below is ugly. 30 | 31 | if (param1 == null) 32 | { 33 | result = ExcelBot.Shared.GetApp().Run(macro); 34 | } 35 | else if (param2 == null) 36 | { 37 | result = ExcelBot.Shared.GetApp().Run(macro, param1.ToString()); 38 | } 39 | else if (param3 == null) 40 | { 41 | result = ExcelBot.Shared.GetApp().Run(macro, param1.ToString(), param2.ToString()); 42 | } 43 | else if (param4 == null) 44 | { 45 | result = ExcelBot.Shared.GetApp().Run(macro, param1.ToString(), param2.ToString(), param3.ToString()); 46 | } 47 | else 48 | { 49 | result = ExcelBot.Shared.GetApp().Run(macro, param1.ToString(), param2.ToString(), param3.ToString(), param4.ToString()); 50 | } 51 | 52 | context.Set(this.Result, result); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Roro.Activities/VariableNode.cs: -------------------------------------------------------------------------------- 1 | 2 | using System; 3 | using System.Drawing; 4 | using System.Drawing.Drawing2D; 5 | 6 | namespace Roro.Activities 7 | { 8 | public sealed class VariableNode : Node 9 | { 10 | public string Type { get; set; } 11 | 12 | public object InitialValue { get; set; } 13 | 14 | internal object CurrentValue { get; set; } 15 | 16 | public const string StartToken = "["; 17 | 18 | public const string EndToken = "]"; 19 | 20 | public override bool CanEndLink => false; 21 | 22 | public override bool CanStartLink => false; 23 | 24 | private VariableNode() 25 | { 26 | // required for XmlSerializer. 27 | } 28 | 29 | internal VariableNode(Activity activity) : base(activity) 30 | { 31 | this.Type = DataType.GetDefault().GetType().FullName; 32 | } 33 | 34 | public override Guid Execute(ActivityContext context) 35 | { 36 | throw new NotImplementedException(); 37 | } 38 | 39 | public override GraphicsPath Render(Graphics g, Rect r, NodeStyle o) 40 | { 41 | var path = new GraphicsPath(); 42 | path.StartFigure(); 43 | path.AddPolygon(new Point[] 44 | { 45 | new Point(r.X + PageRenderOptions.GridSize, r.Y), 46 | new Point(r.Right, r.Y), 47 | new Point(r.Right - PageRenderOptions.GridSize, r.Bottom), 48 | new Point(r.X, r.Bottom), 49 | }); 50 | path.CloseFigure(); 51 | // 52 | g.FillPath(o.BackBrush, path); 53 | g.DrawPath(o.BorderPen, path); 54 | return path; 55 | } 56 | 57 | public override void RenderText(Graphics g, Rect r, NodeStyle o) 58 | { 59 | g.DrawString(this.Name + Environment.NewLine + this.CurrentValue, o.Font, o.FontBrush, r, o.StringFormat); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Roro.Activities/Port.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Drawing.Drawing2D; 4 | 5 | namespace Roro.Activities 6 | { 7 | public abstract class Port 8 | { 9 | public Guid Id { get; } 10 | 11 | public Guid NextNodeId { get; set; } 12 | 13 | public Rect Bounds { get; set; } 14 | 15 | public abstract Point GetOffset(Rect r); 16 | 17 | public abstract Brush GetBackBrush(); 18 | 19 | public Port() 20 | { 21 | this.Id = Guid.NewGuid(); 22 | } 23 | 24 | internal void UpdateBounds(Rectangle r) 25 | { 26 | var portPoint = this.GetOffset(r); 27 | var portSize = new Size(PageRenderOptions.GridSize, PageRenderOptions.GridSize); 28 | portPoint.Offset(-portSize.Width / 2, -portSize.Height / 2); 29 | var portBounds = new Rectangle(portPoint, portSize); 30 | this.Bounds = portBounds; 31 | } 32 | 33 | public GraphicsPath Render(Graphics g, Rectangle r, NodeStyle o) 34 | { 35 | this.UpdateBounds(r); 36 | g.FillEllipse(this.GetBackBrush(), this.Bounds); 37 | var portPath = new GraphicsPath(); 38 | portPath.StartFigure(); 39 | portPath.AddEllipse(this.Bounds); 40 | portPath.CloseFigure(); 41 | return portPath; 42 | } 43 | } 44 | 45 | public sealed class NextPort : Port 46 | { 47 | public override Point GetOffset(Rect r) => r.CenterBottom; 48 | 49 | public override Brush GetBackBrush() => new SolidBrush(Color.FromArgb(100, Color.Blue)); 50 | } 51 | 52 | public sealed class TruePort : Port 53 | { 54 | public override Point GetOffset(Rect r) => r.CenterBottom; 55 | 56 | public override Brush GetBackBrush() => new SolidBrush(Color.FromArgb(100, Color.Green)); 57 | } 58 | 59 | public sealed class FalsePort : Port 60 | { 61 | public override Point GetOffset(Rect r) => r.CenterRight; 62 | 63 | public override Brush GetBackBrush() => new SolidBrush(Color.FromArgb(100, Color.Red)); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Core/ElementHighlighterForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Windows.Forms; 4 | 5 | namespace Roro.Activities.Apps 6 | { 7 | internal class ElementHighlighterForm : Form 8 | { 9 | private const int border = 3; 10 | 11 | private void InitializeComponent() 12 | { 13 | this.SuspendLayout(); 14 | // 15 | // Highlighter 16 | // 17 | this.ClientSize = new System.Drawing.Size(284, 261); 18 | this.Name = "Highlighter"; 19 | this.Opacity = 0.8; 20 | this.BackColor = Color.Red; 21 | this.FormBorderStyle = FormBorderStyle.None; 22 | this.Bounds = Rectangle.Empty; 23 | this.ShowInTaskbar = false; // Hide in taskbar 24 | this.Text = string.Empty; // Hide in task manager 25 | this.Visible = true; // Set Visible (to true) before Enabled (to false) to hide in ALT+TAB windows 26 | this.Enabled = false; // Disable focus; mouse and keyboard events 27 | this.Load += new System.EventHandler(this.Highlighter_Load); 28 | this.ResumeLayout(false); 29 | 30 | } 31 | 32 | public ElementHighlighterForm() 33 | { 34 | this.InitializeComponent(); 35 | this.Render(Screen.PrimaryScreen.Bounds, Color.Red); 36 | } 37 | 38 | public void Render(Rectangle rect, Color color) 39 | { 40 | Rectangle newRect = rect; 41 | newRect.Inflate(border, border); 42 | Region region = new Region(new Rectangle(0, 0, newRect.Width, newRect.Height)); 43 | region.Exclude(new Rectangle(border, border, newRect.Width - border * 2, newRect.Height - border * 2)); 44 | 45 | this.Invoke(new Action(() => 46 | { 47 | this.DesktopBounds = newRect; 48 | this.Region = region; 49 | this.BackColor = color; 50 | this.TopMost = true; 51 | this.Show(); 52 | })); 53 | } 54 | 55 | private void Highlighter_Load(object sender, EventArgs e) 56 | { 57 | 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /bin/Test Workflows/cognitive-ocr.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 664e5727-ab98-46cb-a4f2-d31cd8eee7c6 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | Roro.Activities.Text 24 | 25 | 26 | 27 | 28 | 29 | 30 | X 31 | 32 | 33 | 34 | Y 35 | 36 | 37 | 38 | Width 39 | 40 | 41 | 42 | Height 43 | 44 | 45 | 46 | Text 47 | Text 48 | 49 | 50 | 51 | 52 | 5953b3fa-2906-4b2b-a9e0-2049b1ed21a8 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Core/Element.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace Roro.Activities.Apps 5 | { 6 | public abstract class Element 7 | { 8 | [Property] 9 | public abstract string Id { get; } 10 | 11 | [Property] 12 | public abstract string Name { get; } 13 | 14 | [Property] 15 | public abstract string ClassName { get; } 16 | 17 | [Property(Required: true)] 18 | public abstract string Type { get; } 19 | 20 | [Property(Required: true)] 21 | public abstract string Path { get; } 22 | 23 | [Property(Enabled: true)] 24 | public abstract string Value { get; set; } 25 | 26 | public abstract Rect Bounds { get; } 27 | 28 | [Property(Required: true)] 29 | public abstract string MainWindowName { get; } 30 | 31 | [Property(Required: true)] 32 | public abstract string WindowName { get; } 33 | 34 | public abstract void Focus(); 35 | 36 | public abstract void Click(); 37 | 38 | public ElementQuery GetQuery() 39 | { 40 | var query = new ElementQuery(); 41 | var props = this.GetType().GetProperties().Where(attr => Attribute.IsDefined(attr, typeof(Property))); 42 | foreach (var prop in props) 43 | { 44 | var attr = Attribute.GetCustomAttribute(prop, typeof(Property), true) as Property; 45 | var condition = new Condition(prop.Name, prop.GetValue(this), attr.Enabled, attr.Required); 46 | query.Add(condition); 47 | } 48 | return query; 49 | } 50 | 51 | public bool TryQuery(ElementQuery query) 52 | { 53 | foreach (var condition in query) 54 | { 55 | if (condition.Required || condition.Enabled) 56 | { 57 | var prop = this.GetType().GetProperty(condition.Name); 58 | if (condition.Compare(prop.GetValue(this), prop.PropertyType)) 59 | { 60 | continue; 61 | } 62 | return false; 63 | } 64 | } 65 | return true; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/CellValuePaste.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities.Excel 4 | { 5 | public class CellValuePaste : ProcessNodeActivity 6 | { 7 | public Input WorkbookName { get; set; } 8 | 9 | public Input WorksheetName { get; set; } 10 | 11 | public Input Cell { get; set; } 12 | 13 | public Input PasteValuesOnly { get; set; } 14 | 15 | public override void Execute(ActivityContext context) 16 | { 17 | var wbName = context.Get(this.WorkbookName); 18 | var wsName = context.Get(this.WorksheetName); 19 | var range = context.Get(this.Cell); 20 | var pasteType = context.Get(this.PasteValuesOnly, false); 21 | 22 | if (pasteType) 23 | { 24 | ExcelBot.Shared.GetRange(wbName, wsName, range).PasteSpecial(XlPasteType.xlPasteValuesAndNumberFormats); 25 | } 26 | else 27 | { 28 | ExcelBot.Shared.GetRange(wbName, wsName, range).PasteSpecial(); 29 | } 30 | } 31 | 32 | /// 33 | /// https://msdn.microsoft.com/en-us/vba/excel-vba/articles/xlpastetype-enumeration-excel 34 | /// 35 | private enum XlPasteType 36 | { 37 | xlPasteAll = -4104, //Everything will be pasted. 38 | xlPasteAllExceptBorders = 7, //Everything except borders will be pasted. 39 | xlPasteAllMergingConditionalFormats = 14, //Everything will be pasted and conditional formats will be merged. 40 | xlPasteAllUsingSourceTheme = 13, //Everything will be pasted using the source theme. 41 | xlPasteColumnWidths = 8, //Copied column width is pasted. 42 | xlPasteComments = -4144, //Comments are pasted. 43 | xlPasteFormats = -4122, //Copied source format is pasted. 44 | xlPasteFormulas = -4123, //Formulas are pasted. 45 | xlPasteFormulasAndNumberFormats = 11, //Formulas and Number formats are pasted. 46 | xlPasteValidation = 6, //Validations are pasted. 47 | xlPasteValues = -4163, //Values are pasted. 48 | xlPasteValuesAndNumberFormats = 12, //Values and Number formats are pasted. 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Roro.Activities/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/Roro.Activities.Files/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/Roro.Activities.Cognitive/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/Roro.Activities.SharePoint/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/Roro.Activities/RenderOptions.cs: -------------------------------------------------------------------------------- 1 | using System.Drawing; 2 | using System.Drawing.Drawing2D; 3 | 4 | namespace Roro.Activities 5 | { 6 | public sealed class PageRenderOptions 7 | { 8 | public static int GridSize = 20; 9 | 10 | public static Pen GridPen = new Pen(Color.FromArgb(240, 240, 240), 1); 11 | 12 | public static Color BackColor = Color.White; 13 | 14 | public static Brush SelectionBackBrush = new SolidBrush(Color.FromArgb(50, 150, 150, 150)); 15 | 16 | public static Brush DebugNodeBackBrush = new SolidBrush(Color.FromArgb(255, 225, 125)); 17 | 18 | public static Pen SelectedNodeBorderPen = new Pen(Color.DarkOrange, 2); 19 | } 20 | 21 | public sealed class NodeStyle 22 | { 23 | public Font Font { get; set; } 24 | 25 | public Brush FontBrush { get; set; } 26 | 27 | public Pen BorderPen { get; set; } 28 | 29 | public Brush PortBackBrush { get; set; } 30 | 31 | public Brush BackBrush { get; set; } 32 | 33 | public Pen LinePenWithArrow { get; set; } 34 | 35 | 36 | public NodeStyle() 37 | { 38 | this.Font = new Font("Segoe UI", 10, GraphicsUnit.Pixel); 39 | this.FontBrush = new SolidBrush(Color.FromArgb(50, 50, 50)); 40 | this.BorderPen = new Pen(Color.FromArgb(100, 100, 100), 1.5f); 41 | this.BackBrush = new SolidBrush(PageRenderOptions.BackColor); 42 | this.PortBackBrush = new SolidBrush(Color.FromArgb(150, 50, 150, 250)); 43 | this.LinePenWithArrow = new Pen(Color.FromArgb(100, 100, 100), 1.5f); 44 | using (GraphicsPath endCap = new GraphicsPath()) 45 | { 46 | var width = PageRenderOptions.GridSize * 3 / 4 / 2 / this.LinePenWithArrow.Width; 47 | 48 | endCap.AddLine(-width, -width - this.LinePenWithArrow.Width / 2, 0, -this.LinePenWithArrow.Width / 2); 49 | endCap.AddLine(+width, -width - this.LinePenWithArrow.Width / 2, 0, -this.LinePenWithArrow.Width / 2); 50 | this.LinePenWithArrow.CustomEndCap = new CustomLineCap(null, endCap); 51 | } 52 | } 53 | 54 | public StringFormat StringFormat = new StringFormat() 55 | { 56 | Alignment = StringAlignment.Center, 57 | LineAlignment = StringAlignment.Center 58 | }; 59 | } 60 | } -------------------------------------------------------------------------------- /src/Roro/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /bin/Test Workflows/cognitive-speech.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 80b1f8f7-455a-424a-8603-3286cf97b483 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | Roro.Activities.Text 24 | 25 | 26 | 27 | 28 | 29 | 30 | Text 31 | Message 32 | 33 | 34 | 35 | 36 | 308bda94-48d4-46cc-85c9-5285a62fbb80 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | Text 46 | "You said, " + [Message] 47 | 48 | 49 | 50 | 51 | b7ce4f34-c70b-4b3e-8dd8-33d6f61c9e0c 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Input/InputEventArgs.cs: -------------------------------------------------------------------------------- 1 | // BSD 2-Clause License 2 | 3 | // Copyright(c) 2017, Arvie Delgado 4 | // All rights reserved. 5 | 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are met: 8 | 9 | // * Redistributions of source code must retain the above copyright notice, this 10 | // list of conditions and the following disclaimer. 11 | 12 | // * Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation 14 | // and/or other materials provided with the distribution. 15 | 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | // DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | using System; 28 | 29 | namespace Roro 30 | { 31 | public sealed class InputEventArgs : EventArgs 32 | { 33 | public InputEventType Type { get; internal set; } 34 | 35 | public int X { get; internal set; } 36 | 37 | public int Y { get; internal set; } 38 | 39 | public MouseButton Button { get; internal set; } 40 | 41 | public KeyboardKey Key { get; internal set; } 42 | 43 | public bool AltKey { get; internal set; } 44 | 45 | public bool CtrlKey { get; internal set; } 46 | 47 | public bool ShiftKey { get; internal set; } 48 | 49 | public bool WinKey { get; internal set; } 50 | 51 | public override string ToString() 52 | { 53 | return string.Format( 54 | "[{0} X={1}, Y={2}, Button={3}, Key={4}, AltKey={5}, CtrlKey={6}, ShiftKey={7}, WinKey={8}]", 55 | this.Type, this.X, this.Y, this.Button, this.Key, this.AltKey, this.CtrlKey, this.ShiftKey, this.WinKey); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Roro/Form1.cs: -------------------------------------------------------------------------------- 1 | using Roro.Activities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Data; 6 | using System.Drawing; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | using System.Windows.Forms; 12 | 13 | namespace Roro 14 | { 15 | public partial class Form1 : Form 16 | { 17 | public Form1() 18 | { 19 | InitializeComponent(); 20 | } 21 | 22 | private void Form1_Load(object sender, EventArgs e) 23 | { 24 | 25 | } 26 | 27 | private const string FileDialogFilter = "Roro Workflow (*.xml)|*.xml"; 28 | 29 | private void OpenLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 30 | { 31 | this.OpenWorkflow(); 32 | } 33 | 34 | private void CreateLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 35 | { 36 | this.CreateWorkflow(); 37 | } 38 | 39 | private void OpenWorkflow() 40 | { 41 | using (var file = new OpenFileDialog()) 42 | { 43 | file.Filter = FileDialogFilter; 44 | if (file.ShowDialog() == DialogResult.OK) 45 | { 46 | var form = new PageForm(File.ReadAllText(file.FileName)); 47 | form.OnBeforeSave += (ss, ee) => File.WriteAllText(form.FileName, form.FileContent); 48 | form.FileName = file.FileName; 49 | form.Show(); 50 | } 51 | } 52 | } 53 | 54 | private void CreateWorkflow() 55 | { 56 | var form = new PageForm(string.Empty); 57 | form.OnBeforeSave += (ss, ee) => 58 | { 59 | if (form.FileName == string.Empty) 60 | { 61 | using (var file = new SaveFileDialog()) 62 | { 63 | file.Filter = FileDialogFilter; 64 | if (file.ShowDialog() == DialogResult.OK) 65 | { 66 | form.FileName = file.FileName; 67 | } 68 | else 69 | { 70 | return; 71 | } 72 | } 73 | } 74 | File.WriteAllText(form.FileName, form.FileContent); 75 | }; 76 | form.Show(); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/Roro.Activities.Outlook/Roro.Activities.Outlook.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {C4291815-8E69-4AF4-BD7E-8A9DB3B6D63F} 8 | Library 9 | Properties 10 | Roro.Activities.Outlook 11 | Roro.Activities.Outlook 12 | v4.6 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | ..\..\bin\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | {bd513e2d-46bc-408e-98e6-d12aee06e7ea} 49 | Roro.Activities 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/Roro.Activities.Outlook/MailSend.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Roro.Activities.Outlook 4 | { 5 | public class MailSend : ProcessNodeActivity 6 | { 7 | public Input From { get; set; } 8 | 9 | public Input To { get; set; } 10 | 11 | public Input Cc { get; set; } 12 | 13 | public Input Bcc { get; set; } 14 | 15 | public Input Subject { get; set; } 16 | 17 | public Input Body { get; set; } 18 | 19 | public Input Attachment { get; set; } 20 | 21 | public Input IsHtmlBody { get; set; } 22 | 23 | public Input IsDraft { get; set; } 24 | 25 | public override void Execute(ActivityContext context) 26 | { 27 | var from = context.Get(this.From, string.Empty); 28 | var to = context.Get(this.To, string.Empty); 29 | var cc = context.Get(this.Cc, string.Empty); 30 | var bcc = context.Get(this.Bcc, string.Empty); 31 | var subject = context.Get(this.Subject, string.Empty); 32 | var body = context.Get(this.Body, string.Empty); 33 | var attachment = context.Get(this.Attachment, string.Empty); 34 | var isHtmlBody = context.Get(this.IsHtmlBody, false); 35 | var isdraft = context.Get(this.IsDraft, false); 36 | 37 | dynamic app = Activator.CreateInstance(Type.GetTypeFromProgID("Outlook.Application")); 38 | 39 | var mailItem = app.CreateItem(0 /* OlItemType.olMailItem */); 40 | 41 | if (from.ToString().Length > 0) 42 | { 43 | var fromAccount = app.Session.Accounts.Item(from.ToString()); 44 | if (fromAccount == null) 45 | { 46 | throw new Exception("Cannot find " + from + " account."); 47 | } 48 | mailItem.SendUsingAccount = fromAccount; 49 | } 50 | 51 | mailItem.To = to; 52 | mailItem.CC = cc; 53 | mailItem.BCC = bcc; 54 | mailItem.Subject = subject; 55 | if (isHtmlBody) 56 | { 57 | mailItem.HTMLBody = body; 58 | } 59 | else 60 | { 61 | mailItem.Body = body; 62 | } 63 | if (attachment.ToString().Length > 0) 64 | { 65 | mailItem.Attachments.Add(attachment.ToString(), 1 /* OlAttachmentType.olByValue */); 66 | } 67 | if (isdraft) 68 | { 69 | mailItem.Display(); 70 | } 71 | else 72 | { 73 | mailItem.Send(); 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/Roro.Activities/Node.cs: -------------------------------------------------------------------------------- 1 | 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Drawing; 5 | using System.Drawing.Drawing2D; 6 | using System.Linq; 7 | using System.Xml.Serialization; 8 | 9 | namespace Roro.Activities 10 | { 11 | public abstract class Node 12 | { 13 | [XmlAttribute] 14 | public Guid Id { get; set; } 15 | 16 | [XmlAttribute] 17 | public string Name { get; set; } 18 | 19 | public Rect Bounds { get; set; } 20 | 21 | public Activity Activity { get; set; } 22 | 23 | public List Ports { get; set; } 24 | 25 | protected Node() 26 | { 27 | this.Ports = new List(); 28 | this.RenderedPorts = new Dictionary(); 29 | } 30 | 31 | public Node(Activity activity) : this() 32 | { 33 | this.Activity = activity; 34 | this.Id = Guid.NewGuid(); 35 | this.Name = activity.GetType().Name.Humanize(); 36 | this.Bounds = new Rectangle( 37 | PageRenderOptions.GridSize * 0, 38 | PageRenderOptions.GridSize * 0, 39 | PageRenderOptions.GridSize * 4, 40 | PageRenderOptions.GridSize * 2); 41 | } 42 | 43 | internal Dictionary RenderedPorts { get; set; } 44 | 45 | public virtual bool CanStartLink => true; 46 | 47 | public virtual bool CanEndLink => true; 48 | 49 | public void SetBounds(Rect rect) 50 | { 51 | rect.X = Math.Max(0, (rect.X / PageRenderOptions.GridSize) * PageRenderOptions.GridSize); 52 | rect.Y = Math.Max(0, (rect.Y / PageRenderOptions.GridSize) * PageRenderOptions.GridSize); 53 | foreach (var port in this.Ports) 54 | { 55 | port.UpdateBounds(rect); 56 | } 57 | this.Bounds = rect; 58 | } 59 | 60 | public Port GetPortById(Guid id) 61 | { 62 | return this.Ports.FirstOrDefault(x => x.Id == id); 63 | } 64 | 65 | public Port GetPortFromPoint(Point pt) 66 | { 67 | if (this.RenderedPorts.FirstOrDefault(x => x.Value.IsVisible(pt.X, pt.Y)) is KeyValuePair item) 68 | { 69 | return item.Key; 70 | } 71 | return null; 72 | } 73 | 74 | public abstract Guid Execute(ActivityContext context); 75 | 76 | public abstract GraphicsPath Render(Graphics g, Rect r, NodeStyle o); 77 | 78 | public virtual void RenderText(Graphics g, Rect r, NodeStyle o) 79 | { 80 | g.DrawString(this.Name, o.Font, o.FontBrush, r, o.StringFormat); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Core/WinElementType.cs: -------------------------------------------------------------------------------- 1 | // BSD 2-Clause License 2 | 3 | // Copyright(c) 2017, Arvie Delgado 4 | // All rights reserved. 5 | 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are met: 8 | 9 | // * Redistributions of source code must retain the above copyright notice, this 10 | // list of conditions and the following disclaimer. 11 | 12 | // * Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation 14 | // and/or other materials provided with the distribution. 15 | 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | // DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | using System; 28 | 29 | namespace Roro 30 | { 31 | internal enum WinElementType 32 | { 33 | Button = 50000, 34 | Calendar = 50001, 35 | CheckBox = 50002, 36 | ComboBox = 50003, 37 | TextBox = 50004, // Edit 38 | Hyperlink = 50005, 39 | Image = 50006, 40 | ListItem = 50007, 41 | List = 50008, 42 | Menu = 50009, 43 | MenuBar = 50010, 44 | MenuItem = 50011, 45 | ProgressBar = 50012, 46 | RadioButton = 50013, 47 | ScrollBar = 50014, 48 | Slider = 50015, 49 | Spinner = 50016, 50 | StatusBar = 50017, 51 | Tab = 50018, 52 | TabItem = 50019, 53 | Text = 50020, 54 | ToolBar = 50021, 55 | ToolTip = 50022, 56 | Tree = 50023, 57 | TreeItem = 50024, 58 | Custom = 50025, 59 | Group = 50026, 60 | Thumb = 50027, 61 | DataGrid = 50028, 62 | DataItem = 50029, 63 | Document = 50030, 64 | SplitButton = 50031, 65 | Window = 50032, 66 | Pane = 50033, 67 | Header = 50034, 68 | HeaderItem = 50035, 69 | Table = 50036, 70 | TitleBar = 50037, 71 | Separator = 50038, 72 | SemanticZoom = 50039, 73 | AppBar = 50040, 74 | } 75 | } -------------------------------------------------------------------------------- /src/Roro.Activities/ActivityContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading; 5 | 6 | namespace Roro.Activities 7 | { 8 | public sealed class ActivityContext 9 | { 10 | private CancellationToken CancellationToken { get; } 11 | 12 | private IEnumerable InVariables { get; } 13 | 14 | private IEnumerable OutVariables { get; } 15 | 16 | public ActivityContext(CancellationToken token, IEnumerable variables) : this(token, variables, variables) 17 | { 18 | ; 19 | } 20 | 21 | public ActivityContext(CancellationToken token, IEnumerable inVariables, IEnumerable outVariables) 22 | { 23 | this.InVariables = inVariables; 24 | this.OutVariables = outVariables; 25 | } 26 | 27 | public void ThrowIfCancellationRequested() 28 | { 29 | this.CancellationToken.ThrowIfCancellationRequested(); 30 | } 31 | 32 | public T Get(Input input) where T : DataType, new() 33 | { 34 | if (this.InternalGet(input) is object value) 35 | { 36 | var t = new T(); 37 | t.SetValue(value); 38 | return t; 39 | } 40 | throw new Exception(string.Format("The activity input '{0}' is required", input.Name.Humanize())); 41 | } 42 | 43 | public T Get(Input input, T valueIfNull) where T : DataType, new() 44 | { 45 | if (this.InternalGet(input) is object value) 46 | { 47 | var t = new T(); 48 | t.SetValue(value); 49 | return t; 50 | } 51 | return valueIfNull; 52 | } 53 | 54 | private object InternalGet(Input input) 55 | { 56 | if (string.IsNullOrWhiteSpace(input.Value)) 57 | { 58 | return null; 59 | } 60 | return Expression.Evaluate(input.Value, this.InVariables); 61 | } 62 | 63 | public void Set(Output output, T value) where T : DataType, new() 64 | { 65 | this.InternalSet(output, value); 66 | } 67 | 68 | private void InternalSet(Output output, object value) 69 | { 70 | if (string.IsNullOrWhiteSpace(output.Value)) 71 | { 72 | return; 73 | } 74 | if (this.OutVariables.FirstOrDefault(x => x.Name == output.Value) is VariableNode variable) 75 | { 76 | if (value is DataType dataType) 77 | { 78 | value = dataType.GetValue(); 79 | } 80 | variable.CurrentValue = value; 81 | } 82 | else 83 | { 84 | throw new Exception("Variable not found."); 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/Roro/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Roro.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Roro.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Core/ChromeContext.cs: -------------------------------------------------------------------------------- 1 | // BSD 2-Clause License 2 | 3 | // Copyright(c) 2017, Arvie Delgado 4 | // All rights reserved. 5 | 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are met: 8 | 9 | // * Redistributions of source code must retain the above copyright notice, this 10 | // list of conditions and the following disclaimer. 11 | 12 | // * Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation 14 | // and/or other materials provided with the distribution. 15 | 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | // DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | using System; 28 | using OpenQA.Selenium.Chrome; 29 | using System.Drawing; 30 | 31 | namespace Roro 32 | { 33 | public sealed class ChromeContext : WebContext 34 | { 35 | public ChromeContext() 36 | { 37 | // session 38 | var session = Guid.NewGuid().ToString(); 39 | 40 | // service 41 | var service = ChromeDriverService.CreateDefaultService(); 42 | service.HideCommandPromptWindow = false; 43 | 44 | // options 45 | var options = new ChromeOptions(); 46 | options.AddArgument("--force-renderer-accessibility"); 47 | options.AddArgument(session.ToString()); 48 | 49 | // driver 50 | this.Driver = new ChromeDriver(service, options, this.Timeout); 51 | 52 | // process 53 | this.ProcessId = this.GetProcessIdFromSession(session); 54 | } 55 | 56 | protected override bool UpdateViewport(WinElement winElement) 57 | { 58 | this.Viewport = Rectangle.Empty; 59 | if (winElement != null && winElement.MainWindow is WinElement target && target.ProcessId == this.ProcessId) 60 | { 61 | if (target.GetElement(x => x.Class == "Chrome_RenderWidgetHostHWND") is WinElement viewport) 62 | { 63 | this.Viewport = viewport.Bounds; 64 | return true; 65 | } 66 | } 67 | return false; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Core/SapElementType.cs: -------------------------------------------------------------------------------- 1 | // BSD 2-Clause License 2 | 3 | // Copyright(c) 2017, Arvie Delgado 4 | // All rights reserved. 5 | 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are met: 8 | 9 | // * Redistributions of source code must retain the above copyright notice, this 10 | // list of conditions and the following disclaimer. 11 | 12 | // * Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation 14 | // and/or other materials provided with the distribution. 15 | 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | // DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | using System; 28 | 29 | namespace Roro 30 | { 31 | // As of SAP GUI 7.40 patch 5 32 | 33 | internal enum SapElementType 34 | { 35 | Application = 10, 36 | Box = 62, 37 | Button = 40, 38 | CheckBox = 42, 39 | Collection = 120, 40 | ComboBox = 34, 41 | Component = 0, 42 | ComponentCollection = 128, 43 | Connection = 11, 44 | Container = 70, 45 | ContainerShell = 51, 46 | ContextMenu = 127, 47 | CTextField = 32, 48 | CustomControl = 50, 49 | DialogShell = 125, 50 | DockShell = 126, 51 | FrameWindow = 20, 52 | GOSShell = 123, 53 | Label = 30, 54 | ListContainer = 73, 55 | MainWindow = 21, 56 | Menu = 110, 57 | Menubar = 111, 58 | MessageWindow = 23, 59 | ModalWindow = 22, 60 | OkCodeField = 35, 61 | PasswordField = 33, 62 | RadioButton = 41, 63 | Scrollbar = 100, 64 | ScrollContainer = 72, 65 | Session = 12, 66 | SessionInfo = 121, 67 | Shell = 122, 68 | SimpleContainer = 71, 69 | SplitterContainer = 75, 70 | SplitterShell = 124, 71 | Statusbar = 103, 72 | StatusPane = 43, 73 | Tab = 91, 74 | TableColumn = 81, 75 | TableControl = 80, 76 | TableRow = 82, 77 | TabStrip = 90, 78 | TextField = 31, 79 | Titlebar = 102, 80 | Toolbar = 101, 81 | Unknown = -1, 82 | UserArea = 74, 83 | VComponent = 1, 84 | VContainer = 2 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Core/WinContext.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace Roro.Activities.Apps 5 | { 6 | public sealed class WinContext : Context 7 | { 8 | public static readonly WinContext Shared = new WinContext(); 9 | 10 | public WinElement Target { get; private set; } 11 | 12 | private WinContext() 13 | { 14 | this.ProcessId = WinElement.GetRoot().ProcessId; 15 | } 16 | 17 | public override Element GetElementFromFocus() 18 | { 19 | return this.Target = WinElement.GetFromFocus(); 20 | } 21 | 22 | public override Element GetElementFromPoint(int screenX, int screenY) 23 | { 24 | return this.Target = WinElement.GetFromPoint(screenX, screenY); 25 | } 26 | 27 | public override IEnumerable GetElementsFromQuery(ElementQuery query) 28 | { 29 | var result = new List(); 30 | var candidates = new Queue(); 31 | var targetPath = query.FirstOrDefault(x => x.Name == "Path")?.Value.ToString(); 32 | if (targetPath == null) return result; 33 | 34 | var targetMainWindowName = query.FirstOrDefault(x => x.Name == "MainWindowName").Value?.ToString() ?? string.Empty; 35 | var targetWindowName = query.FirstOrDefault(x => x.Name == "WindowName").Value?.ToString() ?? string.Empty; 36 | var targetWindowCount = targetPath.Split('/').Count(); 37 | 38 | candidates.Enqueue(WinElement.GetRoot()); 39 | while (candidates.Count > 0) 40 | { 41 | var candidate = candidates.Dequeue(); 42 | var candidatePath = candidate.Path; 43 | var candidateWindowCount = candidatePath.Split('/').Count(x => x == "window"); 44 | if (targetPath.StartsWith(candidatePath)) 45 | { 46 | if (candidateWindowCount > 0) 47 | { 48 | if (candidate.MainWindowName != targetMainWindowName) 49 | { 50 | continue; 51 | } 52 | } 53 | if (candidateWindowCount == targetWindowCount) 54 | { 55 | if (candidate.WindowName != targetWindowName) 56 | { 57 | continue; 58 | } 59 | } 60 | if (targetPath.Equals(candidatePath)) 61 | { 62 | if (candidate.TryQuery(query)) 63 | { 64 | result.Add(candidate); 65 | } 66 | } 67 | else 68 | { 69 | foreach (var child in candidate.Children) 70 | { 71 | candidates.Enqueue(child); 72 | } 73 | } 74 | } 75 | } 76 | 77 | return result; 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /src/Roro.Activities/Expression.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.CSharp.Scripting; 2 | using Microsoft.CodeAnalysis.Scripting; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace Roro.Activities 9 | { 10 | internal class Expression 11 | { 12 | public static object Evaluate(string expression, IEnumerable variableNodes) 13 | { 14 | if (String.IsNullOrWhiteSpace(expression)) 15 | { 16 | return null; 17 | } 18 | 19 | try 20 | { 21 | expression = Expression.Resolve(expression, variableNodes); 22 | var result = Task.Run(async () => 23 | { 24 | return await CSharpScript.EvaluateAsync(expression, ScriptOptions.Default.WithImports("System")); 25 | }).Result; 26 | return result; 27 | } 28 | catch (CompilationErrorException) 29 | { 30 | throw; 31 | // string.Join(Environment.NewLine, e.Diagnostics) 32 | } 33 | } 34 | 35 | private static string Resolve(string expression, IEnumerable variableNodes) 36 | { 37 | var resolvedExpression = string.Empty; 38 | 39 | var currentIndex = 0; 40 | while (currentIndex < expression.Length) 41 | { 42 | var startIndex = expression.IndexOf(VariableNode.StartToken, currentIndex); 43 | if (startIndex < 0) 44 | { 45 | resolvedExpression += expression.Substring(currentIndex); 46 | break; 47 | } 48 | var endIndex = expression.IndexOf(VariableNode.EndToken, startIndex + 1); 49 | if (endIndex < 0) 50 | { 51 | throw new FormatException(string.Format("The variable at char {0} has missing '{1}' in expression:\n\n{2}", startIndex, VariableNode.EndToken, expression)); 52 | } 53 | var variableName = expression.Substring(startIndex + 1, endIndex - startIndex - 1); 54 | if (variableName == VariableNode.StartToken) 55 | { 56 | resolvedExpression += expression.Substring(currentIndex, endIndex - currentIndex + 1); 57 | currentIndex = endIndex + 1; 58 | continue; 59 | } 60 | var variableNode = variableNodes.FirstOrDefault(x => x.Name == variableName); 61 | if (variableNode == null) 62 | { 63 | throw new FormatException(string.Format("Variable {0}{1}{2} not found.", VariableNode.StartToken, variableName, VariableNode.EndToken)); 64 | } 65 | var variable = DataType.CreateInstance(variableNode.Type); 66 | variable.SetValue(variableNode.CurrentValue); 67 | resolvedExpression += variable.ToExpression(); 68 | currentIndex = endIndex + 1; 69 | } 70 | 71 | return resolvedExpression; 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Core/EdgeContext.cs: -------------------------------------------------------------------------------- 1 | // BSD 2-Clause License 2 | 3 | // Copyright(c) 2017, Arvie Delgado 4 | // All rights reserved. 5 | 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are met: 8 | 9 | // * Redistributions of source code must retain the above copyright notice, this 10 | // list of conditions and the following disclaimer. 11 | 12 | // * Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation 14 | // and/or other materials provided with the distribution. 15 | 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | // DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | using System; 28 | using OpenQA.Selenium.Edge; 29 | using Microsoft.Win32; 30 | using System.Linq; 31 | using System.Drawing; 32 | 33 | namespace Roro 34 | { 35 | public sealed class EdgeContext : WebContext 36 | { 37 | public EdgeContext() 38 | { 39 | // session 40 | var session = "-ServerName:MicrosoftEdge"; 41 | 42 | // service 43 | var service = EdgeDriverService.CreateDefaultService(); 44 | service.HideCommandPromptWindow = false; 45 | 46 | // options 47 | var options = new EdgeOptions(); 48 | 49 | // driver 50 | this.Driver = new EdgeDriver(service, options, this.Timeout); 51 | 52 | // process 53 | this.ProcessId = this.GetProcessIdFromSession(session); 54 | } 55 | 56 | protected override bool UpdateViewport(WinElement winElement) 57 | { 58 | this.Viewport = Rectangle.Empty; 59 | if (winElement != null && winElement.MainWindow is WinElement mainWindow 60 | && mainWindow.Class == "ApplicationFrameWindow" 61 | && mainWindow.Children.FirstOrDefault(x => x.Type == "window" && x.Name == "Microsoft Edge" && x.Class == "Windows.UI.Core.CoreWindow") is WinElement target 62 | && target.ProcessId == this.ProcessId) 63 | { 64 | if (target.GetElement(x => x.Class == "Internet Explorer_Server" || x.Class == "NewTabPage") is WinElement viewport) 65 | { 66 | this.Viewport = viewport.Bounds; 67 | return true; 68 | } 69 | } 70 | return false; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Core/SapElement.cs: -------------------------------------------------------------------------------- 1 | // BSD 2-Clause License 2 | 3 | // Copyright(c) 2017, Arvie Delgado 4 | // All rights reserved. 5 | 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are met: 8 | 9 | // * Redistributions of source code must retain the above copyright notice, this 10 | // list of conditions and the following disclaimer. 11 | 12 | // * Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation 14 | // and/or other materials provided with the distribution. 15 | 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | // DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | using System; 28 | using System.Collections.Generic; 29 | using System.Drawing; 30 | 31 | namespace Roro 32 | { 33 | public sealed class SapElement : Element 34 | { 35 | private readonly XObject rawElement; 36 | 37 | internal SapElement(XObject rawElement) 38 | { 39 | this.rawElement = rawElement; 40 | } 41 | 42 | [BotProperty] 43 | public string Id => this.rawElement.Get("Id"); 44 | 45 | [BotProperty] 46 | public string Name => this.rawElement.Get("Name"); 47 | 48 | [BotProperty] 49 | public string Type => (this.rawElement.Get("TypeAsNumber")).ToString().ToLower(); 50 | 51 | [BotProperty] 52 | public override string Path => string.Format("{0}/{1}", this.Parent == null ? string.Empty : this.Parent.Path, this.Type); 53 | 54 | public override Rectangle Bounds => new Rectangle( 55 | this.rawElement.Get("ScreenLeft"), 56 | this.rawElement.Get("ScreenTop"), 57 | this.rawElement.Get("Width"), 58 | this.rawElement.Get("Height")); 59 | 60 | public SapElement Parent => this.rawElement.Get("Parent") is XObject rawParent ? new SapElement(rawParent) : null; 61 | 62 | public IEnumerable Children 63 | { 64 | get 65 | { 66 | var children = new List(); 67 | var rawChildren = this.rawElement.Get("Children"); 68 | foreach (var rawChild in rawChildren) 69 | { 70 | children.Add(new SapElement(rawChild)); 71 | } 72 | return children; 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Roro.Activities.Files/Roro.Activities.Files.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {295EE6C0-64BE-459F-AA05-D4284C8A63F1} 8 | Library 9 | Properties 10 | Roro.Activities.Files 11 | Roro.Activities.Files 12 | v4.6 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | ..\..\bin\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | {bd513e2d-46bc-408e-98e6-d12aee06e7ea} 61 | Roro.Activities 62 | False 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /src/Roro.Activities.SharePoint/Roro.Activities.SharePoint.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {AA652A7F-FE1F-4824-80AC-715BF2A1AB86} 8 | Library 9 | Properties 10 | Roro.Activities.SharePoint 11 | Roro.Activities.SharePoint 12 | v4.6 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | ..\..\bin\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\packages\Microsoft.SharePoint.Client.14.0.4762.1000\lib\Microsoft.SharePoint.Client.dll 35 | 36 | 37 | ..\packages\Microsoft.SharePoint.Client.14.0.4762.1000\lib\Microsoft.SharePoint.Client.Runtime.dll 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | {bd513e2d-46bc-408e-98e6-d12aee06e7ea} 57 | Roro.Activities 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/Roro.Activities.Excel.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {1BA8B7CA-6BCB-434E-B7A8-4268962D35DD} 8 | Library 9 | Properties 10 | Roro.Activities.Excel 11 | Roro.Activities.Excel 12 | v4.6 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | ..\..\bin\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | {bd513e2d-46bc-408e-98e6-d12aee06e7ea} 70 | Roro.Activities 71 | False 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /src/Roro.Activities.Excel/ExcelBot.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace Roro.Activities.Excel 5 | { 6 | internal sealed class ExcelBot : IDisposable 7 | { 8 | private const string EXCEL_PROG_ID = "Excel.Application"; 9 | 10 | private const uint RPC_SERVER_UNAVAILABLE = 0x800706BA; 11 | 12 | public static ExcelBot Shared = new ExcelBot(); 13 | 14 | private dynamic App { get; set; } 15 | 16 | public dynamic GetApp() 17 | { 18 | if (this.App == null) 19 | { 20 | try 21 | { 22 | if (Type.GetTypeFromProgID(EXCEL_PROG_ID) is Type excelType) 23 | { 24 | this.App = Activator.CreateInstance(excelType); 25 | } 26 | else 27 | { 28 | throw new ExcelNotFoundException(); 29 | } 30 | } 31 | catch 32 | { 33 | throw; 34 | } 35 | } 36 | else 37 | { 38 | try 39 | { 40 | var version = this.App.Version; 41 | } 42 | catch 43 | { 44 | this.Dispose(); 45 | return this.GetApp(); 46 | } 47 | } 48 | this.App.Visible = true; 49 | return this.App; 50 | } 51 | 52 | public dynamic GetWorkbookByName(string wbName, bool throwIfNotFound) 53 | { 54 | var xlWb = this.GetApp().Workbooks.Item(wbName); 55 | if (xlWb == null) 56 | { 57 | if (throwIfNotFound) 58 | { 59 | throw new ExcelWorkbookNotFoundException(); 60 | } 61 | else 62 | { 63 | return null; 64 | } 65 | } 66 | xlWb.Activate(); 67 | return xlWb; 68 | } 69 | 70 | public dynamic GetWorksheetByName(string wbName, string wsName, bool throwIfNotFound) 71 | { 72 | var xlWs = this.GetWorkbookByName(wbName, true).Worksheets.Item(wsName); 73 | if (xlWs == null) 74 | { 75 | if (throwIfNotFound) 76 | { 77 | throw new ExcelWorksheetNotFoundException(); 78 | } 79 | else 80 | { 81 | return null; 82 | } 83 | } 84 | xlWs.Activate(); 85 | return xlWs; 86 | } 87 | 88 | public dynamic GetRange(string wbName, string wsName, string rangeAddr) 89 | { 90 | return ExcelBot.Shared.GetWorksheetByName(wbName, wsName, true).Range(rangeAddr); 91 | } 92 | 93 | private ExcelBot() 94 | { 95 | ; 96 | } 97 | 98 | public void Dispose() 99 | { 100 | try 101 | { 102 | this.App.Quit(); 103 | } 104 | catch 105 | { 106 | 107 | } 108 | try 109 | { 110 | Marshal.FinalReleaseComObject(this.App); 111 | } 112 | catch (COMException ex) 113 | { 114 | switch ((uint)ex.ErrorCode) 115 | { 116 | // 117 | case RPC_SERVER_UNAVAILABLE: 118 | break; 119 | 120 | default: 121 | throw; 122 | } 123 | } 124 | 125 | this.App = null; 126 | GC.Collect(); 127 | GC.WaitForPendingFinalizers(); 128 | GC.Collect(); 129 | GC.WaitForPendingFinalizers(); 130 | } 131 | } 132 | 133 | 134 | } 135 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Core/XObject.cs: -------------------------------------------------------------------------------- 1 | // BSD 2-Clause License 2 | 3 | // Copyright(c) 2017, Arvie Delgado 4 | // All rights reserved. 5 | 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are met: 8 | 9 | // * Redistributions of source code must retain the above copyright notice, this 10 | // list of conditions and the following disclaimer. 11 | 12 | // * Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation 14 | // and/or other materials provided with the distribution. 15 | 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | // DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | using System; 28 | using System.Collections; 29 | using System.Collections.Generic; 30 | using System.Reflection; 31 | 32 | namespace Roro 33 | { 34 | internal class XObject : IEnumerable 35 | { 36 | private readonly object item; 37 | 38 | private IList items; 39 | 40 | public int Count => this.Get("Count"); 41 | 42 | public XObject(object obj) 43 | { 44 | if (obj is null) 45 | throw new ArgumentNullException("obj"); 46 | 47 | if (obj.GetType() == this.GetType()) 48 | throw new ArgumentException("The parameter'obj' cannot be an instance of XObject."); 49 | 50 | this.item = obj; 51 | 52 | } 53 | 54 | public XObject Get(string name) 55 | { 56 | if (this.item.GetType().InvokeMember(name, BindingFlags.GetProperty, null, this.item, null) is object result) 57 | { 58 | return new XObject(result); 59 | } 60 | return null; 61 | } 62 | 63 | public T Get(string name) 64 | { 65 | if (this.Get(name) is XObject obj) 66 | { 67 | return (T)obj.item; 68 | } 69 | return default(T); 70 | } 71 | 72 | public void Set(string name, object value) 73 | { 74 | this.item.GetType().InvokeMember(name, BindingFlags.SetProperty, null, this.item, new object[] { value }); 75 | } 76 | 77 | public XObject Invoke(string name, params object[] args) 78 | { 79 | if (this.item.GetType().InvokeMember(name, BindingFlags.InvokeMethod, null, this.item, args) is object result) 80 | { 81 | return new XObject(result); 82 | } 83 | return null; 84 | } 85 | 86 | public T Invoke(string name, params object[] args) 87 | { 88 | if (this.Invoke(name, args) is XObject obj) 89 | { 90 | return (T)obj.item; 91 | } 92 | return default(T); 93 | } 94 | 95 | public IEnumerator GetEnumerator() 96 | { 97 | if (this.items == null) 98 | { 99 | this.items = new List(); 100 | for (int i = 0, c = this.Count; i < c ; i++) 101 | { 102 | this.items.Add(this.Invoke("Item", i)); 103 | } 104 | } 105 | return this.items.GetEnumerator(); 106 | } 107 | 108 | IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator(); 109 | 110 | public override string ToString() => this.item.ToString(); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/Roro.Activities/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/Roro/Roro.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {B9565EB4-FAD3-4B1E-BD5C-CE2D28B23A06} 8 | WinExe 9 | Roro 10 | Roro 11 | v4.6 12 | 512 13 | 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | ..\..\bin\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | Always 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | Form 53 | 54 | 55 | Form1.cs 56 | 57 | 58 | 59 | 60 | Form1.cs 61 | 62 | 63 | ResXFileCodeGenerator 64 | Resources.Designer.cs 65 | Designer 66 | 67 | 68 | True 69 | Resources.resx 70 | True 71 | 72 | 73 | SettingsSingleFileGenerator 74 | Settings.Designer.cs 75 | 76 | 77 | True 78 | Settings.settings 79 | True 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | {bd513e2d-46bc-408e-98e6-d12aee06e7ea} 88 | Roro.Activities 89 | 90 | 91 | 92 | 93 | cd $(SolutionDir) 94 | cd .. 95 | PowerShell -command remove-item "bin\$(TargetName).Release.zip" 96 | PowerShell -command compress-archive -Update -Path "bin\*.exe", "bin\*.dll", "bin\*.winmd", "LICENSE" -DestinationPath "bin\$(TargetName).Release.zip" 97 | 98 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Core/IEContext.cs: -------------------------------------------------------------------------------- 1 | // BSD 2-Clause License 2 | 3 | // Copyright(c) 2017, Arvie Delgado 4 | // All rights reserved. 5 | 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are met: 8 | 9 | // * Redistributions of source code must retain the above copyright notice, this 10 | // list of conditions and the following disclaimer. 11 | 12 | // * Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation 14 | // and/or other materials provided with the distribution. 15 | 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | // DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | using System; 28 | using OpenQA.Selenium.IE; 29 | using Microsoft.Win32; 30 | using System.Drawing; 31 | 32 | namespace Roro 33 | { 34 | public sealed class IEContext : WebContext 35 | { 36 | public IEContext() 37 | { 38 | // session 39 | var session = Guid.NewGuid().ToString(); 40 | 41 | // registry 42 | this.SetupRegistry(); 43 | 44 | // service 45 | var service = InternetExplorerDriverService.CreateDefaultService(); 46 | service.HideCommandPromptWindow = false; 47 | 48 | // options 49 | var options = new InternetExplorerOptions(); 50 | options.InitialBrowserUrl = string.Format("{0}:{1}", WebContext.DefaultUrl, session); 51 | 52 | // driver 53 | this.Driver = new InternetExplorerDriver(service, options, this.Timeout); 54 | 55 | // process 56 | this.ProcessId = this.GetProcessIdFromSession(session); 57 | } 58 | 59 | protected override bool UpdateViewport(WinElement winElement) 60 | { 61 | this.Viewport = Rectangle.Empty; 62 | if (winElement != null && winElement.MainWindow is WinElement target && target.ProcessId == this.ProcessId) 63 | { 64 | if (target.GetElement(x => x.Class == "Internet Explorer_Server" || x.Class == "NewTabWnd") is WinElement viewport) 65 | { 66 | this.Viewport = viewport.Bounds; 67 | return true; 68 | } 69 | } 70 | return false; 71 | } 72 | 73 | private void SetupRegistry() 74 | { 75 | //// ERROR: Unable to get browser 76 | //// REPLICATE: Start driver, navigate manually to other site 77 | Registry.SetValue(@"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BFCACHE", "iexplore.exe", 0, RegistryValueKind.DWord); 78 | 79 | //// ERROR: WebDriverException: Unexpected error launching Internet Explorer. Protected Mode settings are not the same for all zones. Enable Protected Mode must be set to the same value (enabled or disabled) for all zones. 80 | Registry.SetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\0", "2500", 0, RegistryValueKind.DWord); 81 | Registry.SetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1", "2500", 0, RegistryValueKind.DWord); 82 | Registry.SetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2", "2500", 0, RegistryValueKind.DWord); 83 | Registry.SetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3", "2500", 0, RegistryValueKind.DWord); 84 | Registry.SetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4", "2500", 0, RegistryValueKind.DWord); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Input/Input.cs: -------------------------------------------------------------------------------- 1 | // BSD 2-Clause License 2 | 3 | // Copyright(c) 2017, Arvie Delgado 4 | // All rights reserved. 5 | 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are met: 8 | 9 | // * Redistributions of source code must retain the above copyright notice, this 10 | // list of conditions and the following disclaimer. 11 | 12 | // * Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation 14 | // and/or other materials provided with the distribution. 15 | 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | // DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | using System.Collections.Generic; 28 | 29 | namespace Roro 30 | { 31 | public sealed partial class InputDriver 32 | { 33 | public event InputEventHandler OnKeyUp = delegate { }; 34 | 35 | public event InputEventHandler OnKeyDown = delegate { }; 36 | 37 | public event InputEventHandler OnMouseUp = delegate { }; 38 | 39 | public event InputEventHandler OnMouseDown = delegate { }; 40 | 41 | public event InputEventHandler OnMouseMove = delegate { }; 42 | 43 | public event InputEventHandler OnInput = delegate { }; 44 | 45 | public void KeyUp(KeyboardKey key) => SetInputState(new InputEventArgs() { Type = InputEventType.KeyUp, Key = key }); 46 | 47 | public void KeyDown(KeyboardKey key) => SetInputState(new InputEventArgs() { Type = InputEventType.KeyDown, Key = key }); 48 | 49 | public void MouseUp(MouseButton button) => SetInputState(new InputEventArgs() { Type = InputEventType.MouseUp, Button = button }); 50 | 51 | public void MouseDown(MouseButton button) => SetInputState(new InputEventArgs() { Type = InputEventType.MouseDown, Button = button }); 52 | 53 | public void MouseMove(int x, int y) => SetInputState(new InputEventArgs() { Type = InputEventType.MouseMove, X = x, Y = y }); 54 | 55 | public void Click(MouseButton button) 56 | { 57 | this.MouseDown(button); 58 | this.MouseUp(button); 59 | } 60 | 61 | public void Press(params KeyboardKey[] keys) 62 | { 63 | var modKeys = new Dictionary 64 | { 65 | { KeyboardKey.LeftAlt, false }, 66 | { KeyboardKey.LeftCtrl, false }, 67 | { KeyboardKey.LeftShift, false }, 68 | { KeyboardKey.LeftWin, false }, 69 | { KeyboardKey.RightAlt, false }, 70 | { KeyboardKey.RightCtrl, false }, 71 | { KeyboardKey.RightShift, false }, 72 | { KeyboardKey.RightWin, false } 73 | }; 74 | foreach (KeyboardKey key in keys) 75 | { 76 | this.KeyDown(key); 77 | if (modKeys.ContainsKey(key)) 78 | { 79 | modKeys[key] = true; 80 | } 81 | else 82 | { 83 | this.KeyUp(key); 84 | } 85 | } 86 | foreach (KeyboardKey key in modKeys.Keys) 87 | { 88 | if (modKeys[key] == true) 89 | { 90 | this.KeyUp(key); 91 | } 92 | } 93 | } 94 | 95 | public void Write(string text) 96 | { 97 | foreach (char c in text ?? string.Empty) 98 | { 99 | this.KeyDown((KeyboardKey)(-c)); 100 | this.KeyUp((KeyboardKey)(-c)); 101 | } 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Roro.Activities.Apps.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {DB4188B9-7008-4FB9-BC27-6BCA69482801} 8 | Library 9 | Properties 10 | Roro.Activities.Apps 11 | Roro.Activities.Apps 12 | v4.6 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | ..\..\bin\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | AnyCPU 25 | latest 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | latest 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | {bd513e2d-46bc-408e-98e6-d12aee06e7ea} 59 | Roro.Activities 60 | False 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | Form 76 | 77 | 78 | Form 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | ElementHighlighterForm.cs 99 | 100 | 101 | ElementPickerForm.cs 102 | 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /src/Roro.Activities.Cognitive/Roro.Activities.Cognitive.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {F4558562-7292-4521-AA1D-3D090B070B92} 8 | Library 9 | Properties 10 | Roro.Activities.Cognitive 11 | Roro.Activities.Cognitive 12 | v4.6 13 | 10.0 14 | 512 15 | 16 | 17 | 18 | 19 | 20 | true 21 | full 22 | false 23 | ..\..\bin\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | ..\packages\Costura.Fody.1.6.2\lib\dotnet\Costura.dll 39 | False 40 | 41 | 42 | 43 | 44 | 45 | False 46 | ..\..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\System.Runtime.WindowsRuntime.dll 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | ..\..\..\..\..\..\..\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.16299.0\Windows.winmd 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | {bd513e2d-46bc-408e-98e6-d12aee06e7ea} 69 | Roro.Activities 70 | False 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /src/Roro.Activities.Apps/Core/SapContext.cs: -------------------------------------------------------------------------------- 1 | // BSD 2-Clause License 2 | 3 | // Copyright(c) 2017, Arvie Delgado 4 | // All rights reserved. 5 | 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are met: 8 | 9 | // * Redistributions of source code must retain the above copyright notice, this 10 | // list of conditions and the following disclaimer. 11 | 12 | // * Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation 14 | // and/or other materials provided with the distribution. 15 | 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | // DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | using System; 28 | using System.Collections.Generic; 29 | using System.Diagnostics; 30 | using System.Linq; 31 | 32 | namespace Roro 33 | { 34 | public sealed class SapContext : Context 35 | { 36 | private XObject appObject; 37 | 38 | public static readonly SapContext Shared = new SapContext(); 39 | 40 | private SapContext() 41 | { 42 | this.IsAlive(); 43 | } 44 | 45 | public override Element GetElementFromPoint(int screenX, int screenY) => 46 | this.IsAlive() 47 | && this.appObject.Get("ActiveSession") is XObject session 48 | && session.Invoke("FindByPosition", screenX, screenY, false) is XObject rawElementInfo 49 | && rawElementInfo.Invoke("Item", 0) is string rawElementId 50 | && session.Invoke("FindById", rawElementId, false) is XObject rawElement 51 | ? new SapElement(rawElement) : null; 52 | 53 | public override IEnumerable GetElementsFromQuery(Query query) 54 | { 55 | var result = new List(); 56 | var candidates = new Queue(); 57 | var targetPath = query.First(x => x.Name == "Path").Value.ToString(); 58 | 59 | if (!this.IsAlive()) 60 | { 61 | return result; 62 | } 63 | 64 | foreach (var connection in this.appObject.Get("Connections")) 65 | { 66 | foreach (var session in connection.Get("Sessions")) 67 | { 68 | candidates.Enqueue(new SapElement(session)); 69 | } 70 | } 71 | 72 | while (candidates.Count > 0) 73 | { 74 | var candidate = candidates.Dequeue(); 75 | var candidatePath = candidate.Path; 76 | if (targetPath.StartsWith(candidatePath)) 77 | { 78 | if (targetPath.Equals(candidatePath)) 79 | { 80 | if (candidate.TryQuery(query)) 81 | { 82 | result.Add(candidate); 83 | } 84 | } 85 | else 86 | { 87 | foreach (var child in candidate.Children) 88 | { 89 | candidates.Enqueue(child); 90 | } 91 | } 92 | } 93 | } 94 | return result; 95 | } 96 | 97 | 98 | private bool IsAlive() 99 | { 100 | if (this.ProcessId > 0 && Process.GetProcessById(this.ProcessId) is Process proc) 101 | { 102 | return true; 103 | } 104 | 105 | if (Type.GetTypeFromProgID("SapROTWr.SapROTWrapper") is Type type 106 | && new XObject(Activator.CreateInstance(type)) is XObject ROTWrapper 107 | && ROTWrapper.Invoke("GetROTEntry", "SAPGUI") is XObject ROTEntry 108 | && ROTEntry.Invoke("GetScriptingEngine") is XObject appObject 109 | && Process.GetProcessesByName("saplogon").FirstOrDefault() is Process saplogon) 110 | { 111 | this.appObject = appObject; 112 | this.ProcessId = saplogon.Id; 113 | return true; 114 | } 115 | else 116 | { 117 | this.appObject = null; 118 | this.ProcessId = 0; 119 | return false; 120 | } 121 | } 122 | } 123 | } --------------------------------------------------------------------------------