It is currently March 29th, 2024, 12:04 am

[Fixed] Installer Merge Variables Feature Fails With Blank Values

Report bugs with the Rainmeter application and suggest features.
User avatar
SilverAzide
Rainmeter Sage
Posts: 2588
Joined: March 23rd, 2015, 5:26 pm

[Fixed] Installer Merge Variables Feature Fails With Blank Values

Post by SilverAzide »

Hello,

I've been meaning to submit this bug report for a long time, so my apologies. It is present in the current 4.4 beta and goes back a long way, to at least 4.2 and maybe even earlier.

When creating a skin package, we have an option in the Packager to identify a list of variables files, like so:
SkinPackager.jpg
When the skin is installed over an existing installation, the installer is supposed to merge the variables together to preserve the end user's configuration. However, I have noticed that if the "source" variables file includes a variable that is set to nothing, the merge operation sets the target file's variable to nothing instead of preserving it. In other words, if the source file being installed has a variable with a value, the target file's value is preserved properly; but if the source has no value, the target value is blanked.

The attached skin illustrates this issue. Please ignore the function of this skin, the important bit to look at is the FirstRunTime variable in the VariablesBug.inc include file, and what happens after an installation. The "source" version of this file (in one in the package), looks like this:

Code: Select all

[Variables]
IsRunOnce=0
FirstRunTime=
The first time the skin runs, IsRunOnce is set to 1, the FirstRunTime variable is set to the run time. So the skin looks like this:
Skin1.jpg
If you install the skin again, or as many times as you want, in theory there should be no change to the skin appearance. This is because the packager was configured to preserve the variables. The skin should show the ORIGINAL first time you ever ran the skin, plus the current time.

However, because the "source" file has a blank FirstRunTime value, this doesn't work as expected because while IsRunOnce is preserved, FirstRunTime is not. What you get is this:
Skin2.jpg
There are cases where the skin developer can't know what value a variable should be set to set ahead of time for things are are user-specific, so a blank is a reasonable default option. Unfortunately, due to this glitch in the installer, it currently isn't working properly.

A skin illustrating this issue is attached.
You do not have the required permissions to view the files attached to this post.
Last edited by SilverAzide on July 4th, 2020, 12:39 am, edited 1 time in total.
Gadgets Wiki GitHub More Gadgets...
User avatar
Yincognito
Rainmeter Sage
Posts: 7029
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [Bug] Installer Merge Variables Feature Fails With Blank Values

Post by Yincognito »

SilverAzide wrote: June 28th, 2020, 1:12 am Hello,

I've been meaning to submit this bug report for a long time, so my apologies. It is present in the current 4.4 beta and goes back a long way, to at least 4.2 and maybe even earlier.

When creating a skin package, we have an option in the Packager to identify a list of variables files, like so:
SkinPackager.jpg

When the skin is installed over an existing installation, the installer is supposed to merge the variables together to preserve the end user's configuration. However, I have noticed that if the "source" variables file includes a variable that is set to nothing, the merge operation sets the target file's variable to nothing instead of preserving it. In other words, if the source file being installed has a variable with a value, the target file's value is preserved properly; but if the source has no value, the target value is blanked.

The attached skin illustrates this issue. Please ignore the function of this skin, the important bit to look at is the FirstRunTime variable in the VariablesBug.inc include file, and what happens after an installation. The "source" version of this file (in one in the package), looks like this:

Code: Select all

[Variables]
IsRunOnce=0
FirstRunTime=
The first time the skin runs, IsRunOnce is set to 1, the FirstRunTime variable is set to the run time. So the skin looks like this:
Skin1.jpg

If you install the skin again, or as many times as you want, in theory there should be no change to the skin appearance. This is because the packager was configured to preserve the variables. The skin should show the ORIGINAL first time you ever ran the skin, plus the current time.

However, because the "source" file has a blank FirstRunTime value, this doesn't work as expected because while IsRunOnce is preserved, FirstRunTime is not. What you get is this:
Skin2.jpg

There are cases where the skin developer can't know what value a variable should be set to set ahead of time for things are are user-specific, so a blank is a reasonable default option. Unfortunately, due to this glitch in the installer, it currently isn't working properly.

A skin illustrating this issue is attached.
Tried to workaround the issue you have by setting FirstRunTime to "", but experienced another interesting issue ... which "propagated" even if I set back things exactly as you had them in your skin (bar 2 obvious options in RMSKIN.ini from the package), i.e. set FirstRunTime back to nothing (maybe I'm doing something wrong, didn't check something?): The issue was that Rainmeter wouldn't write the FirstRunTime value in VariablesBug.inc, not even the first time (I have no idea if it happens the same for you, I can only speak for myself):
VariablesBug_2.0.0.rmskin
The IsRunOnce variable behaved properly. Maybe there's an issue with dates here? By the way, checking Merge Skins while packaging led to writing things without issues, but then, the value of FirstRunTime wasn't preserved either, so...
You do not have the required permissions to view the files attached to this post.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
SilverAzide
Rainmeter Sage
Posts: 2588
Joined: March 23rd, 2015, 5:26 pm

Re: [Bug] Installer Merge Variables Feature Fails With Blank Values

Post by SilverAzide »

^^^ Bump ^^^
Any comments from the devs?
Gadgets Wiki GitHub More Gadgets...
User avatar
Brian
Developer
Posts: 2674
Joined: November 24th, 2011, 1:42 am
Location: Utah

Re: [Bug] Installer Merge Variables Feature Fails With Blank Values

Post by Brian »

This has actually been reported before.
https://forum.rainmeter.net/viewtopic.php?f=14&t=30008&p=154655#p154646

We have identified the root "cause" of this, but haven't come up with a solution for this just yet.

The issue is we use the Windows API function WritePrivateProfileString to write to ini files. If the "value" is empty (or null), it removes that key=value pair entirely from the section.
https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-writeprivateprofilestringw

-Brian
User avatar
SilverAzide
Rainmeter Sage
Posts: 2588
Joined: March 23rd, 2015, 5:26 pm

Re: [Bug] Installer Merge Variables Feature Fails With Blank Values

Post by SilverAzide »

Brian wrote: July 2nd, 2020, 6:58 pm This has actually been reported before.
https://forum.rainmeter.net/viewtopic.php?f=14&t=30008&p=154655#p154646

We have identified the root "cause" of this, but haven't come up with a solution for this just yet.

The issue is we use the Windows API function WritePrivateProfileString to write to ini files. If the "value" is empty (or null), it removes that key=value pair entirely from the section.
https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-writeprivateprofilestringw

-Brian
Oh crap, I could have sworn it was already posted but I couldn't find it for some reason, so I did it again. Sorry! I also forgot about that issue with the Win32 API, it's been a while since I used that particular set of functions.

This is a real head-scratcher of a problem. How does !WriteVariable work? It lets us write blanks somehow. Perhaps if the "source" file (the one in the rmskin package) had something like MyVariable="" (i.e., empty quotes), could the packager go ahead and write the quotes to the .INI so WritePrivateProfileString won't blow away the entry? (It ignores quotes now, like normal, resulting in a deletion.)
Gadgets Wiki GitHub More Gadgets...
User avatar
Yincognito
Rainmeter Sage
Posts: 7029
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [Bug] Installer Merge Variables Feature Fails With Blank Values

Post by Yincognito »

SilverAzide wrote: July 2nd, 2020, 8:28 pm Oh crap, I could have sworn it was already posted but I couldn't find it for some reason, so I did it again. Sorry! I also forgot about that issue with the Win32 API, it's been a while since I used that particular set of functions.

This is a real head-scratcher of a problem. How does !WriteVariable work? It lets us write blanks somehow. Perhaps if the "source" file (the one in the rmskin package) had something like MyVariable="" (i.e., empty quotes), could the packager go ahead and write the quotes to the .INI so WritePrivateProfileString won't blow away the entry? (It ignores quotes now, like normal, resulting in a deletion.)
I'm not sure if it helps, but maybe you could try using the Zero Width Space (aka [\x200B] or [\8203] in Rainmeter's character variable reference notation) Unicode character to workaround the issue? I mean, technically it's not nothing, so in theory it shouldn't cause a problem, but it certainly "looks" like nothing, as it doesn't consume any space.

Personally, I use this quite extensively in my skins to "mark" / "enclose" some string parts in order to apply specific inline settings on the said part of the string, without any drawback. Maybe you get lucky and it works in your case too - I certainly hope so. :confused:
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
Brian
Developer
Posts: 2674
Joined: November 24th, 2011, 1:42 am
Location: Utah

Re: [Bug] Installer Merge Variables Feature Fails With Blank Values

Post by Brian »

Good news, I believe I have fixed this issue.

Turns out the issue was not with WritePrivateProfileString at all. The issue was GetPrivateProfileString. It basically finds a key within a section, and returns its value.
https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getprivateprofilestring

Normally, you can specify a "default" value to be returned if a key=value pair is not found. In this case, only the key is found, so the returned buffer (ie the value) is an empty string and not the "default" value. The function itself returns the amount of characters in the buffer (in this case 0). So there is no way to validate that anything was returned because the returned buffer is empty. This means there was no way to know if variable (in this case "FirstRunTime=" exists at all.

So, I came about it in a different way and searched the entire [Variables] section itself and just looked for the keys only. It is a little less efficient since it has to split the key=value pairs of the previous variables file and the new variables file, but that is the trade off to get it working.

-Brian
User avatar
SilverAzide
Rainmeter Sage
Posts: 2588
Joined: March 23rd, 2015, 5:26 pm

Re: [Bug] Installer Merge Variables Feature Fails With Blank Values

Post by SilverAzide »

Brian wrote: July 3rd, 2020, 7:47 pm Good news, I believe I have fixed this issue.
Image

Thank you!
Gadgets Wiki GitHub More Gadgets...