Error running an old project - Lazarus - lazarus

I am using object pascal in lazarus. When I open an old project and attempt to run it; this code window pops up in the source editor:
program TimeKeeper;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms, datetimectrls, TimeKeeperU1;
{$R *.res}
begin
RequireDerivedFormResource := True;
Application.Initialize;
Application.CreateForm(TfrmTimeKeeper, frmTimeKeeper);
Application.Run;
end.
This code window popup in the source window errors, is paired with these errors:
TimeKeeper.lpr(20,1) Error: Can't create object file: TimeKeeper.exe
(error code: 5) TimeKeeper.lpr(20,1) Error: Can't create executable
TimeKeeper.exe
Does anyone know what the workaround is?

The error message indicates that the object file can't be created, which results in the application not being created. The error code 5 means access denied, which means you don't have write access to the directory where the compiler and linker are attempting to store output, or the executable is in use and can't be replaced (perhaps by anti-virus software), or it's been made read-only.
If the problem is with rights, the solutionis to either get sufficient rights to the directory or to change the output path of the project to a directory where you do have sufficient rights. This is typically done in Project->Options from the main menu.
If it's due to anti-virus software or another process that's using the executable, disable the AV software or provide an exception rule that prevents scanning that folder.
If the issue is caused by the file being read-only, change the file attributes to remove that attribute.

It could also be caused simply by having an executable of the program already running such as in an external terminal which is hidden from view. The compiler will not attempt to overwrite an .exe file that is open. Ask me how I know. :)

Related

Migrating an old old old VB + MSAccess program to a different computer

I have an old program that was made for us a looong time ago. It consists of a large MDB (Access) file with all the data (no encryption, I can manually open the file and browse all the data) and an EXE file (probably VB?) that was custom made to easily manage the data in the file.
I'm trying to move this program for another user, to run in his own laptop.
First I tried just copying all the files, but I had MSCOM, GRD, LST, and ocx missing file errors. I tracked them all down and regsvr32'd them, and the program seemed to go a little further.
Then I got an ODBC connector error. Playing with ODBC sources manager and I added an entry with the name of the program that points to the specific MBD file. This helped too.
Now program starts and shows all menus, buttons and everything. However, the default record that should be onscreen is empty and as soon as I hit any control (next record, list, etc...) it crashes with a VB error 91:
Run-time Error '91': Object variable or With block variable not set
So it looks like the program can open the database file itself but it cant really access the data inside.
What else can I try to see what I need to set it all up correctly? Is there anything that "spies" inside and VB program to see how it's trying to access the MDB file?
Any help would be appreciated!
Probable cause of your problem is some missing dll/ocx file referenced in your application. Open your exe file with notepad (or notepad++) and find all occurrences of .dll and .ocx files and check if those
files exist at user's laptop. If not, just copy them from your working machine and regsvr32 them.
I will go with #smith suggestion.
While looking at the error message on microsoft's website, below is the solution that applies to your scenerio
"The object is a valid object, but it wasn't set because the object library in which it is described hasn't been selected in the Add References dialog box."
So ensure all files are correctly copied to new system.

Call to fopen() in a DLL from a UWP app returns a NULL pointer. GetLastError() returned ERROR_ACCESS_DENIED

I am working on a UWP application that calls a function from a DLL. It supplies the function with the application installation path so that I can go ahead and write some data to it.
I imported the DLL using LoadPackagedLibrary as described in How to: Use Existing C++ Code in a Universal Windows Platform App.
I retrieved the path using Windows::Storage::StorageFolder^ installedLocation = Windows::ApplicationModel::Package::Current->InstalledLocation;.
However, when I try to open the file and get a handle to it using fopen, I get a NULL pointer. I retrieved the error code using GetLastError() and it returned ERROR_ACCESS_DENINED error.
What could be the reason for this? Am I missing something? Do I need to declare additional capabilities to ensure that the DLL can access files in the application's installation path?
Writing to the UWP app's installation folder is restricted by design. This is to ensure the integrity of the app installation and to enable seamless, incremental automatic updates for the application package.
If you want to write data you will need to write it to the app's appdata location, not the install location.
fopen() relies on CreateFile to do the actual work. CreateFile only knows how to handle filesystem ACLs, not capability-based UWP permissions, and so it always fails with ACCESS_DENIED for anything other than your AppData directories (for read/write access) or your install location (for read-only access).
There is a work-around using CreateFileFromApp but it won't work for fopen() unless you're willing to statically-link the CRT, which has its cons. For example, you don't get the benefit of automatic security patches and you might not be able to distribute through the Microsoft Store.

Windows scripting: is it possible to capture missing-DLL errors in a log file?

When you try to run a program on Windows, and the loader can't find all of the required DLLs, the default behavior is to pop up a dialog box that describes the problem, including both the name of the program and the name of (one of the) missing DLLs. The process then hangs until someone clicks OK, and then exits with an error code. Here's an example of this dialog box:
Now suppose you're scripting some automated process that might fail for this reason, e.g. running CI tests after installation, where part of the point is to make sure the installer installs all the DLLs. You don't want your build workers to hang waiting for someone to click on a dialog box that's being displayed on a monitor that the computer physically does not have because it's in a server rack somewhere. You want the test cycle to stop immediately and the details to get written to the log.
Your build driver can disable this dialog box for itself and all its child processes (assuming nobody uses CREATE_DEFAULT_ERROR_MODE) by calling SetErrorMode:
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
hProc = CreateProcess(...);
However, this only solves half of the problem. The offending process will terminate with an exit status of 0xC0000135 (STATUS_DLL_NOT_FOUND), but the name of the problem executable and the name of the missing DLL are not reported anywhere that I can find it.
So here's the actual question: From code running in the build driver, how do I get the name of the problem executable and the name of the missing DLL, so that I can write them to my CI build logs? Anything goes, except that the code of the problem executable itself and its DLLs cannot be modified (because this is supposed to be a general solution) and an approach that does not require elevated privileges is strongly preferred.
(This is a follow-up question for Suppress "The program can't start because X.dll is missing" error popup . I've been vaguely meaning to write it for years now.)
Even though it's a little overkill, you could write a program/script that parses the PE format of each executable, walks its import table to enumerate imported modules, and checks to see if each module exists on the system (i.e. is it in \Windows\System32, the current directory, etc).
Then, if the executable in question is missing an import, log the executable and the missing import somewhere (and don't run the executable, of course).
If you want to do this in Python, the pefile module is excellent (https://pypi.org/project/pefile/).
(Update: This won't work for DLLs that are imported via LoadLibrary)

FoxPro compiled code output

Trying to do some work on an old FoxPro and VB6 legacy application and I've run into a brick wall.
The VB6 part of the application creates three .qpr file which, I understand, are just SQL queries. It then calls an external .fxp file, which is compiled foxpro code. I am not sure exactly what this is - however, I am assuming it to be a compiled version of an identically-named .prg file in the same folder, which contains the following code:
COMPILE "\\Count\Database\Sql_Result.qpr"
WAIT TIMEOUT 1
COMPILE "\\Count\Database\Sql_Total.qpr"
WAIT TIMEOUT 1
COMPILE "\\Count\Database\Sql_Query.qpr"
Those are the .qpr files which the VB6 app generates.
When you run this compilation command, it seems to do something. No error is thrown. Yet I can't see it's done very much.
What is the product of the above compile commands, and how can I find it?
The .QPR programs are nothing but a simple .PRG file with renamed extension. When the main VFP app calls the .qpr program, it just runs the query, the resulting cursor result is created and then VFP does with it whatever it needs to.
If your VFP application is compiled into an EXE, and the original underlying EXE was compiled with .qpr code, then the new versions of .qpr would not be impacted... but not enough to confirm the situation of your app design / implementation.

registration free COM without copying the dll to the same directory as the executable

How can I consume a registration free COM object without copying the dll to the same directory as the executable? Is this possible?
I would like a complete working sample or a detailed step-by-step guide for my exact scenario.
For example, I have the following components:
CppTestRunner.exe - vc++ console application
CppTests.dll - vc++ mfc dll
CsCOMServer.dll - c# COM visible dll
I do not want to modify the exe or its directory, like adding an external manifest.
CppTests.dll is in a different directory than the exe.
It is okay if CsCOMServer.dll is in the same directory as CppTests.dll.
CppTestRunner.exe calls LoadLibrary on CppTests.dll which works fine.
After embedding manifests and using the windows activation context apis, I was able to copy CsCOMServer.dll to the exe directory to verify that CppTests.dll can create an instance of CsCOMServer.dll without issues, but again, I am trying to avoid this step.
Currently, with CsCOMServer.dll in the same directory as CppTests.dll, and without CsCOMServer.dll in the exe directory, I am getting the following error when I call CoCreateInstance:
Error = 0x80070002 The system cannot find the file specified.
I have used sysinternals process monitor to track down the paths CppTestRunner.exe looks in, etc.
I notice that depending on the things I try to do, sometimes CppTestRunner.exe tries to read CsCOMServer.dll.config in the same directory as CppTests.dll, but no matter what I try to put in there, I was not able to get past the error.
Also depending on other things I try to do, CppTestRunner.exe tries to read CsCOMServer.dll in the same directory as CppTests.dll but for some reason, I still get the same error.
Anyone know of working code with this exact scenario?
As you can probably tell, this is part of some unit\integration tests.
As a simple workaround, I am currently copying CppTestRunner.exe to the same directory as CppTests.dll and running it from there, but would like to avoid this step.
Thank you.
.NET looks for managed registration-free COM first in the GAC, then in the executable's folder. It uses the activation context to read activation metadata, but not to determine the location of the files themselves.
You can save the DLL in a sub Folder, let say DLLFolder\YourDll.dll, and in the manifest file of yourDll, write the filename like
<file name = "DLLFolder\YourDll.dll">
But you need to keep the manifest file (of the DLL) in the location where the EXE is saved.

Resources