Printing from a vb.net program using activereports stops working - vb6

and sorry for not exactly a programming question, but if anyone can help i thought this is the place after googling around and finding nothing.
I have to cope with a crappy (presumably vb6) .net application for printing all sorts of reports. After installing it prints Ok, but if i print using another program, this one stops printing (halts on a modal blocks telling me it is 'forming a report').
From what i gathered with exploring the .exe and the hopeless support (apparently no-one else has this problem, they cannot understand what's wrong), it uses actrpt2.dll which seems to something called ActiveReports2. If i register this dll with regsvr32 the program WILL print, and after printing from any other program i need to register the dll again before printing works on this one.
So i made a quick .bat hack for it.. But the programmer in me cannot understand why this stuff with the dll keeps happening (well ok, it's windows...) - if anyone knows what is happening, and how could it be fixed, please tell me, i would appreciate it :)

Probably your "another program" is overwriting actrpt2.dll registration, for instance by registering an older version of ActiveReports which it stores next to its exe file.
Easiest "fix" would be to run both apps (or just "another program") with non-admin rights so that it can not register (or corrupt) COM components at all.

Related

Behind the scenes of "Windows is searching for a solution ..."?

So when a program dies rather ungracefully, modern versions of Windows put up a dialog that reads:
Windows is searching for a solution to the problem
It clocks for a little while, then doesn't find anything. Well, I've never had it tell me it's found a solution.
The question is, what exactly is going on when this dialog is being shown? What are possible things it can show as "solutions"? Is there a way my application can tap into it?
Obviously, if I know enough about what could go wrong, I should handle it in the app, so I'm left wondering what this actually does.
Anyone know?
Windows Error Reporting is capturing a stack trace of the failed program and sending it off to Microsoft. The data it collects is stuffed into an enormous database for vendors to research; if this is your program, you can sign up here. If the vendor submits a patch, Windows will notify you.
You can tap into it, either by customizing the info, triggering reports for (soon to be) fatal errors, and much more.

VB6 Decompiling Problems

I got to decompile a VB6 dll, got a decompiler (actually tried 4 of them), even paid for a pro license, but of course I ran into a problem: the retrieved code doest even look like the previous one and it looks like a lot of information is lost. I do understand it's a one way road, but maybe someone could technically explain to me why VB6 compiled dll loses some info in machine code which cannot be retrieved later on in the decompilation process?
This is not possible to do unless the code was compiled with the option to compile to P-Code. For example, if you look at http://www.vb-decompiler.org/ it clearly says that it will only work with the P-Code.
The issue is that VB6 by default will compile to machine code which doesn't translate to VB6. You may be able to get the UI back because this is not code, but aside from that you are out of luck.

Vb6 application works in the IDE but the executable crashes

I have a little problem with visual basic 6 project. Everything works fine in the IDE
but the executable crashes every time, when I run the application. The application uses callbacks to communicate with a C++ dll. Even code as simple as showing a message box fails when the callback starts.
I changed the compilation mode to P-Code and still the problem persist.
Any help would be appreciate.
Thank you all
This sounds like the callbacks may be occurring on a different thread than your application is executing on. [EDIT: As I see Jim has already suggested.] If that's the case, yeah, kaboom just as soon as you "touch" anything OLE related or call into the runtime. Same story as with multimedia timer callbacks, fwiw, and I'd suspect you'll have to take the same precautions as one would with those if this is the case.
The short story with different thread callbacks is that you'll need to post a message to yourself, using PostMessage declared in a typelib so that the Err object isn't set by VB, then let the callback return. You do your own processing on receipt of the posted message. Here's the typelib I used for this with the CCRP Timers library:
http://vb.mvps.org/tools/files/postmessage.zip
Hope that helps...
Who's calling back to whom? Show us a little code.
The IDE can mask real problems, so just being able to run there is no guarantee that what you're doing is supported.
One common problem with callbacks is that VB6's runtime is not thread-safe, so if another thread is calling back into your VB code, you can't do anything that will invoke the runtime -- like access strings or objects.
There are ways around some of these issues, but I think we need to know more first.
Is the code being run from the same location as the IDE? Likely it is a reference problem, and you need to re-register the DLL.
A deployment package should make sure you have everything installed.
A few questions:
Is the executable on the same PC as it was developed, or a different one?
Does the file use a manifest file? If so, does mainfest call XP themes?
Also, if using manifest, does manifest use SXS for OCX files?

What can we do about a randomly crashing app without source code?

I am trying to help a client with a problem, but I am running out of ideas. They have a custom, written in house application that runs on a schedule, but it crashes. I don't know how long it has been like this, so I don't think I can trace the crashes back to any particular software updates. The most unfortunate part is there is no longer any source code for the VB6 DLL which contains the meat of the logic.
This VB6 DLL is kicked off by 2-3 function calls from a VB Script. Obviously, I can modify the VB Script to add error logging, but I'm not having much luck getting quality information to pinpoint the source of the crash. I have put logging messages on either side of all of the function calls and determined which of the calls is causing the crash. However, nothing is ever returned in the err object because the call is crashing wscript.exe.
I'm not sure if there is anything else I can do. Any ideas?
Edit: The main reason I care, even though I don't have the source code is that there may be some external factor causing the crash (insufficient credentials, locked file, etc). I have checked the log file that is created in drwtsn32.log as a result of wscript.exe crashing, and the only information I get is an "Access Violation".
I first tend to think this is something to do with security permissions, but couldn't this also be a memory access violation?
You may consider using one of the Sysinternals tools if you truly think this is a problem with the environment such as file permissions. I once used Filemon to figure out all the files my application was touching and discovered a problem that way.
You may also want to do a quick sanity check with Dependency Walker to make sure you are actually loading the DLL files you think you are. I have seen the wrong version of the C runtime being loaded and causing a mysterious crash.
Depending on the scope of the application, your client might want to consider a rewrite. Without source code, they will eventually be forced to do so anyway when something else changes.
It's always possible to use a debugger - either directly on the PC that's running the crashing app or on a memory dump - to determine what's happening to a greater or lesser extent. In this case, where the code is VB6, that may not be very helpful because you'll only get useful information at the Win32 level.
Ultimately, if you don't have the source code then will finding out where the bug is really help? You won't be able to fix it anyway unless you can avoid that code path for ever in the calling script.
You could use the debugging tools for windows. Which might help you pinpoint the error, but without the source to fix it, won't do you much good.
A lazier way would be to call the dll from code (not a script) so you can at least see what is causing the issue and inspect the err object. You still won't be able to fix it, unless the problem is that it is being called incorrectly.
The guy of Coding The Wheel has a pretty interesting series about building an online poker bot which is full of serious technical info, a lot of which is concerned with how to get into existing applications and mess with them, which is, in some way, what you want to do.
Specifically, he has an article on using WinDbg to get at important info, one on how to bend function calls to your own code and one on injecting DLLs in other processes. These techniques might help to find and maybe work around or fix the crash, although I guess it's still a tough call.
There are a couple of tools that may be helpful. First, you can use dependency walker to do a runtime profile of your app:
http://www.dependencywalker.com/
There is a profile menu and you probably want to make sure that the follow child processes option is checked. This will do two things. First, it will allow you to see all of the lib versions that get pulled in. This can be helpful for some problems. Second, the runtime profile uses the debug memory manager when it runs the child processes. So, you will be able to see if buffers are getting overrun and a little bit of information about that.
Another useful tool is process monitor from Mark Russinovich:
http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx
This tool will report all file, registry and thread operations. This will help you determine if any you are bumping into file or registry credential issues.
Process explorer gives you a lot of the same information:
http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx
This is also a Russinovich tool. I find that it is a bit easier to look at some data through this tool.
Finally, using debugging tools for windows or dev studio can give you some insight into where the errors are occurring.
Access violation is almost always a memory error - all the more likely in this case because its random crashing (permissions would likely be more obviously reproducible). In the case of a dll it could be either
There's an error in the code in the dll itself - this could be something like a memory allocation error or even a simple loop boundary condition error.
There's an error when the dll tries to link out to another dll on the system. This will generally be caused by a mismatch between dll versions on the machine.
Your first step should be to try and get a reproducible crash condition. If you don't have a set of circumstances that will crash the system then you cannot know when you have fixed it.
I would then install the system on a clean machine and attempt to reproduce the error on that. Run a monitor and check precisely what other files (dlls etc) are open when the program crashes. I have seen code that crashes on a hyperthreaded Pentium but not on an earlier one - so restoring an old machine as a testbed may be a good option to cover that one. Varying the amount of ram in the machine is also worthwhile.
Hopefully these steps might give you a clue. Hopefully it will be an environment problem and so can be avoided by using the right version of windows, dlls etc. However if you're still stuck with the crash at this point with no good clues then your options are either to rewrite or attempt to hunt down the problem further by debugging the dll at assembler lever or dissassembling it. If you are not familiar with assembly code then both of these are long-shots and it's difficult to see what you will gain - and either option is likely to be a massive time-sink. Myself I have in the past, when faced with a particularly low-level high intensity problem like this advertised on one of the 'coder for hire' websites and looked for someone with specialist knowledge. Again you will need a reproducible error to be able to do this.
In the long run a dll without source code will have to be replaced. Paying a specialist with assembly skills to analyse the functions and provide you with flowcharts may well be worthwhile considering. It is good business practice to do this sooner in a controlled manner than later - like after the machine it is running on has crashed and that version of windows is no longer easily available.
You may want to try using Resource Hacker you may have luck de-compiling the in house application. it may not give you the full source code but at least maybe some more info about what the app is doing, which also may help you determine your culrpit.
Add the maximum possible RAM to the machine
This simple and cheap hack has work for me in the past. Of course YMMV.
Reverse engineering is one possibility, although a tough one.
In theory you can decompile and even debug/trace a compiled VB6 application - this is the easy part, modifying it without source, in all but the most simple cases, is the hard part.
Free compilers/decompilers:
VB decompilers
VB debuggers
Rewrite would be, in most cases, a more successful and faster way to solve the problem.

How to protect yourself against shell DLLs loaded into your process?

When you use a standard Windows "file open" dialog using GetOpenFileName(), the shell will load various DLLs that it requires to display the file list, including custom ones.
In my application, I found that the DLL that TortoiseCVS uses to draw overlays on the icons was calling GdiPlusShutdown(), and so some time after displaying a "file open" dialog, the TortoiseCVS DLL would be unloaded, it would shut down GDI+ and my graphics functions would all fail!
It seems quite bad that basically any old DLL could be loaded by my application at any time and start doing random things to its state. The workaround in my case was quite simple - just restart GDI+ if I detect that it's been shut down. However had this happened on a client's machine where I couldn't debug it, it would have been a lot more challenging to figure out what was going on.
Can anybody offer any insight? What could I do to stop this from happening?
I've had to deal with the crap that Dell puts on its machines, in particular wxVault. My solution was to "simply" patch the code. Slightly tricky with DEP, but still doable. You could have a peek at Microsoft Detours, which is a slightly more structured way to do the same. You'd still have the DLL load, but at least you can stop it calling functions that it should not be calling.
At to why Windows has such a crappy mechanism, read Raymond Chen's "Old New Thing" blog or book.

Resources