Archive: Problems with Installer on Win 2k


Problems with Installer on Win 2k
Hello,
My installer requires users to enter a valid CD Key, when they enter the CD Key, the Installer Calls a function from an included DLL and the DLL checks on the internet if the key is valid..

this works great on windows xp...but on every windows 2000 machine i've tried it on it always comes up with the "Incorrect Registration ID" message...which is the default message (even if the Dll is not found it will come up with that message.

Anyone know why this is happening? Or is there something different in the calling of DLLs from Windows 2000?

Thanks


Hello, I'm wondering what character set NSIS would send to the DLL?

Unicode? or Ansi?

If that switches with operating systems that would explain what's going on maybe?

Does this sound logical?


Alright, well I made some changes to the DLL and now can confirm that the DLL function is not being called on Windows 2000, but is being called on Windows XP

the System.Dll plugin does work on Windows 2k Right?

Here is my code that uses the DLL


Function CheckID

ReadINIStr $0 "$PLUGINSDIR\reg.ini" "Settings" "State"
StrCmp $0 0 0 done

ReadINIStr ${Key} "$PLUGINSDIR\reg.ini" "Field 2" "State"

System::Call /NOUNLOAD 'Register::Check(t, i) i("${Key}", "4") .r0'

StrCmp $0 "1" done
StrCmp $0 "2" incorrect
StrCmp $0 "3" toomany

incorrect:
MessageBox MB_ICONEXCLAMATION|MB_OK "Incorrect Registration ID"
Abort

toomany:
MessageBox MB_ICONEXCLAMATION|MB_OK "This Registration ID has been used too many times. Please call 800-XXX-XXXX"
Abort

done:

FunctionEnd


Anyone see anything that looks funny or would make Win 2k not call the DLL? Is there a way to check and make sure it's finding the correct file or any types of error checking with the System.dll?

Currently I just leave the DLL with the Setup.exe, is this where it's suppose to go? Same directory (I never specify in the code that's where it goes)

Also, does this rule out the possiblility of it being a .dll coding problem?

I tried just a basic user32::MessageBox function and that worked fine, so obviously it's something with my .DLL.

I simplified my code a bit to


Function CheckID

ReadINIStr $0 "$PLUGINSDIR\reg.ini" "Settings" "State"
StrCmp $0 0 0 done

ReadINIStr ${Key} "$PLUGINSDIR\reg.ini" "Field 2" "State"

System::Call "Registration::Check(t) i('${Key}') .r0"

MessageBox MB_ICONEXCLAMATION|MB_OK $0
StrCmp $0 "1" done
StrCmp $0 "2" incorrect
StrCmp $0 "3" toomany

incorrect:
MessageBox MB_ICONEXCLAMATION|MB_OK "Incorrect Registration ID"
Abort

toomany:
MessageBox MB_ICONEXCLAMATION|MB_OK "This Registration ID has been used too many times. Please call 800-XXX-XXXX"
Abort

done:

FunctionEnd


After I do the System::Call, I try to MessageBox the result($0) and it displays "error" on the screen. Is there a way I can get better error results?


Function CheckID

ReadINIStr $0 "$PLUGINSDIR\reg.ini" "Settings" "State"
StrCmp $0 0 0 done

ReadINIStr ${Key} "$PLUGINSDIR\reg.ini" "Field 2" "State"
SetOutPath $PLUGINSDIR
File "Registration.dll"
System::Call "Registration::Check(t) i('${Key}') .r0 ?e"
Delete $PLUGINSDIR\Registration.dll

MessageBox MB_ICONEXCLAMATION|MB_OK $0
StrCmp $0 "1" done
StrCmp $0 "2" incorrect
StrCmp $0 "3" toomany

incorrect:
MessageBox MB_ICONEXCLAMATION|MB_OK "Incorrect Registration ID"
Abort

toomany:
MessageBox MB_ICONEXCLAMATION|MB_OK "This Registration ID has been used too many times. Please call 800-405-2100"
Abort

done:

FunctionEnd


completely rebuilt the dll, checked with Dependancey Watcher and it finds the Check function, but in win 2k the installer will not run the function (the reason I know this is because in the DLL function i have it set to pop up message boxes..which don't occur)...I don't know what the '?e' part does on the system::call function...I can't seem to receive any error value, the MessageBox MB_ICONEXCLAMATION|MB_OK $0 still shows a messagebox with 'error' as the text.

Anyone, any Ideas?

Perhaps you need to register it first with RegDLL (then unregister with UnRegDLL)?

-Stu


Thank you very much for the reply Afrow UK,

I added RegDLL and UnRegDLL like you said (not sure if it's where it's suppose to be)..

So this is my function


Function CheckID

ReadINIStr $0 "$PLUGINSDIR\reg.ini" "Settings" "State"
StrCmp $0 0 0 done

ReadINIStr ${Key} "$PLUGINSDIR\reg.ini" "Field 2" "State"
SetOutPath $PLUGINSDIR
File "Registration.dll"
RegDLL $PLUGINSDIR\Registration.dll
System::Call "Registration::Check(t) i('${Key}') .r0 ?e"

UnRegDLL $PLUGINSDIR\Registration.dll
Delete $PLUGINSDIR\Registration.dll

MessageBox MB_ICONEXCLAMATION|MB_OK $0
StrCmp $0 "1" done
StrCmp $0 "2" incorrect
StrCmp $0 "3" toomany

incorrect:
MessageBox MB_ICONEXCLAMATION|MB_OK "Incorrect Registration ID"
Abort

toomany:
MessageBox MB_ICONEXCLAMATION|MB_OK "This Registration ID has been used too many times. Please call 800-XXX-XXXX"
Abort

done:

FunctionEnd


I also trimmed down my DLL to just a windows MessageBox...I'm pretty sure i'm building it right..Created a blank VS 2005 Win32 DLL Project, with this header file (.h)

#ifndef _DLLREG_H_
#define _DLLREG_H_

#include <windows.h>
#include <iostream>

extern "C" __declspec(dllexport) int Check(char * code);

#endif


and this source file (.cpp)

#include "Reg.h"

extern "C" __declspec(dllexport)
int Check(char * code)
{
MessageBox(0, "The Code", code, 0);
return 0;
}


And I still get the same response as before ('error').

If anyone could just at least confirm* that my source is fine that would be great. Has anyone tried using the System::Call on a Win2k machine before?

Thanks again!
-Kyle

I've never written a DLL to be called with the System plugin. If I need to execute some C/C++ code, I just put it into an NSIS plugin.

See Contrib\ExDll\exdll.c in the NSIS source distribution.

-Stu


Hrmm

If I need to execute some C/C++ code, I just put it into an NSIS plugin.
I'm not too familier with the NSIS source (just downloaded it now actually...but I would like to try this, but have no idea where to put my code or how the .nsi scripts call the functions...Is there a place for me to learn? Or is it simple enough to be explained over the forums?


and btw..in the file you mentions I see a exported function called myFunction..then in the comments a "do your stuff here"...does this code ever get called? If so..where? can you simply just write in the NSIS script Call myFunction ?

It could be that your library references the MS Runtime library (MSVCRTxx.DLL). It is not hard to do by accident - I know I did twice in my projects.

Windows 2000 likely has a different version of this library to Windows XP, if it is even present at all in Win2K.

I think VS2005 projects expect to find either version 7 or version 8 of the runtime library. The .NET Framework also installs a version of the runtime (usually v7) and this will affect your development PC (since it will now have the required DLL).

It could be that it can find a suitable version on XP (v7) but no version on Win2K (v6).

Double-check you dependencies in Dependency Walker and confirm the versions of all libraries that are being used i.e. no just that a library with the right name exists but the date/time stamp is the same. Also, check that you are using the static linking rather than dynamic linking for the MS C/C++ runtime.

BTW: The System function call works fine on Win2K, I have used in several updaters/installers that run on Win2K.


Just opened up my Registration DLL in Dependency Walker and found MSVCRT80.dll...so I'm hoping this is the problem, and the Win2k machine would not have this...

Now sure how to get rid of it though..workin on it..


BTW you can use existing tools for communication with server instead of your own dll. NSISdl included to distribution, InetLoad also supports POST. Last plug-in solves most of intercommunication problems we found on this forum last year ;)