Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Program in a single exe with no other files needed 1

Status
Not open for further replies.

Bryan - Gendev

Programmer
Jan 9, 2011
408
AU
I have been asked to produce a small utility app that will be distributed and run as a single exe file.

I have never done this before, always including a runtime with my applications.

Is this approach possible?

Thanks

GenDev

 
Not without runtimes.

But once the runtimes are registered any exe needing this version can work, no matter where located.
What is really the problem with that?

There is no language creating self contained exes. VFP itself is c++ and needs the C runtime, which is why that belongs to the VFP runtimes, the VFP runteim itself needs C.
.NET executables need a .NET framework installed
VB(6 or earlier) executables need a VB runtime
...
Even windows itself needs a C runtime to run.

Bye, Olaf.
 
There is absolutely no problem in doing this. It's quite a common thing to do. I've done it several times.

As Olaf indicated, you do need the runtime files to be installed - the same ones as you would use with a full application. But the customer doesn't really need to be aware of that. If you already have the runtimes correctly installed and registered (perhaps from another application), you can simply distribute the single EXE file. If not, create a SETUP.EXE using INNO Setup or InstallShield or something similar, give it to the customer, and tell them to follow the prompts the first time it is run.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Molebox is over the top, you could also put EXE + VFP runtime files into a self extracting archive, if you find one offering an option to start something afterwards.

You can do a html application (HTA), though it would be one of the last resorts I'd use.
You can run several things without any installation by batch files, scripts, etc., using system components.
You can do a clickonce installation. Juri Shutenko once did a demo with a small VFP utility. But that needs a .net framework to load and then install the VFP runtimes on top.
You can once and for all install the runtimes with the prolib runtime installers now in Christof Wollenhaupts hands: And as others already said you can of course do a setup, but to count that as a single EXE is mildly neglecting the fact you need admin rights to start a setup, let it run and install something.

Bye, Olaf.
 
Perhaps we should ask the question: Does this really need to be a single EXE? Sometimes a client will make a request, without really meaning it to be taken literally. He might just have meant that he wanted a simple program that could be easily installed.

It might also be useful to know if this program is to be distributed widely to a large number of users, or if it is to be installed on a single system by a knowledgeable user, or whatever.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Thanks to everybody who has responded.

The small program is to be used to gather data from tables which are on a users PC within another ( genealogy ) program. This program is written in VFP so each user ( and it may be sent to hundreds ) will have VFP 9 runtimes installed already. So I will be opening the users tables and recording statistics of each etc etc.

So I intend to write a test form, compile it to an exe and create an installer with Inno and test on one of my PCs that doesn't have a full VFP installed.

I will let you know how it goes.

Thanks again

GenDev
 
Which VFP9 runtimes? Is it installed the right way or just copied into the program folder?

That's the irony in this profile. You can likely rely on them having done everything the right way, and then find out that you use ONE feature that doesn't work right in THAT version of the VFP9 runtime, whichever one they have.
 
What dan says, also they might simply have put the runtime to their EXE not registering it, so even if it's your the same version as you use, it may not be registered.

What you plan to do shows you haven't understood what we're saying at all. If you'd establish a runtime of your needs you can deploy any further exe without anything accompanying it, not even an installer. But if you do an installer, if that is not the hurdle, then do yourself a favor and create an installer WITH runtimes of your VFP version. It'll just mean another turnaround, if you see your EXE does not work with the already installed runtime.

Are you afraid of breaking anything? A newer version doesn't kill an old one. The only chance you break something has the prerequisite you use another SP of the same main version and the already installed software has its runtime installed globally/registered and you also do that with your other SP. That could break, if your SP is older.

But you can prevent even that by simply doing what's recommended to not interfere with anything else: Put your needed runtimes side by side to your EXE and they'll be taken plus the existing software will not know of your runtimes in the same way it won't know about any other files in any other folder.

All you need is DBF access, so you don't need the DLLs for CHM help support, you don't need XML functionalities, you don't do report. You will only need msvcr71.dll, gdiplus.dll, vfp9r.dll, vfp9renu.dll and your EXE. If you use some FLL you may also need the msvcp71.dll or even other C runtime versions.

And yes, while your EXE may only be 50K, the runtimes add about 10 MB, so what? The smallest USB stick I still use has 1GB. And safety goes first, always.

I only recommend setting up your version of the runtimes globally and registered, if you provide many VFP applications, but even when you use the same VFP version you can put the runtimes to your EXE and are fine without a registered runtime.

And if you think about file extension mappings, you're on the wrong path, the runtimes won't set up any file extension mappings to them, only the full VFP product establishes file extension mappings of VFP file extensions, what extensions would a runtime map? EXE? Think about why not.

About your idea to make a setup of an EXE: If you really want to test whether your EXE works with the existing runtime, you only put your EXE on a stick and try to run it from there. No installer needed for that test. If it works, then what dan warned about could still happen, if you use a function not supported with the existing runtime, it'll fail, and that won't necessarily show immediately. If the runtimes are not registered, you won't be able to start from stick. In that case you may try to run the exe from the existing application folder, but then you also know you could put up your own runtime registered and won't harm the existing application.

The installer was suggested in case your customer is so stubborn, he only accepts one EXE and so you could meet this condition You don't have to tell him this initial dialogs appearing at first start really install the software. He most probably is so inaffine to computers, he doesn't realize this process is making an installation of the actual application exe plus runtimes you of course then put into the installer. That was the idea behind that. You don't need an installer to test the single exe. That would be like doing a setup for a doc to see if they have word installed at all and in the right version.

Bye, Olaf.
 
The 'target' tables belong to a particular genealogy application (program xx say) which does do all the right things when it is installed. It is very robust and had been used fore over 10 years in various versions. It has included VP9 runtimes since they became available.

I have tested my small exe from a memory stick on another PC I have. I got an error message naturally.
I installed xx and my small program ran OK.

Regards

GenDev
 
Congratulations so far.

>It has included VP9 runtimes
As your EXE worked after installing xx, xx does register its runtimes, that's OK. Since VFP9 is your version, you can run VFP9 exes.

That still might fail on certain commands, if the SP is wrong, your test run proves at least if there are such commands they are not executed in every case. But you may expand and I hope you'd like to be safe about any future constellations, too. There are runtimes of the original VFP9 (SP0), SP1, SP2 and hotfix versions and one thing not working downward compatible is sql buffermode, the one thing caused nightmares for me. I had reproducible C0000005 errors when using the wrong runtime, therefore I am more sensitive about that topic, perhaps.

You program ran OK as single EXE. This means one thing for sure: As you don't bring any other runtime you don't break anything - not in regard to runtimes. So far OK.

Now one thing I'd do is check, which runtime your EXE uses. Compare the output of Version(1) in your VFP IDE with the output of the compiled EXE on that computer. If that matches, you are safe about the main runtime. Also check out _vfp.servername. If you output that in your vfp9.exe in the command window, that will give you the full path to vfp9.exe, output from an EXE, it will give the full path to the vfp9r.dll, so you find out where xx has this dll installed and most probably also other files of the VFP runtime can be found there. Looking there you know how comprehensive xx did install the runtimes.

Bye, Olaf.
 
Olaf said

Congratulations so far.

>It has included VP9 runtimes
As your EXE worked after installing xx, xx does register its runtimes, that's OK. Since VFP9 is your version, you can run VFP9 exes.

As I move on in the development of my application I have introduced the routine opening the files of the 'main' application.

This works like a dream on my development PC.

So I moved the exe to the memorystick and tried again on the other PC.

Like before, my app opens fine and all is well (selecting paths - writing to my ini etc) until I get to open a dbf belonging to the 'main' app. I have programmed a simple error msg when I encounter a lTablerror = .t.. However I want to get more information about this and would like to get the output from my errhandler routine. ( I see a nice listing when I get errors elsewhere ( I think this is one of Ramani's routines).

But I can't work out how to get this to work with my table error.

Can anyone point me to a comprehensive error routine for use when opening tables?

Thanks in advance.
GenDev
 
I have managed to get my error routine working with the lTableerror = .t.

I now have to find out why I get that error.

GenDev
 
Out of curiosity, what is the error?

Errors when opening tables got a lot better with VFP9's SET TABLEPROMPT ON|OFF command. Before then, it was a crap shoot. Users would get a File Open dialog. The smart ones would click cancel. Everyone else would choose a dbf (not knowing which one the code was looking for), begetting COMPLETELY unrelated errors that further clouded the issue.

At least now we can go straight to the error opening the table. But we still need to know which error it is.
 
Interesting would be the code setting lTablerror = .t.

If you do ON ERROR lTablerror = .t., you simply override the normal error handling. If you don't want that, don't do it and the normal error handler will work as always.
It makes sense, if you want to react to lTablerror = .t. in trying again, for example, or simply diaplaying your own more user friendly message related to the current code/form/table.

Bye, Olaf.
 

My new app works perfectly on my development PC.

Further - running the new app on user's PC (my test PC with genie app installed)

1 Running my app from the memorystick - actions work correctly ( choosing paths,files etc) until
2 When the app gets to the 'grunt' stuff - opening a dbf I get an error message at the start of this routine code

Code:
Procedure tbl_opening
Parameters myfile,tempter

Local lcErrorHandling, lTableError

lcErrorHandling = On("error")
On Error Store .T. To lTableError
On Error Do errHandler With ;
	ERROR( ), Message( ), Message(1), Program( ), Lineno( )

LOCAL gcname

lTableError = .F.
Set Defa To (myactualpath)
gcname=Justfname(myfile)
Adir(gatable, '*.dbf')
etc...

my error report states Variable 'gcname' is not found. The same error is shown for gatable variable ( and others) in this routine.

These error do not occur when running my new app on my dev PC.

Can anyone point to possible solutions please?

Thanks

GenDev

 
By name convention gcname should be global, meaning a PUBLIC variable, you define it as LOCAL, your error handler will not know it, yes, because it's not PUBLIC.
gaTable is created by ADIR, it will be a private variable, that means it's seen here and in routines called from here, but not in routines called by ON ERROR triggering.

You must have modified things so they stop working.

The error handler/report should not depend on any global variables, instead you pass in all info needed.

BEsides, what I assumed turns out the truth, you had ON ERROR lTableError=.T., just with the STORE syntax instead. That is temporarily killing normal error handling, but the original error handler is stored in lcErrorHandling and that should be used later to reset to normal error handling, maybe it is in the part you cut out and indicated with "etc...". Anyway, putting up normal error handling in the next line just overrides On Error Store .T. To lTableError, which you then can remove. And if you do that, you can also remove both ON ERROR, as the error handling surely is established beforehand in main.prg or down the line of other initialising code.

I don't know what you did or modified, but you need to go back a few steps obviously, to get to where it worked.

Bye, Olaf.
 
Olaf,

Thank you for your response.

I am a self taught septagenarian VFP programmer and am struggling a bit of late.

Taking your points I see that the 'On Error Store .T. To lTableError' is superfluous and the errorhandler routine comes into play anyway which is why I see my standard error message report which I mentioned.
Next steps..
I removed the LOCAL gcname and added PUBLIC gcname in my main.prg and I no longer get an error there.
I did the same with gatable but that caused another error 'gatable is not an arra'. So I removed that.
Running on the user PC again I get an error message 'gatable is not found' but as you say
>'gaTable is created by ADIR, it will be a private variable, that means it's seen here'

Still working OK on the dev PC after my changes. Its very exciting to see it rip through the analysis routines that its designed to do.

Any further ideas - it seems so nearly solved but so far.

GenDev
 
You have to define gaArray as an ARRAY via DIMENSION or PUBLIC ARRAY, give it one element, ADIR will expand that later.

You could also change your error reporting routine. All info needed is in ARRAY plus ASTACKINFO, if an error regarding a table occurs, aside of MESSAGE() and one of the error array elements most likely SYS(2018) contains the name of the table involved. So maybe instead of fixxing your variables, you'd better switch to a better self contained error handler.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top