Link to home
Start Free TrialLog in
Avatar of Ronald112197
Ronald112197Flag for Germany

asked on

Class not registered - EOleSysError???

I have a little problem with one of my programs that loads one specific internet page and evaluates the contents.
I use the THTTP-class and everything works fine on my PC... ONLY on my PC.
As soon as I start the program at university or on a friend's computer, I get the following error message:
"Exception EOleSysError in module s_watch.exe at 00032F45
Class not registered"

I changed the code so it doesn't really do anything when started, but I get the error message anyway - this must be some problem with the classes themselves, not with the "code". It works fine on my PC with both NT and Win95 (dual boot).

Is it possible that the program tries to reference some DLL that is not present on "normal" systems? (I have Delphi 3 on both of my systems). How would I find out if so and which ones??
What else could be the problem and how would I find it? The problem is that everything is fine at home but not on other computers. I can NOT install Delphi on those computers which makes "trial and error" debugging a real pain!!

Any help greatly appreciated!
Avatar of Odie
Odie

Any ActiveX components your program uses must be registered on the destination machine.  In this case it's probably only html.ocx (C:\windows\system).  You should place this in the system directory of the destination machine and then run "regsvr32.exe" (C:\windows - probably) passing the filename as a parameter ("regsvr32.exe html.ocx").
Yo,
take a look at
http://www.rtfm.be/fpiette/indexuk.htm
A lot of good and free native Delphi internet components ! No pain to register ActiveX controls on all clients.

Slash/d003303
Avatar of Ronald112197

ASKER

Ooops. Shooot!
Asking people to copy the file and run regsvr is not a valid option, so what would I do? Supply an install program (well, should only be a batch file actually...)??

Still not nice at all, because the program should ideally be only one file that can easily be started from a disk or from the network!

Is there any way around this?? I don't use HTML, I only use THTTP to retrieve a URL and evaluate the contents of the page. I don't need any visualization...
Can I use THTTP or do I need to use a different class? Lots of programs use Windows' Internet connection without having to register components...
Well, in that case you'll have to use WinSock or a third-party non-activex control.

Of course a batch-file would do the trick nicely.  Something like:
<<<
@echo off
copy http.ocx %windir%\system
%windir%\regsvr32.exe %windir%\system\http.ocx
>>>

An install program would be better and you could handle errors then.  And what if the http.ocx already exists, etc.  Maybe you should use InstallShield for this.

I don't think you can install the control from the program itself for Delphi checks wether the control is installed at startup.  (You've seen it - your program doesn't even start)

Otherwise, you'll need to use a third-party control.

Hope it helps,

Odie


hmm... looks like using a different component would mean major changes in the code :-((
I guess I'll try InstallShield first - that'll be interesting all by itself because I've never used it so far...*g*

How do I know if I have to include any DLL's? As I said: I can't try it at home (of course it always works!) and it costs me 2-3 days for each "try"

P.S.: I don't have Delphi with me but wanted to try it anyway. I found some page that suggested that i have to register httpct.ocx. When I ran regsvr32, I got the following error-message:
"LoadLibrary("c:\win95\system\httpct.ocx") failed.
GetLastError returns 0x00000485".
I'll look for the *.ocx files on my Delphi CD, but no matter what, I shouldn't get an error message trying to register an *.ocx... any ideas?
I tried it on several machines but I can't get it to run!
I even used InstallShield which copies the *.ocx and (as far as I know) tries to register it. I don't get any error messages during installation, but the program still aborts with the same "Class not registered" error :-((

When I "uninstall" my program, InstallShield tells me that httpct.ocx is not used by any application any more and asks if it should be removed - it is in the registry somewhere but obviously not in all the places it should be!!

P.S.: The *.ocx file is the one from the Delphi-CD (i.e. the one from my own hard disk's system directory)
hmm... I also added
nmocod.dll
nmorenu.dll
nmsckn.dll
nmw3vwn.dll

Now the program "works", i.e. it starts without error-message, but I get an access violation (Read of address FFFFFFFF) as soon as I access the HTTP-object...

once again: everything works fine on the PCs/HDDs that have Delphi installed, so it must be some missing DLL or registry entry that keeps the THTTP-object (placed on the form) from being inizialized correctly!

Any ideas? Again: I really wonder how you know which files to include!! Is this a guessing game or trial and error????!
i have an answer for that, but i would like to post it
as an answer, not a comment.
unlock this question (i.e. reject the proposed answer)
so that i can give you my answer.
What the hell, here it goes:

I had just the same problem with smtp. Here's how I solved it:

The .ocx libraries have an internal function to register
themselves. The the regsrv32.exe loads the library and
calls this function. I took the source of regsrv32.exe,
modified it a little and put it in my program.
Just call RegisterAxLib('http.ocx') on TForm.OnCreate, or
TApplication.OnException, what ever happens first.
You might need to re-run the application after registering.
You could show a dialog saying "stuff needed to run this app
has just been installed. please re-run me" and terminate the app.
And, of course, you would only run this once. Put some mark
in the computer (e.g. a registry entry) to let the program
know the ocx is installed.

********BOF********

uses
  SysUtils, Windows, ActiveX, ComObj, RegConst;

type
  TRegAction = (raReg, raUnreg);
  TRegProc = function : HResult; stdcall;

const
  ProcName: array[TRegAction] of PChar = ('DllRegisterServer', 'DllUnregisterServer');

procedure RegisterAxLib(FileName: string);
var
  LibHandle: THandle;
  RegProc: TRegProc;
  RegAction: TRegAction = raReg;
begin
  LibHandle := LoadLibrary(PChar(FileName));
  if LibHandle = 0 then raise Exception.CreateFmt(SLoadFail, [FileName]);
  try
    @RegProc := GetProcAddress(LibHandle, ProcName[RegAction]);
    if @RegProc = Nil then
      raise Exception.CreateFmt(SCantFindProc, [ProcName[RegAction],FileName]);
    if RegProc <> 0 then
      raise Exception.CreateFmt(SRegFail, [ProcName[RegAction], FileName]);
  finally
    FreeLibrary(LibHandle);
  end;
end;

********EOF********
It seems that will solve your problem.

Anyway, about knowing which DLLs you need for your program to run, you can use Windows' Quick View.  This lists the imported and exported functions for a program, and the imported dlls.  It doesn't seem to list activex (ocx) controls though.

Oh - acerola,
Why doesn't this control register the regular way?
And what would be the regular way?
Quickview was a good idea, but all the DLLs listed there are present on the "destination machine" - yet I still have the problem with the "access violation" :-((
(btw: Quickview doesn't list any of the DLLs I listed above! It didn't work at all without them! Would QuickView know if some DLL references some other DLL?)

What could be missing?
This is becoming a critical problem in my project!!
Adjusted points to 125
httpct.ocx uses nmocod.dll and nmsckn.dll. i dont think it uses the others.

httpct.ocx and nmocod.dll have their internal procedure for registering. use tregsvr.exe or the function i gave you to register them.
if that doesnt work, try using tregsvr.exe with the -t option to register the libs (ocx and dll). i am not sure what is it for, but it might work.
http also uses nmorenu.dll.
nmw3vwn.dll is for html.
nmocod.dll should be registered with the tregsvr.exe -t
httpct.ocx should be registered with tregsvr.exe (without -t)
the source of tregsvr is in
C:\Program Files\Borland\Delphi 3\Demos\ACTIVEX\TREGSVR
tell me if it works. the access violation may be because nmocod was not registered properly. also check out:
C:\Program Files\Borland\Delphi 3\OCX\ISP\Licenses.reg
i dont think these registry entries are actually needed for the ocx to work, but you could try if everything else fails.
About Quickview: it doesn't show wether some dll references another dll.  And with the regular way I mean just registering the ocx and on you go.  I really thought you only needed to register the ocx (my mistake).  And if the ocx needs the other dlls you do need to register them too (probably) with regsvr32 or acerola's function.

BTW - have you tried it on another destination machine than the one you were using for testing?
Well, my quickview shows the import/export table of the dll. It also shows the import/export of the ocx. I just have to rename the .ocx to .dll and call quickview on it. I use win98 rc0.

ocx works just like a dll. regsvr32 and tregsvr call the dll/ocx DllRegisterServer function (that is in the dll/ocx) in order to register it. this is also what my function does.

nmocod.dll is a "type library". it must be registered with tregsvr with the -t option, or this function, also taken from tregsvr source:

********BOF********

uses
  SysUtils, Windows, ActiveX, ComObj, RegConst;

procedure RegisterTLB(FileName: String);
var
  WFileName, DocName: WideString;
  TypeLib: ITypeLib;
  LibAttr: PTLibAttr;
  DirBuffer: array[0..MAX_PATH] of char;
begin
  if ExtractFilePath(FileName) = '' then
  begin
    GetCurrentDirectory(SizeOf(DirBuffer), DirBuffer);
    FileName := '\' + FileName;
    FileName := DirBuffer + FileName;
  end;
  if not FileExists(FileName) then
    raise Exception.CreateFmt(SFileNotFound, [FileName]);
  WFileName := FileName;
  OleCheck(LoadTypeLib(PWideChar(WFileName), TypeLib));
  OleCheck(TypeLib.GetLibAttr(LibAttr));
  try
    OleCheck(TypeLib.GetDocumentation(-1, nil, nil, nil, @DocName));
    DocName := ExtractFilePath(DocName);
    OleCheck(RegisterTypeLib(TypeLib, PWideChar(WFileName), PWideChar(DocName)));
  finally
    TypeLib.ReleaseTLibAttr(LibAttr);
  end;
end;

********EOF********
sorry guys... I'm quite busy at the moment, but I'll try the above as soon as I can... Just wanted to make sure this question won't be autograded and let you know that I haven't forgot about it...

    C U soon and thx so far!
still too busy... this is complicated and will take some time. For some reason my ActiveX controls don't want to work...

I just don't want anybody to get an automatic C for a good answer...
hmm... I'm having exams right now and no time to try complicated stuff.
This is what I'm doing right now: I stopped using ActiveX controls, because either way, installation seems to be more complicated than it should be.

So who should get the points now?
Odie, because he told me why I get the error message?
d003303, because he proposed the component I now use?
acerola, because he told me how I could fix the problem? (I assume it would work, but haven't tried it yet)??

What do you say?
Up to you.
Huh, that's a complicated question... I think no one will answer it for less than 500 points...
Just another thing not related with the solution of this prob. It came to me when I was reading through the whole thread again.
A better tool to explore DLL dependencies is Borlands TDUMP utility in the delphi?\bin directory. Put it in your path and call it with e.g. "tdump somedll.dll | more" and you get much more information than QuickView gives.

Slash/d003303
ok, let's put an end to this discussion. I'm really sorry, but I don't currently have the time to try all of the above, especially since I use a different component now and the problem is not so pressing any more.

Now what bout the points?

The winner iiiiiiiiiiis:

acerola

because I guess he put the most effort into this answer and it probably would have been the best solution for my problem - other than using a non Active-X component. I think d003303 has enough points I guess and only posted a few lines :-))

Thanks a lot Odie! Your comment helped but for some reason didn't solve my problem. It's possible that it should have, but somehow it didn't :-( Thanks a lot anyway

acerola: Did I understand correctly that I can use EITHER tregsvr OR your function?
Why didn't InstallShield correctly register the components/DLLs when I included them in the setup file? As far as I know, it is supposed to register everything it installs!
ASKER CERTIFIED SOLUTION
Avatar of acerola
acerola

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
So if InstallShield does not register the DLLs, how do I provide an install program that "makes it work" without including special code to register components in my program??

About the components: I agree. I also once asked about getting the build number and project version from the exe-file and somebody gave me a huuuge components that retrieved all available information. It was a nice component, but I didn't manage to figure out which part of the code read the version info! A little later, somebody posted about twenty lines that did the job! On the other hand, I was quite happy to get a good http-component (since I couldn't get the OCX to install) because it would have been quite a pain to write one!!
Well, I don't know much about InstallShield. I just use it when my program needs to use the BDE. But you could make yourself a install program in delphi that does all the stuff.