It is currently April 18th, 2024, 11:28 pm

How can I set a variable with a measure's value?

Get help with creating, editing & fixing problems with skins
User avatar
Yincognito
Rainmeter Sage
Posts: 7125
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: How can I set a variable with a measure's value?

Post by Yincognito »

teiji wrote: May 11th, 2023, 10:21 pmI'll turn it into a full fledged skin and share with the community as Yincognito suggested.
Take your time to make it right, no rush. ;-)

In the meantime, I found this approach, corrected a few typos, tested it, and it works well. Was thinking that it could be implemented with the help of a RunCommand measure to get the (hopefully, STDOUT) output in real time for display in a Rainmeter skin and avoid always saving things on the slower drive, but there's one drawback to it: CMD must be run as administrator to get all the goodies. There are ways to do it, of course, but not too convenient / comfortable... :???:

Anyway, it would be nice to have the ability to see whatever errors might register in the Event Viewer right when they happen, because while the latter does provide the time when the error happened, nobody stays with his eyes on the clock or remember what he was doing at the time of the error. It could be a valuable debugging tool.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
teiji
Posts: 27
Joined: April 9th, 2021, 5:15 pm

Re: How can I set a variable with a measure's value?

Post by teiji »

Monitoring the Event Viewer in real time and without writing data to a file constantly (prolonging SSD life) is definitely the way to go. Maybe you'd like to take a shot at this problem and come up with a much more elegant skin/solution than me. You're a sage after all. :D
User avatar
Yincognito
Rainmeter Sage
Posts: 7125
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: How can I set a variable with a measure's value?

Post by Yincognito »

teiji wrote: May 11th, 2023, 11:21 pm Monitoring the Event Viewer in real time and without writing data to a file constantly (prolonging SSD life) is definitely the way to go. Maybe you'd like to take a shot at this problem and come up with a much more elegant skin/solution than me. You're a sage after all. :D
Well, that's not a bad idea. Trying to avoid running stuff as adminstrator is for now the main disadvantage (at least in the CScript implementation I linked to, since PowerShell could probably be run like this with minimal difficulty, though it would be heavier on resources, I think). I just posted a feature suggestion here in case it's easier to do it from within Rainmeter and in a plugin, let's see if anyone responds.

If not, I might consider tackling this as a skin. The key points are the administrator thingy and checking if the output is to STDOUT and RunCommand can capture it properly - if the answer to both points is a positive thing, then all it would take is setting the filter through some parameters passed to the script. I can't promise anything, but maybe I'll take a closer look at this these days... :???:

P.S. Of course, that shouldn't stop you from investigating the matter yourself too. I might be a "sage" and all (spoiler: it might be overrated :sly: ), but you never know from which direction a good idea or thought can pop up. ;-)
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
balala
Rainmeter Sage
Posts: 16144
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: How can I set a variable with a measure's value?

Post by balala »

teiji wrote: May 11th, 2023, 10:21 pm Thank you so much. It does work! I learned a lot from the errors you mentioned.
Great! And I'm glad.
teiji wrote: May 11th, 2023, 10:21 pm I see one problem still remain though. Currently I hardcoded the first event from the log to the match condition to ensure it will always match on the first run to set the var1 correctly:

Code: Select all

IfMatch=05/10/2023 10:31
But if the log.txt doesn't have that time, then the skin breaks down because this will never be true:

Code: Select all

IfMatch=05/10/2023 10:31
IfMatchAction=[!SetVariable var1 "[MeasureLog]"]
I doubt it breaks down. The measure not having the value used in the IfMatch option, the IfMatchAction is not executed. But the skin shouldn't break down by this.
However I'm not sure what exactly is you question (if you have any). I see what you did, but do you have any question related to this? Because you didn't ask anything.
teiji
Posts: 27
Joined: April 9th, 2021, 5:15 pm

Re: How can I set a variable with a measure's value?

Post by teiji »

Haha sorry, it was a bit of an exaggeration. I originally had a question on how to remove the hardcoded time, but I figured it out as you can see from my edit.
User avatar
balala
Rainmeter Sage
Posts: 16144
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: How can I set a variable with a measure's value?

Post by balala »

teiji wrote: May 12th, 2023, 4:40 pm but I figured it out as you can see from my edit.
Alright.
User avatar
Yincognito
Rainmeter Sage
Posts: 7125
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: How can I set a variable with a measure's value?

Post by Yincognito »

teiji wrote: May 11th, 2023, 11:21 pm Monitoring the Event Viewer in real time and without writing data to a file constantly (prolonging SSD life) is definitely the way to go. Maybe you'd like to take a shot at this problem and come up with a much more elegant skin/solution than me. You're a sage after all. :D
Well, it's not that close to real time mainly because the RunCommand plugin, which grabs the STDOUT contents from whatever program is executed at the command line, does not capture the output until the program terminates, but this can write test events on demand (the Set Event "button"), and read them (the Get Event "button") on demand and / or once every 10 seconds (adjustable from the Interval value in [Variables])...

Skin:
Event Log Monitor_1.0.0.rmskin
Code:

Code: Select all

[Variables]
; Alternate Program and Parameter options for the SetEvent | GetEvent measures:
; - cscript    set works without any drawback
; - cscript    get works but can't be captured by RunCommand until the endless loop terminates and needs to be run as administrator
; - powershell set works without any drawback
; - powershell get works but can't be captured by RunCommand until the endless loop terminates
setprg0=CScript
setarg0=""#@#Event Log Test.vbs""
getprg0=CScript
getarg0=""#@#Event Log Monitor.vbs""
setprg1=powershell
setarg1=-command Write-EventLog -LogName 'Application' -Source 'WSH' -EventID 0 -EntryType Information -Message 'Event written to an event log using a script.'
getprg1=powershell
getarg1=-command While ($True) {Try {Get-WinEvent -FilterHashtable @{LogName='Application'; ProviderName='WSH'; ID='0'; StartTime=(Get-Date).AddMilliseconds(-1000)} -MaxEvents 1 -ErrorAction Stop} catch {}; Start-Sleep -Milliseconds 1000;}

; Height of the scrolled text container
ScrollH=600
; Vertical position of the scrolled text
ScrollY=0
; Scrolling step or speed in pixels
ScrollN=25
; Event get or retrieval interval in seconds
Interval=10

[Rainmeter]
Update=1000
AccurateText=1
DynamicWindowSize=1

---Measures---

[SetEvent]
Measure=Plugin
Plugin=RunCommand
Program=eventcreate
Parameter=/t Information /id 1 /l Application /d "Test event"
State=Hide
OutputType=ANSI

[GetEvent]
Measure=Plugin
Plugin=RunCommand
Program=wevtutil
Parameter=qe Application /c:10 /rd:true /f:text /q:"Event[*[(EventID=1)]]"
State=Hide
OutputType=ANSI

[Trigger]
Measure=Calc
UpdateDivider=#Interval#
OnUpdateAction=[!CommandMeasure GetEvent "Run"]

---Meters---

[SetEventButton]
Meter=String
X=150
W=300
H=30
SolidColor=255,0,0,128
FontColor=255,255,255,255
FontSize=16
StringAlign=Center
AntiAlias=1
Text=Set Event
LeftMouseUpAction=[!CommandMeasure SetEvent "Run"]

[GetEventButton]
Meter=String
X=450
W=300
H=30
SolidColor=0,255,0,128
FontColor=255,255,255,255
FontSize=16
StringAlign=Center
AntiAlias=1
Text=Get Event
LeftMouseUpAction=[!CommandMeasure GetEvent "Run"]

[GListContainer]
Meter=Image
Y=30
W=600
H=#ScrollH#
SolidColor=0,0,0,255
MouseScrollUpAction=[!SetVariable ScrollY (Clamp(#ScrollY#+#ScrollN#,[GListContainer:H]-[GetEventListed:H],0))][!UpdateMeter *][!Redraw]
MouseScrollDownAction=[!SetVariable ScrollY (Clamp(#ScrollY#-#ScrollN#,[GListContainer:H]-[GetEventListed:H],0))][!UpdateMeter *][!Redraw]
DynamicVariables=1

[GetEventListed]
Container=GListContainer
Meter=String
Y=#ScrollY#
W=600
SolidColor=0,0,0,128
FontColor=255,255,255,255
FontSize=16
ClipString=2
AntiAlias=1
MeasureName=GetEvent
Text=%1
DynamicVariables=1
Preview:
Event Log Monitor.jpg
I left the .ps1 script from your skin in resources as a reference, added two (unfeasible) alternatives for the same reason (see the comments), used some values as variables for easier adjustment, and made the event list scrollable for conveniency. Typically, the list should be populated already since it appears that Windows Security Center also writes an event with the ID = 1 when starting, but any time afterwards you can use Set Event to write a test event to the log and either use Get Event or see how the list gets updated once every 10 seconds with the newly added event.

This works without writing to any file (other than the usual log operations in Windows) and has a reasonably short update time. I chose to use eventcreate and wevtutil to do the operations even though they're not exactly the best options being made a bit restrictive by MS, since they are very fast command line tools specifically for this purpose. Additional help on those can be found online.

Feel free to play with the skin / code and modify / parameterize it as you like. I might add a similar skin to my suite in the future, certainly if I add a similar network monitoring one, but I'll have to think about it.
You do not have the required permissions to view the files attached to this post.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth