It is currently November 22nd, 2019, 1:55 pm

Measure Registry Multi-String?

Help with creating, editing & fixing problems with skins
Yincognito
Posts: 682
Joined: February 27th, 2015, 2:38 pm

Re: Measure Registry Multi-String?

Yincognito » March 23rd, 2019, 3:25 am

SilverAzide wrote:
March 23rd, 2019, 2:45 am
Yes.. what we don't know (maybe you've already tried it and do know) is whether Rainmeter (or, more specifically, the Win32 API Rainmeter uses) will read the registry entry up to the first null and stop, or will it read in the entire buffer into memory, nulls and all. If the latter, then you won't be able to see the strings after the first null, but they will be there and could be made available with a substitute to get rid of embedded nulls.
Well, if it was the latter, then REG_MULTI_SZ should have been already in the list of supported key value types, from a logical point of view. The fact that it isn't (yet) supported makes me believe it's the former possibility. After a quick look at this, this and this, it seems that the null character is indeed used as a string terminator - correct me if I'm wrong. The nullptr keyword and the _wcsicmp functions there seem to indicate that the NULL character/pointer is used to detect where the string taken from the registry ends.
SilverAzide wrote:
March 23rd, 2019, 2:45 am
Either way, you CAN read a REG_MULTI_SZ registry entry using Rainmeter. It requires Powershell and a little command-line kung fu, but you could easily do it with a Command measure. One example:

Code: Select all

PS> Get-ItemProperty -Path "HKCU:\Software\Binary Fortress Software\DisplayFusion\Wallpaper\c01c88eb-b1af-446a-ba4c-d714a2c45fdd" | Select-Object -ExpandProperty Wallpaper_0_RotatePaths
That will dump out a list of strings you could then grab and parse however you like. With a little creativity, you can probably alternatively format the text as a single string joined together with a separator of your choice (e.g., "string1;string2;string3")
Yep, I know. Having a native Rainmeter measure to get that though saves both resources and potential inconvenient things happening along the way. I'm also currently getting the names, sizes and usages of all the pagefiles using a similar gwmi based RunCommand/Powershell method, but given a native Rainmeter alternative I would choose the latter in a heartbeat. It would be faster, safer and, well, simpler.

EDIT: If I'm not mistaken, it was you who pointed me in the right direction with that pagefile gwmi method - many thanks, by the way... :thumbup: All I'm saying is that I would only use RunCommand/PS methods only when there are no other alternatives available.
EDIT2: Yes, I've already tried regex substituting to clear up nulls using all the available regex methods, and had no success.
User avatar
balala
Rainmeter Sage
Posts: 9117
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Measure Registry Multi-String?

balala » March 23rd, 2019, 7:13 am

SilverAzide wrote:
March 22nd, 2019, 10:33 pm
However, I'm not sure what the original poster is trying to do; his question was how to get all the values. By using a substitute to remove the separator, all you will end up doing is concatenating the individual strings together, which will render it useless. If the goal is to do something with the individual strings, then another approach is needed.
Apart from the above discussion, if the registry value can be read, there is no more problem what to do with it. If we have it, the new line can be replaced with something (like a |), then some String measures can be used to get the different paths returned by the Registry measure.
There are two problems here, in my opinion:
  • Can be got the needed registry key (the above discussion, related to the data type)?
  • If we got it, what the new line character is, to can replace it with something else (like described above)?
If we succeeded reading the registry key, we have to add the following two options to the Registry measure used to read it:

Code: Select all

RegExpSubstitute=1
Substitute="\0":"|"
(or obviously the above used \0 must be replaced with the appropriate characters).
This measure will return the two paths separated with a |.
Now two String measures are needed to get distinctly the two paths. Something like this:

Code: Select all

[MeasurePath1]
Measure=String
String=[MeasureRegistry]
RegExpSubstitute=1
Substitute="^(.*)\|(.*)$":"\1"
DynamicVariables=1

[MeasurePath2]
Measure=String
String=[MeasureRegistry]
RegExpSubstitute=1
Substitute="^(.*)\|(.*)$":"\2"
DynamicVariables=1
Obviously [MeasurePath1] returns the first path, while [MeasurePath2] returns the second one.
User avatar
StArL0rd84
Posts: 336
Joined: February 8th, 2015, 10:07 pm
Location: EU, Denmark.

Re: Measure Registry Multi-String?

StArL0rd84 » March 23rd, 2019, 7:41 am

Tested Substitute="\0":"|" today and i'm afraid it does not work either.
Still only returns the first string.

I have never used Powershell together with Rainmeter before.
How do i format the measure?
The following measure only returns the number 103...

Code: Select all

[mMultiString]
Measure=Plugin
Plugin=RunCommand
Program=PS> Get-ItemProperty 
Parameter=-Path "HKCU:\Software\Binary Fortress Software\DisplayFusion\Wallpaper\c01c88eb-b1af-446a-ba4c-d714a2c45fdd" | Select-Object -ExpandProperty Wallpaper_0_RotatePaths
DynamicVariables=1
(#WorkTime# = 1 ? #Work# : ([mEnergyLoss:%] > 100 ? #SleepMode# : #Rainmeter#))
User avatar
balala
Rainmeter Sage
Posts: 9117
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Measure Registry Multi-String?

balala » March 23rd, 2019, 10:45 am

StArL0rd84 wrote:
March 23rd, 2019, 7:41 am
Tested Substitute="\0":"|" today and i'm afraid it does not work either.
Still only returns the first string.
Could you please post the whole code?
User avatar
StArL0rd84
Posts: 336
Joined: February 8th, 2015, 10:07 pm
Location: EU, Denmark.

Re: Measure Registry Multi-String?

StArL0rd84 » March 23rd, 2019, 11:43 am

balala wrote:
March 23rd, 2019, 10:45 am
Could you please post the whole code?
I can post the whole code if you want, but everything else is a mess right now and would probably only confuse you.
But i can post the measure that's supposed to substitute the NUL and return the multi string.

Code: Select all

[mWallpaperShortPath0]
Measure=Registry
RegHKey=HKEY_CURRENT_USER
RegKey=Software\Binary Fortress Software\DisplayFusion\Wallpaper\c01c88eb-b1af-446a-ba4c-d714a2c45fdd
RegValue=Wallpaper_0_RotatePaths
UpdateDivider=5
RegExpSubstitute=1
Substitute="\0":"|"
Last edited by balala on March 23rd, 2019, 12:40 pm, edited 1 time in total.
Reason: Please use <code> tags whenever are you posting code snippets. It's the <> button.
(#WorkTime# = 1 ? #Work# : ([mEnergyLoss:%] > 100 ? #SleepMode# : #Rainmeter#))
User avatar
balala
Rainmeter Sage
Posts: 9117
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Measure Registry Multi-String?

balala » March 23rd, 2019, 12:45 pm

StArL0rd84 wrote:
March 23rd, 2019, 11:43 am
I can post the whole code if you want, but everything else is a mess right now and would probably only confuse you.
But i can post the measure that's supposed to substitute the NUL and return the multi string.

Code: Select all

[mWallpaperShortPath0]
Measure=Registry
RegHKey=HKEY_CURRENT_USER
RegKey=Software\Binary Fortress Software\DisplayFusion\Wallpaper\c01c88eb-b1af-446a-ba4c-d714a2c45fdd
RegValue=Wallpaper_0_RotatePaths
UpdateDivider=5
RegExpSubstitute=1
Substitute="\0":"|"
And what does return this measure as it is? Add a String meter, to see the result and add a LeftMouseUpAction option to the meter, to copy to clipboard what the measure have returned. Post it here, please.

Code: Select all

[MeterPath]
Meter=STRING
MeasureName=mWallpaperShortPath0
X=0
Y=0
Padding=15,5,15,5
FontColor=220,220,220
FontEffectColor=0,0,0
StringEffect=Shadow
SolidColor=0,0,0,150
FontSize=8
FontFace=Segoe UI
StringStyle=BOLD
StringAlign=LEFT
AntiAlias=1
Text=%1
LeftMouseUpAction=[!SetClip "[mWallpaperShortPath0]"]
In the upper left corner of the skin you'll see value returned by the measure. Click to copy it to clipboard, then paste it back here, please.
User avatar
jsmorley
Developer
Posts: 19751
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Measure Registry Multi-String?

jsmorley » March 23rd, 2019, 2:03 pm

I doubt that we are going to do anything with REG_MULTI_SZ in the Registry measure.

This is a registry key that is intended to return an "array" of values, which are expressed as a series of NULL-terminated strings. While I don't doubt that we could get the separate values and concatenate them into a single string (remember, a measure can't return an "array" of values, it can return a single value), this is going to mean needing two or more separate measures, probably String measures, that are used to create separate entities using RegExpSubstitute.

I don't know what we would use as the "separator" for the string(s), maybe the \x0 NULL character would work ok, but maybe not, given that NULL is used to indicate the end of a string.

I personally think you are well advised to use one of the many ways you can query the registry, the most obvious being a simple "reg query ..." command in cmd.exe, but certainly Powershell commands, and even wmic.exe if you want it to be really slow.

The net result is going to be more or less the same, one measure (RunCommand) that gets the full string, and two or more that separates it into distinct usable entities.

While I understand (although I don't agree with particularly) the idea that something "native" to Rainmeter is preferred to executing and parsing some external command, I don't see us putting the work and testing needed for this into it in the short term. I just don't see the end result as being of huge value.
User avatar
StArL0rd84
Posts: 336
Joined: February 8th, 2015, 10:07 pm
Location: EU, Denmark.

Re: Measure Registry Multi-String?

StArL0rd84 » March 23rd, 2019, 2:26 pm

balala wrote:
March 23rd, 2019, 12:45 pm
And what does return this measure as it is? Add a String meter, to see the result and add a LeftMouseUpAction option to the meter, to copy to clipboard what the measure have returned. Post it here, please.

Code: Select all

[MeterPath]
Meter=STRING
MeasureName=mWallpaperShortPath0
X=0
Y=0
Padding=15,5,15,5
FontColor=220,220,220
FontEffectColor=0,0,0
StringEffect=Shadow
SolidColor=0,0,0,150
FontSize=8
FontFace=Segoe UI
StringStyle=BOLD
StringAlign=LEFT
AntiAlias=1
Text=%1
LeftMouseUpAction=[!SetClip "[mWallpaperShortPath0]"]
In the upper left corner of the skin you'll see value returned by the measure. Click to copy it to clipboard, then paste it back here, please.
The measure only returns the first line, as if the substitute was not even there:
D:\Images\Vintage

'D:\Images\Futurism' is still missing...
(#WorkTime# = 1 ? #Work# : ([mEnergyLoss:%] > 100 ? #SleepMode# : #Rainmeter#))
Yincognito
Posts: 682
Joined: February 27th, 2015, 2:38 pm

Re: Measure Registry Multi-String?

Yincognito » March 23rd, 2019, 2:40 pm

jsmorley wrote:
March 23rd, 2019, 2:03 pm
I doubt that we are going to do anything with REG_MULTI_SZ in the Registry measure.

This is a registry key that is intended to return an "array" of values, which are expressed as a series of NULL-terminated strings. While I don't doubt that we could get the separate values and concatenate them into a single string (remember, a measure can't return an "array" of values, it can return a single value), this is going to mean needing two or more separate measures, probably String measures, that are used to create separate entities using RegExpSubstitute.

I don't know what we would use as the "separator" for the string(s), maybe the \x0 NULL character would work ok, but maybe not, given that NULL is used to indicate the end of a string.

I personally think you are well advised to use one of the many ways you can query the registry, the most obvious being a simple "reg query ..." command in cmd.exe, but certainly Powershell commands, and even wmic.exe if you want it to be really slow.

The net result is going to be more or less the same, one measure (RunCommand) that gets the full string, and two or more that separates it into distinct usable entities.

While I understand (although I don't agree with particularly) the idea that something "native" to Rainmeter is preferred to executing and parsing some external command, I don't see us putting the work and testing needed for this into it in the short term. I just don't see the end result as being of huge value.
At least now we have an answer about whether it's going to be implemented or not. Hypothetically, the separator should be \r?\n, since it's the same separator that regedit is using ... OR, don't concatenate them at all and use some option to indicate the index of the NUL separated string to get, like you currently do for the Interface option of the Net measure (this way no further measures made by the user to split the string again would be needed).

Good idea on CMD + reg query, this looks like the fastest method yet. I also understand your point in this and why you have these doubts on implement it, but then the same argument can be used on the already supported types, that the result wasn't that much of a "huge value" (yet they got implemented). Not trying to convince you of anything, I'm just saying... ;-)
User avatar
jsmorley
Developer
Posts: 19751
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Measure Registry Multi-String?

jsmorley » March 23rd, 2019, 2:46 pm

Yincognito wrote:
March 23rd, 2019, 2:40 pm
...but then the same argument can be used on the already supported types, that the result wasn't that much of a "huge value" (yet they got implemented). Not trying to convince you of anything, I'm just saying... ;-)

Sure, but my response to that is that the Registry measure has worked the same way in Rainmeter for 10 years or so, and I don't think we have seen any hue and cry to change how it works. I'm not saying I'm opposed in principle to having Registry be able to handle any type of value from the registry, but the question is one of time and resources, weighed against the resulting value to users.

It's just not trivial to do. NULL is used by the C language to indicate the end of a string, and we would have to deal with that. binary values are another issue, as what do we return, the raw binary number, the number converted to HEX / Decimal. All, in all, a fair amount of thought and care would need to be put into this.

I would be opposed to dealing with REG_MULTI_SZ distinctly. We either rework the Registry measure to be all-inclusive, or we don't.