I'm working on Windows XP/Delphi 7. I need to add some procedures (or functions) inside a program that is running, and I do not want to re-compile it once again after I finished it.
I just have a host application with 5 functions to send different types of alarms, but there are other new alarm types, so I have to do new functions to send those alarms, but I should not re-build the host application. I have a class named TAlarmManager that it's invoked calling those functions.
Maybe a plugin?? OK, but how can I "insert" new functions??? Tutorial, manual, book, etc.. for learning about this, or any advice on how to do this???
I have studied plugins (I'm totally new on this theme), but no one "talks" about adding functions to a host application. It seems to me that plugins add functionality from itself, I mean, they have been developed with self code to do something, not to "add" code to the host application... How can I do this??
For the technical side: How does the Delphi IDE do it? That would be the first place for me to look.
To understand plugins, you must understand that you can't add new functions. You could but since the old code doesn't know how to call it, they wouldn't be called.
So what you do is you add a "register" or "start" function to your plugin. That start function gets a data structure as parameter which it can examine or extend. In your case, that would be the list of alarms. Alarms always work the same (my guess), so it can add additional alarms.
The main code will then, after registering all plugins, just walk over the list of alarms and invoke the standard alarm function on each of them. It no longer cares where each alarm comes from and what it really does.
The key here: You need to define an interface which both sides subscribe to. The main code calls the interface functions and your plugin code implements them.
Another option available is to use a scripting component to your project. One which works quite well is PascalScript. This would allow you to load external scripts after the fact and then run them as needed to interact with your application. As Aaron suggested you will also need to still provide an interface of some sort for your script to interact with your application.
See also Plugins system for Delphi application - bpl vs dll? here on Stackoverflow.
I'm not quite sure what you mean by "alarms", so I'm making a couple of assumptions.
1) If you don't need additional code for the alarms, I would try to make them data driven. Keep the different kinds of alarms in a database or configuration file, which makes it easy to update applications in the field without recompiling or reinstalling.
2) If you need special code for each alarm, you could use run time packages as plug-ins for your application. Search for Delphi runtime packages to get some ideas and tutorials. Here are a couple of links I found:
http://delphi.wikia.com/wiki/Creating_Packages
http://delphi.about.com/od/objectpascalide/a/bpl_vs_dll.htm
3) Scripting, as skamradt already mentioned. If it makes sense for your application, this could also let your customers write their own add-on functionality without requiring a recompile on your part.
You almost definitely want to use Pascalscript, as skamradt suggests. You should start here, and seriously consider this option. There are many possibilities that come out of being able to serialize live code as text. The only downside is possibly speed of execution, but that may not matter for your application domain. I would have upvoted skamradt, but I don't have enough reputation to upvote :)
Some time ago I was looking at a situation sort of like what you're describing.
My answer was .DLLs. I put the variable code in a .DLL that was dynamically loaded, the name specified in a configuration file. I passed in a record containing everything I knew about the situation.
In my case there was only a success/fail return and no screen output, this worked quite well. (It was commanding a piece of machinery.)
This sounds like a place where a scripting language or "Domain Specific Language" may make sense. There are several approaches to this:
Implement alarm functions in VBscript (.vbs files written in notepad) that accesses your Delphi code via COM API. Using the COM API gives you access to a large range of programming tools for writing functions, including Delphi. This is the most clumsy solution, but easiest to do. It may also be a benefit to your sales process, and it is always good to think about how to sell things.
Implement your own function language in Delphi. This way you can make it so easy, that your endusers can write their own alarm functions. If you do it as an expression evaluator, you can write an alarm as 2*T1>T2. There are several expression evaluators out there, and you can also write your own if they don't match your needs.
Use a predefined programming language inside your Delphi application, for instance, "Pascal Script", see http://www.remobjects.com/ps.aspx
You should take a look at PaxCompiler, like PascalScript it allows to load scripts, but you can even precompile them before for more performance. Look at the demos section for the solution of your problem.
As a side note, the web page really looks bad, but the package is really powerful and stable.
I think that the scripting solution it's good for this situation.
There are many scripting packages that you can evaluate:
Context Scripting Suite
Fast Script
RemObjects Pascal Script
TMS Scripter Studio
paxScript
Other packages that you can find on Torry, DSP, VClComponents,...
Regards.
Related
I just started exploring the capabilities of live templates (using Delphi XE4), and ran into a question. Some templates that I have made create code that requires certain units to be added to my uses clause in order to function.
How can I make my template automatically add the required units to the uses clause if they aren't already included? My initial guess is that I need to make a custom scripting engine in order to do this, and I have found a few articles that seem to contain sufficient information for me to create a scripting engine without much hassle. However, I don't know how to make the scripting engine actually perform my desired task. I assume that I need to use the Open Tools Api, but I don't know how to do that.
If I am on the right track, could somebody please share some information that would help me proceed down it? Otherwise, could somebody point me in the right direction?
Open Tools Api does not provide such functionality (as in .NET's CodeDOM, for example). You have to interpret existing uses clause(s) and then add a desired unit. Additionally you will have to expose your new function to the Live Template scripting engine.
I need to speed up my coding, too much work, so I need be able to generate code.
Any tools, any ideas?
Delphi includes Live Templates, a completely scriptable and configurable system for generating code constructs of any size or complexity.
Live Templates are, in my view, one of the more under-appreciated features in Delphi.
Find out how to use them at: http://delphi.wikia.com/wiki/Delphi_Live_Templates
and
http://delphi.wikia.com/wiki/Live_Templates_Technical_Info
Live templates are completely scriptable, meaning you can write Delphi code to do whatever you want with them.
An extendable example can be found here:
http://cc.codegear.com/Item/26420
Not a very good idea IMHO. If you need generator, then probably you have lots of code that looks very similar, so instead of generator, better thing would be to rethink and refactor code you have.
That should result in less code that is easier to maintain and less code in future for similar tasks.
If you are doing database application, then you could use some good visual SQL query builder to help you create queries. That is part that Delphi was not very good (I don't know if it improved in D2007 and D2009)
EDIT - Regarding SQL generation
There's lots of comments about query builder.
Well, I suppose I'm spoiled. As I remember, Delphi before version 6 (or maybe even 5?), had decent visual query builder. I had 0 (zero) bugs in SQL when I selected fields in query designer, opposed to writing SQL by myself.
SQL is just string in Delphi, there is no compiler checking, so this was the best way to ensure that SQL is correctly written.
If you mean something like a modeling tool, you could try out ModelMaker.
Rather than trying to code generate, you should probably just obtain code to do the bulk of what you want to do.
There are hundreds of free products at Sourceforge for Delphi.
And there are hundreds of thousands of code samples at Google Code Search that you can use.
Plus lots thousands of free or purchaseable components at repositories such as Torry's Delphi Pages or Embarcadero's Code Central for Delphi
Using components already made is the fastest way to speed up your coding, and to add capabilities that you would never have been able to.
For me best way is by creating custom components, and then create designer for this component.
I have find that i spent most of the time writing code that read/write values from controls. So i created control that can read, write, validate values, and automatically fill form or stored procedure or directly generate SQL and execute.
Custom designer allows you to setup all properties easy. Now i don't write code for such trivial task i just put control , open designer and set properties and rules that must be satisfied.
ModelMaker Code Explorer speed up my coding in times. It has a nice hotkeys for synchronising implementation and declaration, so if you changed one, you don't have to search for it pair. Also, very nice feature is, method editing dialog. And many more.
Have you tried GExpert? It is a set of tools built to increase the productivity of Delphi and C++Builder programmers by adding several features to the IDE. GExperts is developed as Open Source software.
Other alternative is using project template by saving a framework into the IDE Repository, create your own components and frames.
I wrote a code generator calle CodeTypo. I'm used it in many production environment. You can find it here: http://dade2000.altervista.org/index.php?page=CodeTypo
It's still in beta phase but is usable and reasonably stable.
I'll migrate all content of this old site in the new one (www.danieleteti.it) in english. And I'll add some other info about CodeTypo and code generators.
The thing that sped up my Delphi coding the most was getting CodeRush for Delphi (via a DevExpress VCL subscription for Delphi 5, 6, 7) and setting up a ton of templates.
I am re-writing and/or consolidating a bunch of my "app framework" classes (basic mainform, about box, locking routines & purchase linking, auto-update, datamodule initializer, etc) -- Basically, I have a number of small potential shareware apps that I'm wanting to get out the door, and want to re-use code where I can, as well as build a framework for later apps to save time.
In one app I have auto-updating, I'm using LMD's WebUpdate, and am reasonably happy with it, but given that I'm re-vamping everything, I thought I'd see what the consensus is for "best approach" on this. I don't mind paying for commercial, nor using open source if that's best... just would rather not reinvent the wheel. (I've read: Delphi: How do you auto-update your applications?)
What is the best Auto-update component for Delphi Win 32 apps?
I use TmxWebUpdate. It's free, simple and easy to customize. I also own TMS Component Pack with TWebUpdate, but never really found a good incentive to switch.
I use TWebUpdate from TMS Components and am very happy with it. I haven't used LMD so unfortunately am not able to provide a comparison.
TMS also supply a whole raft of other components so if your re-writes require any else, especially if you want some shiny UI enhancements (TMS have a range of iPhone-style components) then the website is certainly worth a visit.
They seem fairly active in their support forums (although I haven't had need to use them for the WebUpdate component) and they have a fairly regular release cycle.
I have heard good compliment about TWebUpdate from Tmssoftware
also torry has much components for the same job, some are free and others are commericals.
Now what's the best?, it's depend on your needs, you already using one from LMD, which is a good company and I have very good experince with their components, but never used this one.
If you need a specific functionality, or you have some problems with the current one you are using, it's will be better to list them, so you will get a better answers, but it's hard to define the best, because every one has different experience and views.
I use TWebUpdate myself. It works, but the docs are a bit limited and it seems a bit buggy sometimes.
I have looked into LMD's (I have their full component pack), but it seemed to be much more limited than TWebupdate.
I'm also using TWebUpdate, and have to echo stg's comments on quality of support (good), and quality of documentation (spotty -- it's old, and doesn't always reflect their new features immediately).
You'll also find some places that stress the "roll your own" approach.
Remember that part of the auto-update issue is the tools that you will need to create the update "package" at your end. TMS Software makes a tool available for use with TWebUpdate, and it's reasonably well done. In my case, I'm "misusing" the component to deal with multiple files so that I can refresh additional related libraries, text files, etc. The update builder tool isn't really good for that. So there's some manual editing. But the updating part works well.
I'll also add a caution that you need to be careful with updates in Vista (and probably Windows 7). Writing to the protected places in the Program Files hierarchy was problematic for me. You may want to check that out with whatever component you use.
Have you considered Appwave from Embarcadero. It's not free and I don't know the price.
I need a few of my related applications to communicate to each other (exchange data and initiate actions). Requirements are without packages and no sockets. So I guess that leaves named pipes, WM_CopyData (like Skype does it) and command parameters. What are your best practices?
You probably have a couple of options.
Beyond what you already have:
DDE
Memory Mapped Files (MMF)
MailSlots
I would probably go with either the Pipes or the MMF.
There are a couple of free MMF components that you can download,
Deborah Pate has a set of freeware classes you can use.
MapFiles.zip
Check for MailSlots on Torry's site.
The final solution might be dependent on the amount, size and frequency of the data transfers that decide which option you choose.
I would advise to use COM in this situation. (Attention: not COM+, not ActiveX, not OLE; COM, just COM.)
Since Delphi 7 (or an earlier version, I'm not sure), this is easily done by adding a Type Library to the project, and an Automation object.
Advantages are it's pretty widely supported, both within Delphi (the Type Library Editor has everything you need and updates your code, and COM internals and registering are catered for from the ComServ unit), and outside of Delphi (I use it in a number of project to interact with all sorts of applications: C++ projects, Word and Excel documents using VBA, oldskool ASP...).
An only disadvantage I encountered may be threading issues, in normal applications, a plain CoInitialize(nil); at application startup will do, in more complex applications, you need to think about 'threading apartments' or use free threading and do your own locking. (Which in some cases you've been doing already.)
Another alternative which is dirt simple to implement is to use the database to pass information.
Not overly elegant, and it does use a lot of overhead, but if your application is already data-aware (ie has a database as part of it), then using a table or two to pass information is pretty easy.
You could use simple files: One side writes to it, the other reads. If you need two way communication, just use two files, one for each direction.
Of course this is not really high performance.
Another vote from me for named pipes, for the data exchange. I like them slightly more than mmap files, since the win32 pipe APIs give you some nice choices out of the box: sync/async, byte stream vs message packets, simple ReadFile/WriteFile calls. All of which you could do yourself with mmaps... but pipes are already there...
And you can control access with security attributes -- which isn't an option with WM_CopyData. This might not be an issue immediately... but can be handy to have the option, even if you don't care who sends your app messages. For me, this was helpful when Vista came along, and suddenly user apps ran in a separate session to my service. Was good that tweaking the security attributes was the only thing needed to get things working again.
For "initiating actions", you might be able to get away with something as easy as some named Events, and not worry about sending messages at all? The interested parties simply wait for it to be signalled.
Personally, I'd avoid COM unless you have to specifically support COM-based clients.
Do not use COM, too much overhead (variants) and you must register you .dll or .exe (and it gives a lot of weird installation + update problems).
I should go for MMF, I use this for communication with Windows Services.
I use the following TGpMessageQueueReader and writer for this:
http://17slon.com/gp/gp/gpsync.htm
If you want to pass data, call functions etc then use COM, however if there are lots of calls be aware that COM is slow. Also you might have to register the application with "xxx.exe /Regserver", before it will work.
Is'nt this the sort of this that RemObjects is good at?
Bri
I've got to do some significant development in a large, old, spaghetti-ridden ASP system. I've been away from ASP for a long time, focusing my energies on Rails development.
One basic step I've taken is to refactor pages into subs and functions with meaningful names, so that at least it's easy to understand # the top of the file what's generally going on.
Is there a worthwhile MVC framework for ASP? Or a best practice at how to at least get business logic out of the views? (I remember doing a lot of includes back in the day -- is that still the way to do it?)
I'd love to get some unit testing going for business logic too, but maybe I'm asking too much?
Update:
There are over 200 ASP scripts in the project, some thousands of lines long ;) UGH!
We may opt for the "big rewrite" but until then, when I'm in changing a page, I want to spend a little extra time cleaning up the spaghetti.
Assumptions
The documentation for the Classic ASP system is rather light.
Management is not looking for a rewrite.
Since you have been doing ruby on rails, your (VB/C#) ASP.NET is passable at best.
My experience
I too inherited a classic ASP system that was slapped together willy-nilly by ex excel-vba types. There was a lot of this stuff <font size=3>crap</font> (and sometimes missing closing tags; Argggh!). Over the course of 2.5 years I added a security system, a common library, CSS+XHTML and was able to coerce the thing to validate xhtml1.1 (sans proper mime type, unfortunately) and built a fairly robust and ajaxy reporting system that's being used daily by 80 users.
I used jEdit, with cTags (as mentioned by jamting above), and a bunch of other plugins.
My Advice
Try to create a master include file from which to import all the stuff that's commonly used. Stuff like login/logout, database access, web services, javascript libs, etc.
Do use classes. They are ultra-primitive (no inheritance) but as jamting said, they can be convenient.
Indent the scripts properly.
Comment
Write an external architecture document. I personally use LyX, because it's brain-dead to produce a nicely formatted pdf, but you can use whatever you like. If you use a wiki, get the graphviz add-in installed and use it. It's super easy to make quick diagrams that can be easily modified.
Since I have no idea how substantial the enhancements need to be, I suggest having a good high-level to mid-level architecture document will be quite useful in planning the enhancements.
On the business logic unit tests, the only thing I found that works is setting up an xml-rpc listener in asp that imports the main library and exposes the functions (not subroutines though) in any of the main library's sub-includes, and then build, separately, a unit test system in a language with better support for the stuff that calls the ASP functions through xml-rpc. I use python, but I think Ruby should do the trick. (Does that make sense?). The cool thing is that the person writing the unit-test part of the software does not need to even look at the ASP code, as long as they have decent descriptions of the functions to call, so they can be someone beside you.
There is a project called aspunit at sourceforge but the last release was in 2004 and it's marked as inactive. Never used it but it's pure vbscript. A cursory look at the code tells me it looks like the authors knew what they were doing.
Finally, if you need help, I have some availability to do contract telecommuting work (maybe 8 hours/week max). Follow the link trail for contact info.
Good luck! HTH.
Since a complete rewrite of a working system can be very dangerous i can only give you a small tip: Set up exuberant tags, ctags, on your project. This way you can jump to the definition of a function and sub easy, which i think helps a lot.
On separating logic from "views". VBScript supports som kind of OO with classes. I tend to write classes which do the logic which I include on the asp-page which acts as a "view". Then i hook together the view with the class like Username: <%= MyAccount.UserName %>. The MyAccount class can also have methods like: MyAccount.Login() and so on.
Kind of primitive, but at least you can capsulate some code and hide it from the HTML.
My advice would be to carry on refactoring, classic ASP supports classes, so you should be able to move all everything but the display code into included ASP files which just contain classes.
See this article of details of moving from old fashioned asp towards ASP.NET
Refactoring ASP
Regarding a future direction, I wouldn't aim for ASP.NET web forms, instead I'd go for Microsoft's new MVC framework an add-on to of ASP.NET) It will be much simpler migrating to this from classic ASP.
I use ASPUnit for unit testing some of our classic ASP and find it to be helpful. It may be old, but so is ASP. It's simple, but it does work and you can customize or extend it if necessary.
I've also found Working Effectively with Legacy Code by Michael Feathers to be a helpful guide for finding ways to get some of that old code under test.
Include files can help as long as you keep it simple. At one point I tried creating an include for each class and that didn't work out too well. I like having a couple main includes with common business logic, and for complicated pages sometimes an include with logic for each of those pages. I suppose you could do MVC with a similar setup.
Is there any chance you could move from ASP to ASP.Net? Or are you looking at keeping it in classic ASP, but just cleaning it up. If at all possible, I would recommend moving as much as possible moving to .Net. It looks like you may be rewriting/reorganizing a lot of code anyway, so moving to .Net may not be a lot of extra effort.
Presumably someone else wrote most or all of the system that you're now maintaining. Look for the usual bad habits (repeated code, variables that are too widely scoped, nested if statements, etc.), and refactor as you would any other language. Keep an eye out for recurring things in the same file or different files and abstract them into functions.
If the code was written/maintained by various people, there might be some issues with inconsistent coding style. I find that bringing the code back into line makes it easier to see things that can be refactored.
"Thousands of lines long" makes me suspicious that there may also be situations where loosely-related things are being displayed on the same page. There again, you want to abstract them into separate subroutines.
Eventually you want to be writing objects to help encapsulate stuff like database connectivity, but it will be a while before you get there.
This is very old, but couldn't resist adding my two cents. If you must rewrite, and must continue to use classic ASP:
use JScript! much more powerful, you get inheritance, and there some good side benefits like using the same methods for server-side validation as you use for client-side
you can absolutely do MVC - I wrote an MVC framework, and it was not that many lines of code
you can also generate your model classes automatically with a bit of work. I have some code for this that worked quite well
make sure you are doing parameterized queries, and always returning disconnected recordsets
Software Development Project Management practices indicates that softwares like this are requiring to retire.
I know how hard it is to do the right thing, even more when the responsible manager knows sht and is scared of everything other than the wost way possible.
But still. It's necessary to start working on the development of a new software. It's simply impossible to maintain this one forever, and the loger they wait for retiring it the worse.
If you don't have proper specification/requirements documentation (I think no asp software in the world does, given the noobatry hability of those coders), you'll need both a group of users that know the software features and a manager to be responsible for validating the requirements. You'll need to review every feature and document its requirements.
During that process you'll go learning more about the software and its business. Once you have enough info, you can start developing a new one.