mirror of
https://github.com/gnh1201/welsonjs.git
synced 2025-03-12 00:45:14 +00:00
Some works for #124
This commit is contained in:
parent
b5af648512
commit
f73b180329
|
@ -1,51 +1,85 @@
|
||||||
// this is prototype code
|
/*
|
||||||
// https://github.com/gnh1201/welsonjs
|
* WelsonJS.Service
|
||||||
|
*
|
||||||
|
* filename:
|
||||||
|
* ScreenTimer.cs
|
||||||
|
*
|
||||||
|
* description:
|
||||||
|
* WelsonJS - Build a Windows app on the Windows built-in JavaScript engine
|
||||||
|
*
|
||||||
|
* website:
|
||||||
|
* - https://github.com/gnh1201/welsonjs
|
||||||
|
* - https://catswords.social/@catswords_oss
|
||||||
|
* - https://teams.live.com/l/community/FEACHncAhq8ldnojAI
|
||||||
|
*
|
||||||
|
* author:
|
||||||
|
* Namhyeon Go <abuse@catswords.net>
|
||||||
|
*
|
||||||
|
* license:
|
||||||
|
* GPLv3 or MS-RL(Microsoft Reciprocal License)
|
||||||
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.ServiceProcess;
|
||||||
|
using System.Timers;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using WelsonJS.Service;
|
using WelsonJS.Service;
|
||||||
|
|
||||||
public class TemplateMatching
|
public class ScreenTimer : System.Timers.Timer
|
||||||
{
|
{
|
||||||
public void Test(string workingDirectory)
|
private static List<Bitmap> templateImages = new List<Bitmap>();
|
||||||
|
private string templateDirectory;
|
||||||
|
|
||||||
|
public string WorkingDirectory { get; set; }
|
||||||
|
public ServiceBase Parent { get; set; }
|
||||||
|
|
||||||
|
public class MatchedResult
|
||||||
{
|
{
|
||||||
string templateFolderPath = Path.Combine(workingDirectory, "assets/img/templates");
|
public string FileName;
|
||||||
|
public int ScreenNumber;
|
||||||
|
public Point Location;
|
||||||
|
public double MaxCorrelation;
|
||||||
|
}
|
||||||
|
|
||||||
// Load all template images
|
public ScreenTimer()
|
||||||
List<Bitmap> templateImages = LoadTemplateImages(templateFolderPath);
|
{
|
||||||
|
Elapsed += OnTimeElapsed;
|
||||||
|
|
||||||
// try template matching
|
templateDirectory = Path.Combine(WorkingDirectory, "assets/img/templates");
|
||||||
List<(string FileName, int ScreenNumber, Point Location, double MaxCorrelation)> results =
|
LoadTemplateImages();
|
||||||
CaptureAndMatchAllScreens(templateImages);
|
}
|
||||||
|
|
||||||
// print results
|
private void OnTimeElapsed(object sender, ElapsedEventArgs e)
|
||||||
foreach (var result in results)
|
{
|
||||||
|
List<MatchedResult> matchedResults = CaptureAndMatchAllScreens();
|
||||||
|
|
||||||
|
ServiceMain svc = (ServiceMain)Parent;
|
||||||
|
matchedResults.ForEach(result =>
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Template: {result.FileName}, Screen: {result.ScreenNumber}, " +
|
svc.Log(svc.DispatchServiceEvent("screenTime", new object[] {
|
||||||
$"Location: (x: {result.Location.X}, y: {result.Location.Y}), " +
|
result.FileName,
|
||||||
$"Max Correlation: {result.MaxCorrelation}");
|
result.ScreenNumber,
|
||||||
|
result.Location.X,
|
||||||
|
result.Location.Y,
|
||||||
|
result.MaxCorrelation
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadTemplateImages()
|
||||||
|
{
|
||||||
|
string[] imageFiles = Directory.GetFiles(templateDirectory, "*.png");
|
||||||
|
foreach (string file in imageFiles)
|
||||||
|
{
|
||||||
|
templateImages.Add(new Bitmap(file));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Bitmap> LoadTemplateImages(string folderPath)
|
public List<MatchedResult> CaptureAndMatchAllScreens()
|
||||||
{
|
{
|
||||||
var templates = new List<Bitmap>();
|
var results = new List<MatchedResult>();
|
||||||
var files = Directory.GetFiles(folderPath, "*.png");
|
|
||||||
|
|
||||||
foreach (var file in files)
|
|
||||||
{
|
|
||||||
templates.Add(new Bitmap(file));
|
|
||||||
}
|
|
||||||
|
|
||||||
return templates;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<(string FileName, int ScreenNumber, Point Location, double MaxCorrelation)>
|
|
||||||
CaptureAndMatchAllScreens(List<Bitmap> templateImages)
|
|
||||||
{
|
|
||||||
var results = new List<(string FileName, int ScreenNumber, Point Location, double MaxCorrelation)>();
|
|
||||||
|
|
||||||
for (int i = 0; i < Screen.AllScreens.Length; i++)
|
for (int i = 0; i < Screen.AllScreens.Length; i++)
|
||||||
{
|
{
|
||||||
|
@ -57,14 +91,20 @@ public class TemplateMatching
|
||||||
Point matchLocation = FindTemplate(mainImage, templateImage, out double maxCorrelation);
|
Point matchLocation = FindTemplate(mainImage, templateImage, out double maxCorrelation);
|
||||||
string templateFileName = templateImage.Tag as string;
|
string templateFileName = templateImage.Tag as string;
|
||||||
|
|
||||||
results.Add((templateFileName, i, matchLocation, maxCorrelation));
|
results.Add(new MatchedResult
|
||||||
|
{
|
||||||
|
FileName = templateFileName,
|
||||||
|
ScreenNumber = i,
|
||||||
|
Location = matchLocation,
|
||||||
|
MaxCorrelation = maxCorrelation
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bitmap CaptureScreen(Screen screen)
|
public Bitmap CaptureScreen(Screen screen)
|
||||||
{
|
{
|
||||||
Rectangle screenSize = screen.Bounds;
|
Rectangle screenSize = screen.Bounds;
|
||||||
Bitmap bitmap = new Bitmap(screenSize.Width, screenSize.Height);
|
Bitmap bitmap = new Bitmap(screenSize.Width, screenSize.Height);
|
||||||
|
@ -77,7 +117,7 @@ public class TemplateMatching
|
||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Point FindTemplate(Bitmap mainImage, Bitmap templateImage, out double maxCorrelation)
|
public Point FindTemplate(Bitmap mainImage, Bitmap templateImage, out double maxCorrelation)
|
||||||
{
|
{
|
||||||
int mainWidth = mainImage.Width;
|
int mainWidth = mainImage.Width;
|
||||||
int mainHeight = mainImage.Height;
|
int mainHeight = mainImage.Height;
|
||||||
|
@ -103,7 +143,7 @@ public class TemplateMatching
|
||||||
return bestMatch;
|
return bestMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double CalculateCorrelation(Bitmap mainImage, Bitmap templateImage, int offsetX, int offsetY)
|
private double CalculateCorrelation(Bitmap mainImage, Bitmap templateImage, int offsetX, int offsetY)
|
||||||
{
|
{
|
||||||
int templateWidth = templateImage.Width;
|
int templateWidth = templateImage.Width;
|
||||||
int templateHeight = templateImage.Height;
|
int templateHeight = templateImage.Height;
|
|
@ -35,6 +35,7 @@ namespace WelsonJS.Service
|
||||||
private static List<Timer> timers;
|
private static List<Timer> timers;
|
||||||
private string workingDirectory;
|
private string workingDirectory;
|
||||||
private string scriptName;
|
private string scriptName;
|
||||||
|
private bool disabledScreenTimer = false;
|
||||||
private string scriptFilePath;
|
private string scriptFilePath;
|
||||||
private string scriptText;
|
private string scriptText;
|
||||||
private ScriptControl scriptControl;
|
private ScriptControl scriptControl;
|
||||||
|
@ -52,12 +53,23 @@ namespace WelsonJS.Service
|
||||||
timers = new List<Timer>();
|
timers = new List<Timer>();
|
||||||
|
|
||||||
// set default timer
|
// set default timer
|
||||||
Timer timer = new Timer
|
Timer defaultTimer = new Timer
|
||||||
{
|
{
|
||||||
Interval = 60000 // 1 minute
|
Interval = 60000 // 1 minute
|
||||||
};
|
};
|
||||||
timer.Elapsed += OnElapsedTime;
|
defaultTimer.Elapsed += OnElapsedTime;
|
||||||
timers.Add(timer);
|
timers.Add(defaultTimer);
|
||||||
|
|
||||||
|
// set screen timer
|
||||||
|
if (!disabledScreenTimer)
|
||||||
|
{
|
||||||
|
timers.Add(new ScreenTimer
|
||||||
|
{
|
||||||
|
Parent = this,
|
||||||
|
WorkingDirectory = workingDirectory,
|
||||||
|
Interval = 1000 // 1 second
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void TestStartupAndStop(string[] args)
|
internal void TestStartupAndStop(string[] args)
|
||||||
|
@ -82,6 +94,10 @@ namespace WelsonJS.Service
|
||||||
case "script-name":
|
case "script-name":
|
||||||
scriptName = entry.Value;
|
scriptName = entry.Value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "--disable-screen-timer":
|
||||||
|
disabledScreenTimer = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +143,7 @@ namespace WelsonJS.Service
|
||||||
scriptControl.AddCode(scriptText);
|
scriptControl.AddCode(scriptText);
|
||||||
|
|
||||||
// initialize
|
// initialize
|
||||||
Log(DispatchServiceEvent(scriptName, "start"));
|
Log(DispatchServiceEvent("start"));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -152,7 +168,7 @@ namespace WelsonJS.Service
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Log(DispatchServiceEvent(scriptName, "stop"));
|
Log(DispatchServiceEvent("stop"));
|
||||||
scriptControl?.Reset();
|
scriptControl?.Reset();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -168,7 +184,7 @@ namespace WelsonJS.Service
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Log(DispatchServiceEvent(scriptName, "elapsedTime"));
|
Log(DispatchServiceEvent("elapsedTime"));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -176,11 +192,6 @@ namespace WelsonJS.Service
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string DispatchServiceEvent(string name, string eventType)
|
|
||||||
{
|
|
||||||
return InvokeScriptMethod("dispatchServiceEvent", name, eventType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private string InvokeScriptMethod(string methodName, params object[] parameters)
|
private string InvokeScriptMethod(string methodName, params object[] parameters)
|
||||||
{
|
{
|
||||||
if (scriptControl != null)
|
if (scriptControl != null)
|
||||||
|
@ -195,15 +206,6 @@ namespace WelsonJS.Service
|
||||||
return "void";
|
return "void";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void Log(string message)
|
|
||||||
{
|
|
||||||
using (StreamWriter writer = new StreamWriter(logFilePath, true))
|
|
||||||
{
|
|
||||||
writer.WriteLine($"{DateTime.Now}: {message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Dictionary<string, string> ParseArguments(string[] args)
|
private Dictionary<string, string> ParseArguments(string[] args)
|
||||||
{
|
{
|
||||||
var arguments = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
var arguments = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
@ -219,12 +221,30 @@ namespace WelsonJS.Service
|
||||||
var value = arg.Substring(index + 1);
|
var value = arg.Substring(index + 1);
|
||||||
arguments[key] = value;
|
arguments[key] = value;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var key = arg.Substring(2);
|
||||||
|
arguments[key] = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Log(string message)
|
||||||
|
{
|
||||||
|
using (StreamWriter writer = new StreamWriter(logFilePath, true))
|
||||||
|
{
|
||||||
|
writer.WriteLine($"{DateTime.Now}: {message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string DispatchServiceEvent(string eventType, object[] args = null)
|
||||||
|
{
|
||||||
|
return InvokeScriptMethod("dispatchServiceEvent", scriptName, eventType, args);
|
||||||
|
}
|
||||||
|
|
||||||
public string GetWorkingDirectory()
|
public string GetWorkingDirectory()
|
||||||
{
|
{
|
||||||
return workingDirectory;
|
return workingDirectory;
|
||||||
|
|
|
@ -90,6 +90,9 @@
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="ScreenTimer.cs">
|
||||||
|
<SubType>Component</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Include="ServiceMain.cs">
|
<Compile Include="ServiceMain.cs">
|
||||||
<SubType>Component</SubType>
|
<SubType>Component</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -104,7 +107,6 @@
|
||||||
<DependentUpon>ProjectInstaller.cs</DependentUpon>
|
<DependentUpon>ProjectInstaller.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="TemplateMatching.cs" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<COMReference Include="MSScriptControl">
|
<COMReference Include="MSScriptControl">
|
||||||
|
|
10
app.js
10
app.js
|
@ -589,7 +589,7 @@ function initializeWindow(name, args, w, h) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function dispatchServiceEvent(name, eventType) {
|
function dispatchServiceEvent(name, eventType, args) {
|
||||||
var app = require(name);
|
var app = require(name);
|
||||||
|
|
||||||
// load the service
|
// load the service
|
||||||
|
@ -597,8 +597,9 @@ function dispatchServiceEvent(name, eventType) {
|
||||||
return (function(action) {
|
return (function(action) {
|
||||||
if (eventType in action) {
|
if (eventType in action) {
|
||||||
try {
|
try {
|
||||||
var f = action[eventType];
|
return (function(f) {
|
||||||
if (typeof f === "function") return f();
|
return (typeof f !== "function" ? null : f(args));
|
||||||
|
})(action[eventType]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Exception:", e.message);
|
console.error("Exception:", e.message);
|
||||||
}
|
}
|
||||||
|
@ -606,7 +607,8 @@ function dispatchServiceEvent(name, eventType) {
|
||||||
})({
|
})({
|
||||||
start: app.onServiceStart,
|
start: app.onServiceStart,
|
||||||
stop: app.onServiceStop,
|
stop: app.onServiceStop,
|
||||||
elapsedTime: app.onServiceElapsedTime
|
elapsedTime: app.onServiceElapsedTime,
|
||||||
|
screenTime: app.onServiceScreenTime
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.error("Could not find", name + ".js");
|
console.error("Could not find", name + ".js");
|
||||||
|
|
Loading…
Reference in New Issue
Block a user