Sorry, the reason I gave why your addition would fail was slightly wrong... it isn't the main reason (you get that from being a guy and being busy with multiple things at once
).
The main reason for not working is that the boolean value will never be removed after the first execution:
emailList.length is always bigger than 0 (well, as long as you have hardcoded some accounts to sign in), so the script will never get to
shell.RegDelete. Aka, it would work the first time (when there are no other delays that is), but not the second time.
But say you got the removal of the registry key correct, or that there were some delays in the loading of the other instances, then it would indeed fail for the reason I gave before. You indeed need to have at least a counter instead of a simple boolean, so:
quote:
Originally posted by whiz
How about this?js code:
...
Now the count is only initiated by the 'main' script, but further handled by the other instances and thus it wont be influenced by possible delays when loading scripts etc. Which looks alright at first sight....
...except for the small booboo:
shell.RegDelete(MsgPlus.ScriptRegPath + "\\
IsRunningRunCount");
PS: Yustme, there are some other things you do a bit wrong in your script and might result in bugs now or in the futur.
1) move the whole
if (Messenger.Version >= 8.5) check inside
OnEvent_Initialize().
This because the Messenger object might not be initiated yet when the script is loaded (it should, but there are no garantees, and it might change it in futur versions also).
You should never assume specific objects created by Messenger Plus! exist in the global scope of a script!
btw, as for the
PerPassportSettings registry key, that can still be found under
HKCU\SOFTWARE\Microsoft\MSNMessenger and it's still not version dependant. You also don't need the
WLMexe variable anywhere. In other words, that whole version check can actually be removed.
--
But if you ever need to refer to the HKLM registry keys of Messenger, you should use:
js code:
if (Messenger.Version >= 9) {
var WLM_HKLM = 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Live\\Messenger';
} else {
var WLM_HKLM = 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSNMessenger';
}
Notice the 9 and not 8.5 !.
----------
2) You hard coded the path to the Messenger executable. This is not the proper way to handle this. Instead you should get the current path from the registry:
js code:
// Get the installation path in a proper and secure way
try {
var WSH = new ActiveXObject('WScript.Shell');
if (Messenger.Version >= 9) {
var sPath = WSH.RegRead('HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Live\\Messenger\\InstallationDirectory');
} else {
var sPath = WSH.RegRead('HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSNMessenger\\InstallationDirectory');
}
} catch(e) {
Debug.Trace('Error: the mandatory registry key \'InstallationDirectory\' is missing.');
}
But, for your script, all you actually need is the executable of Messenger. In other words, the module of the process you are already running. You can get this very easily by using the Windows API
GetModuleFileName:
js code:
function GetMessengerExecutable() {
var sBuffer = Interop.Allocate(2050);
Interop.Call('Kernel32', 'GetModuleFileNameW', 0, sBuffer.DataPtr, sBuffer.Size / 2);
return sBuffer.ReadString(0, true);
}
----------
3) Your
SetBinaryValue() function (and thus possibly
SetStringValue() too) can also use some work and a lot of optimizations. It also includes a major bug in the way it is coded and made to be used!!
For starters the content of the allocated datablock
lBufferSize is calculated wrong for most binary values. It is not
2*stringsize+2, but just
2*stringsize in case you are passing a JScript string to it (like the function is currently set up).
The extra 2 bytes which are hard coded in that function come from the fact that this function was probably made with null terminated unicode JScript strings in mind. But
not all binary variables consist of null terminated unicode string! In fact, most of them even don't (because strings can better be written as a REG_SZ)!!
You're simply lucky that it works because the
DefaultMemberName registry key accidently needs a null terminated unicode string too.
This is highly important to know if you ever want to use that same function to write other binary values to the registry. In fact, even many binary registry keys which are in fact unicode strings aren't null terminted at all. So you wouldn't even be able to use this function as-is for such binary strings either.
Either way, this
lBufferSize datablock isn't needed at all. The size parameter you need to pass is the length of the binary content (and nothing extra), and if you pass a JScript string you can just as well use a normal JScript variable for that or even directly using
sKeyValue.length * 2.
And instead of adding the extra two bytes to accomodate the unicode null character in the size calculation
inside the function, you should actually be
passing a null terminated string to the function instead! Thus "
MyString\0"
Then there is also the issue that unicode strings in JScript can not handle every possible character combination properly! Some character combinations will be converted automatically internally. This means that you actually should not use a JScript string to pass to such a function. Instead it should be made so you can pass a datablock.
And there is the issue that if you use that function with a registry path which doesn't exist yet, it will fail.
To make it short: that function needs a rewrite or should not be used as-is or be copied to another script like it is. Because it will fail for many binary values! Aka: it does not write all binary values properly.
Thus:
js code:
SetBinaryValue(HKEY_CURRENT_USER, 'SOFTWARE\\Microsoft\\MSNMessenger\\PerPassportSettings', 'DefaultMemberName', email + '\0');
function SetBinaryValue(lKeyLocation, sKey, sKeyName, sKeyValue) {
// Warning: this function can only be used to write unicode strings!!!
// Any other attempt to write true binary content with this function might fail due to internal unicode conversions.
var hKey = Interop.Allocate(4);
var lRetVal = Interop.Call('advapi32.dll', 'RegCreateKeyExW', lKeyLocation, sKey, 0, 0, 0, KEY_WRITE, 0, hKey.DataPtr, 0);
if (lRetVal === ERROR_SUCCESS) {
lRetVal = Interop.Call('advapi32.dll', 'RegSetValueExW', hKey.ReadDWORD(0), sKeyName, 0, REG_BINARY, sKeyValue, sKeyValue.length * 2);
Interop.Call('advapi32.dll', 'RegCloseKey', hKey.ReadDWORD(0));
}
return lRetVal === ERROR_SUCCESS;
}
- notice the addition of a null terminator character in the passed string instead of hard coding it in the function.
- notice the use of sKeyValue.length * 2 instead of that unneeded and wrong calculated datablock.
- notice the use of === (identity operator) which is faster than == (equality operator), also see here
- notice the use of RegCreateKeyExW instead of RegOpenKeyExW which will also create the registry path if it doesn't already exist.
- notice the smarter use of the return value lRetVal, making the code a whole lot shorter, yet the output will be identical as before.