I have a Delphi application with an automation object.
On the start of the program, I want to register the COM object automatically in the registry (instead of using the /regserver switch).
The old version of the program was written in Delphi 7 and I think I remember that this version registered itself after program start. But now it's compiled with D2009 and it doesn't register itself now. Maybe somebody know something about this?
Thank you very much!
This is probably failing because you are running on a machine with UAC and you don't have rights to write to HKLM. You aren't going to find a satisfactory solution using the /regserver switch because it will always try to write there.
You could switch to registry free COM, although it might just be better to do the registration as part of installation. That's when you are expected to do it because that's when you know that you will have sufficient rights.
You can use ComServer.UpdateRegistry(True); to register your com objects and ComServer.UpdateRegistry(False); to un-register.
ComServer is found in ComServ.pas
http://docwiki.embarcadero.com/VCL/en/ComServ.TComServer.UpdateRegistry
Related
I am writing a Windows 32 bit program that can use one of multiple possible dlls. So it tries to load each dll in turn, using SysUtils.SafeLoadLibrary and if loading succeeds, it uses that dll.
Unfortunately some of these dlls are statically linked to other dlls. These dlls may be missing from the computer. In that case I get dialog telling me
[myprogram]: [myprogram.exe] System Error
The program can't start because [some dll name] is missing from your computer. Try reinstalling the program to fix this problem."
After pressing the OK button on that dialog, the program gets the error code and tries one of the other dlls which then works fine.
Rather than showing that dialog to the user I want my program to silently ignore it.
How can I accomplish that?
In case it matters: My program is written in Delphi 2007. The Windows version is Windows 8.1, but the program should also work with other Windows versions >= Windows XP.
I have tried SetErrorMode(SEM_FAILCRITICALERRORS) but it did not make any difference.
SafeLoadLibrary sets the error mode to the value that you provide as an argument, and then restores it after the call to LoadLibrary returns. Most likely you are not supplying a value for that parameter, in which case a default of SEM_NOOPENFILEERRORBOX is passed. In that case it is probably disabling SEM_FAILCRITICALERRORS which would explain the behaviour that you see.
You could solve the problem by passing SEM_FAILCRITICALERRORS every time you call SafeLoadLibrary. Or, perhaps better would be to pass the current error mode. However this is hard to obtain. In Vista and later you can call GetErrorMode. But in older versions you have to do this:
ErrorMode := SetErrorMode(0);
SetErrorMode(ErrorMode);
Because this is a process wide setting, you have a window of opportunity between the two calls to SetErrorMode, for multi-threaded applications to be caught out.
Frankly, I believe that you should call SetErrorMode exactly once in the lifetime of a process, at startup. With that in mind, I would shun SafeLoadLibrary.
If you wish to take advantage of its other function, namely to protect against changes to floating point control state, then you should implement that functionality yourself, in my opinion.
In our program we are using a web service to pull back data from a third party into our program.
Ever since we updated to Delphi XE from Delphi 2009, Windows server 2003 users are receiving the following error message when making a SOAP call to the web service.
msvcrt.dll on Server 2003 does not have the procedure _ftol2_sse which is now being called for some reason..
I know this procedure was not being called when we had our source code on Delphi 2009 because I don't get this error on Windows server 2003 when running those builds.
Is this feasible? Could a change in the IDE affect which dll procedures are being called? Does anyone have any insight or ideas on how I might track down or fix this error?
Thanks
This is the third similar question you have asked on this topic. I'll attempt to give you some background information and help you work out what is going on.
First of all it's important to know that msvcrt.dll is a system component. It is not the MSVC runtime. It is supplied as part of Windows. Back in the bad old days, in the mid-90s, a lot of devlopers assumed that the MSVC6 runtime was always available. And they neglected to install that runtime as part of their program's installation. This occasionally caused trouble when the install program happened to find a machine without MSVC6.
The MSVC team moved to differently named runtime DLLs, msvcrt70.dll, msvcrt80.dll and so on. And they educated the developers that installing the MSVC runtime should be part of all MSVC application's installation programs.
But the Windows team wanted to help out legacy apps that had installers that assumed MSVC6 runtime was available. So they took the MSVC6 runtime under their control and started shipping it with Windows. I think this started around the time of Windows 2000 or XP.
The point I am trying to make is that msvcrt.dll is a system DLL over which you have no control. In your previous questions you have described your attempts to modify that DLL. Don't do that.
Now, from what I can glean, the version of msvcrt.dll that shipped with 2003 server does not export a function named _ftol2_sse. Hardly surprising since SSE floating point was not widely available back in the days of 2003 server. Clearly something in your system is resulting in an attempt to import _ftol2_sse.
You should be able to work out what is provoking this by using Dependency Walker. Use the functions on the Profile menu to start your application and study closely the logs. You should be able to see the chain of events that lead to an attempt to link to _ftol2_sse.
I'd be surprised if any of the Windows code linked to msvcrt.dll. That library is provided purely as a prop for legacy apps that link against MSVC6. But you never know.
Also try loading your executable in Dependency Walker. Look at the list of imported DLLs. Check to see if msvcrt.dll is in the list. If so, see what functions your executable imports, and if _ftol2_sse is in that list. If so then you'll be able to find it somewhere in the Delphi source code.
From the various similar sounding reports on the web I suspect that the problem you face is benign. Many of the people reporting the same issue can OK the dialogs and have their program continue without problem. This suggests that you can simply suppress the error reporting and so solve your problem. Use the SetErrorMode function to do so. You want to include the SEM_FAILCRITICALERRORS flag.
Be aware that SetErrorMode has a rather perverse interface. Almost all code that I have ever seen uses it incorrectly. Including the code in the Delphi RTL, and so many of the commonly used Delphi third party libraries. Raymond Chen, as usual, explains how to use it correctly.
Could switching compilers provoke the behaviour change? Certainly they could. Either the library code that you are using is implemented differently. Or perhaps the error mode is somehow different at the crucial moment.
I have an application with an automation object.
In the delphi IDE I can register it via the button "register type library".
As an alternative I can use codegear's tregsvr.
But how should I register the application when it's installed on other computers?
Should the setup include the tregsvr.exe? Am I allowed to contribute the tregsvr.exe?
Thanks for your advice!
Windows has a regsvr32.exe which is able to register DLLs (or OCXs). If your server is an EXE you should be able to register it using the command line switch /REGSERVER.
This mechanism is called self-registration, so your COM server library performs registration itself.
RegSvr32 yours.dll
RegSvr32 /u yours.dll
Actually, along with this, there are lot of Windows built-in registration behaviours, all of them are simple, you only need to list your file eg. in RegisterDlls INF section. Those are merely a calls to DllRegisterServer and DllUnregisterServer functions
HI:
I've a Delphi 7 program that I wrote many years ago, but I've lost the source code. It's a small program but very useful for me.
I've tried to 'install' it again in a new Windows XP computer, just copying the folder with de data (.db paradox files), and configured the BDE connection.
When the programm starts I receive an "Unknown exception" and halts. I've no idea why this happens, and can't debug cause the lost source code. I've tried in another computer with the same results.
Any suggestions or ideas? What do you do in a situation like this?
Thanks in advance.
EDIT:
When I installed Delphi 7 in the new XP computer, the exception came from unknown to known. It was something related to the folder for the Paradox.net file. Thnk you all.
Delphi IDE can attach to a running process and debug it (Run -> Attach to process), although without debug symbols you will end up debugging plain assembler code, which requires some knowledge of assembler and how a Windows application works. And debugging startup exceptions could be pretty difficult if the debugger can't start the program. You can also use the WinDbg debugger from Microsoft.
There are disassemblers (I used the very powerful IDA Pro) that are able to recognize standard library calls helping analysys a lot. You may also find decompilers, although decompiling native applications is a bit more difficult than with those using a p-code or the like.
If the error is not due to a misconfiguration, patching a binary file is not easy.
You can use any debugger, either Visual Studio one, or a free OllyDbg, don't know if Delphi IDE have a simple external-exe-debugger.
But debugging will be very hard w/o source codes, and you must have at least basic knowledge of Assembler Language and win32api.
Alternatively you can use tools like FileMon & RegMon to examine your app activity and find potential problems.
You can try "Run|Connect to process..." in the Delphi IDE. But what zed_0xff said regarding debbugging without sources still applies.
I would go for the disassemble approach like ldsandon suggest, especially since you have (some) knowledge about what your exe is doing.
Besides IDA Pro also take a look at tools aimed specifically at Delphi such as IDR (Interactive Delphi Reconstructor), DeDe and PE Explorer.
To make sure it is not BDE related, I would build another rudimentary application trying to access the same data on this machine.
Once this application works, you can move on to test on the Pascal code side of things.
I have had my share of BDE oddities so I'd prefer to rule this out.
I have created a few AUTOObjects using Delphi and its type library. It compiles without error, but when I tried to register it, Delphi froze, and doesn't return to normal. I have tried to register it in both Delphi 7 and 2006, but both get into the same problem. I tried to register a simple library in Delphi's demo, I am ruling out bad registry file,
There might be something wrong with my code, but I have no idea where, since it compiles well and I have not put any code in RegisterDLL.
Anyone had the same problem before?
You have not provided enough information for anyone to help you.
Have a read of this http://support.microsoft.com/kb/555375 on how to ask a technical question, it's written for the Microsoft newsgroups, but has the same application here.
Initialization sections of the units also get executed when registering a COM dll. Try registering outside of Delphi with tregsvr or regsvr32 and see if that works ok. You can also have those tools as a startup project and debug your dll while it gets registered.
Cheers everyone. I solved the problem. The problem was in one of unit there was a initialization code creates threads, now I have removed it, the library registers fine. :)