How to tell VB6 where to find winhlp32.exe - vb6

I maintain a large VB6 application I would like to be able to install on Windows 10. It has a large Help file in WinHelp format. I would like to distribute winhlp32.exe (and winhlp32.exe.mui) with the application rather than replace the winhlp32.exe file in the Windows 10 Windows folder. If I put (an old) winhlp32.exe file in the application folder in Windows 10, and file winhlp32.exe.mui in a subfolder named en-US, the help file works if I enter the command "winhlp32.exe myhelpfile.hlp" in the application folder. However if I run the application exe (created by VB6), and press F1, it runs the Windows 10 winhlp32.exe stub, not the winhlp32.exe in the application folder.
Can anyone suggest how to persuade the VB6 application (before or after compiling it) to use winhlp32.exe from the application folder instead of the Windows folder?

The short story - you may be warned and you know in all it's a heavy task to migrate your VB6 app maybe without reaching a simple way for migrating WinHelp to HTMLHelp.
The official recommendation (10 years old):
Forget about WinHelp, it's history and migrate to CHM help file format.
But, maybe you already have found my answer (search for Run WinHelp on Windows10) and read all further links:
How to convert HLP files into CHM files
Please note a tool called HHPMod especially for migrating context-sensitive F1 help.
I tried the WinHelp of an old VB6 program before and after the fix from above and it is working for me on Windows 10 (Version 1803).
Another solution you may want to try (depends on your deploy and IT environment):
Windows Help Program (WinHlp32.exe) for Windows 8.1 and Windows 7 x64 and x86
Quoted from this article (thanks to Komeil Bahmanpour):
"Please note users who have tried to replace winhlp32.exe manually in Windows folder and winhlp32.exe.mui in Windows\en-US folder of Windows 7, was faced with overwrite restrictions due to ownership and permission problems."
Additional information:
I may well be wrong, but I believe that also (old) online help files are usually copyrighted as part of Microsoft Windows. Distributing the files would normally constitute a violation of copyright law (as you mentioned in your question).
AFAIK developers are not allowed to distribute the Vista version of WinHlp32.exe or included it in their installations. Every individual user who wants to use WinHelp must download the WinHelp update directly from Microsoft and install it themselves.
Help for applications has been .chm for many many years now. Microsoft released the tool HH Workshop (HTMLHelp SDK 1.4) around 1997. Around March 2006 during discussions with MVPs, Microsoft Help team announced that WinHelp would be deprecated (phased out). WinHelp is architected in such a way that Microsoft would have to rewrite it from the ground up to meet the Windows Vista code standards. Since then .CHM has been the only choice for our application help.
What does this mean (please note we are about ten years later now!):
WinHelp runtime (WinHelp32.exe) no longer ships with Windows Vista/7/8/10
ISVs (Independant Software Vendors) should stop promoting WinHelp as a viable help system.
Help authors should move over to HTML Help 1.x (.chm) if they haven't done so already.
HH Workshop is sufficient to author .CHM help files. I'm using a tool with a few more features (drag and drop TOC/Index editing etc) called "FAR HTML". Then there are high-end more expensive tools (you mentioned RoboHelp) that have advanced features such as "convert between different help systems".

Try (untested, but you should get the idea)
Shell App.Path & "\winhlp32.exe myhelpfile"
App.Path gets the executable's current path, so just make sure your winhlp32.exe file is right there with it.

Related

Comprehensive list of programs on different operating systems

How would I get a list of EVERY program into a text file for windows 95-windows 10. The uninstall programs in control panel doesn't have the version and publisher for the older operating systems, and wmic does not display every program. Even the uninstall registry, which I thought would be my savior, does not list every program. I can see discrepancies between that and the uninstall programs tab. Powershell and the like are off the table since it is relatively new.
Some combination of the following:
Enumerate registry for HKEY_CURRENT_USER\Software\Microsoft\CurrentVersion\Uninstall and HKEY_LOCAL_MACHINE\Software\Microsoft\CurrentVersion\Uninstall. And probably HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall on 64-bit os (might be duplicated). These are the list of installed programs that appear in the Control Panel's "Program and Features" section. Notice that some of the entries are straight-forward and have most of the data you want. Others are a GUID - this corresponds to an MSI installation.
For all the entries obtained in #1 that reference a GUID, use the MSI API to find the installation information you seek. Start with MsiEnumProducts. From there you can get at version info of installed applications.
Brute force search for EXEs installed in C:\Program Files and C:\Program Files (x86). For each EXE found, you can use this method to get the version information.
You want a list of applications installed from the Windows Store? Ask me for a code sample if that's important too.
The registry uninstall registration requirements in the 90's was just the display name and the command to start the uninstallation. Windows 2000 added support for more values and exposed them in the new UI but they were still optional. In recent years a couple of them became a requirement to pass the Windows Logo tests but they are still optional for non-certified applications so the uninstall key is not guaranteed to contain version/publisher information for every entry. Portable applications are not listed in the registry so if you need a inventory of everything then you need to inspect all exe files and ignore the registry.
Supporting everything back to Win95 RTM is going to be tough since you have nothing except batch files as a scripting option. VBScript is a optional component that normally gets installed with IE 4 and I don't even remember if it is possible to get Powershell on these systems.
I don't think it is possible to extract the version information with a simple batch file, you probably need the help of a 3rd-party tool. The issue with 3rd-party tools is that a lot of them depend on the Microsoft CRT run-time .DLLs and Windows 95 RTM does not have them out of the box, not even msvcrt.dll.
If you can raise your requirement for Win95 to have Windows Scripting Host installed (redistributable or part of IE4) then you could write a VB/Jscript file that uses the FileSystemObject to both walk the entire directory tree on every drive and to get version information from .exe files.
If that is unacceptable then you need to try to find a tool that can extract version information. There is a Microsoft tool named filever.exe listed here but I don't know if it works on Win95 and a NirSoft tool here but I'm not sure if it supports stdout redirection from the commandline (but it is open source so you could fix that if needed). Even if you find a suitable tool you would still need to walk the directory tree looking for .exe files and that is not going to be fun when you are limited to command.com and its DOS compatible batch handling.
My recommendation is to write a new application. I can't recommend writing it in a .NET language because you would be dealing with versions 1-4 and it is not installed on XP and older by default.
The way I see it, you have 3 options if you are writing it yourself: Visual Basic 6, Delphi (something old, v3 or older perhaps) or C/C++.
For C/C++ any version of Microsoft Visual C++ or MinGW/GCC will do but the older the better and you must not link to or use any C run-time library stuff (you might get away with static linking with MinGW but not recent versions of Visual Studio). If I was doing this I would use Visual Studio 6 or 2003 and build with /Zl & /NODEFAULTLIB. There are multiple small standalone CRT libraries if you need them. If you use any recent version of Visual Studio you will manually have to hex-edit the file to make it run on anything older than XP.
The actual implementation needs to call FindFirstFileA (and friends) on Windows 95/98/ME and FindFirstFileW on other systems to walk the directory tree and GetFileVersionInfoA/W (and friends) to get version info.
If you are feeling fancy you could perhaps filter out files in %WinDir% signed by Microsoft. Good luck...

How to unbind a Microsoft .OBD file?

I can't seem to find any way to open an old .OBD file. Our company has around a hundred of these binders that were created a long time ago by another company that we took over. They were created using Office 97 on some old machines that don't exist any more.
Our current machines run Windows 7 or later, with Microsoft Office 2010 and later. Is there a way to open these .OBD files? I've tried the Unbind.exe program that some people mentioned on other forums, but it won't run in Windows 7 with any compatibility settings. 7-zip was able to sort of look into the binders, but the files that were extracted aren't readable by any Office software.
We looked into using pywin32 to talk through COM and use Office to do the unbinding automatically, but we still need some program to actually do the unbinding.
Does anyone have any solutions? Thanks.
EDIT: I figured out the problem. The unbind.exe application (available from Microsoft) works, but only when run in a 32-bit OS. Using compatibility mode from a 64-bit OS doesn't seem to work. I was able to use a virtual machine on our servers that was set up for something else. If you don't have a 32-bit environment handy, I'm not sure on how to get around this.
I had 4 Microsoft binder (*.obd) files I wanted to open and didn't have access to a 32bit Windows computer. Please note that this method does not retain the original file names of the documents. Using Windows 10 64 bit I used 7Zip to extract the obd files to folders. Inside the folders were subfolders numbered 1, 2, 3 etc. In the subfolders were data files called WordDocument, Book and PowerPoint Document. I renamed WordDocument files to filename subfolder.doc, renamed Book files to filename subfolder.xls and renamed PowerPoint Document files to filename subfolder.ppt. Then I opened .doc files in Word 2019 and resaved as .docx files. Then I opened .xls files in LibreOffice Calc v7.2 and resaved as .xlsx files. I didn't have any luck with .ppt files. In my case I had to change Word 2019 protected view settings (File, Options, Trust Center, Trust Center Settings..., File Block Settings, untick Word 2, 6.0 & 95). Hope someone finds this info useful.

How to make app portable?

I have standard instalations of some programs, and althou they are freeware and i can download them and install on any machine, things are not that easy always. When system crash and i dont have working machine or working internet connection or lan card or drivers for lan card i always struggle to find them and make them work if some dependency file is not on that version of windows.
What i need is to know is how can i make applications portable so i can run them from my usb or just copy them from my usb on pc and run, what dependency files application require, and what files and where specific application install?
It's a complicated story but let's try to summarize. Starts from the part "why?"
I'm an obsessive guy who seriously "hates" installers. I love to have a clean system without bloated in files reg entries and DLL's. Thats why I make nearly all (at least 97%) of programs that I use portable. I made more than 600 up to today and what I can say is;
You need:
1- A program to watch file system (what included after installation)
I use this. Simple and straight (sorry not freeware, but you can find tons of alternates)
http://www.samsunsegman.com/um/
2- A program to watch registry (what changed or included after installation)
I use this in HTML mode. Free fast and simple. And portable in nature.
http://sourceforge.net/projects/regshot/
Now scan the system with these 2, and than run the installer. After open the installed program and make your settings as you want. And than use this 2 program to find the added files and registry entries.
For files, delete them to trash can and take them back from trash in batch (easy to do like that) to the folder of application.
Registry, open the related branches in registry, delete any entries containing addressings like (plugins folder = c:\prog.... etc) After right click on main branch and select export. This is your reg settings...
3- Download this program http://ctuser.net/?reg2exe
This will convert your reg file to an exe file.
4- Download this application http://download.cnet.com/FilePacker/3000-2216_4-10414081.html
Note: Click on "Direct Download Link" if not you'll cnet will welcome you with their installer :)
And with this program (I use this because have no interference with any application) pack the program that you want to make portable. In wizard, first choose your reg-exe file after main programs file. Launcher will execute them with this order. And in setting choose "delete after terminate" will delete the extracted files on exit.
You can discover the further details. This helps you to portabilitize nearly 75% of simple applications.
5- For complicated programs or complicated needs you even can make home made loaders like
Before executing the app, put the user files under appdata folder (that I hate)
Put settings in registry (even with dynamically modified "path" addresses)
Choose which to execute (x86 or x64)
Execute in admin mode if needed
Execute the app... And when application is terminated...
Delete the settings from registry
Take the user files from appdata folder and put under programs folder (usb etc) back.
Delete left-over files under the system...
I just wrote these last ones to make you understand how far you can go. And for all these extra tricks, I use just and just bat files. And I convert them to exe also with this software. http://www.f2ko.de/programs.php?lang=en&pid=b2e (also free)
All the softwares that I use except "uninstall manager" are free. And with this technique, amazing but some of programs are running even faster.
Actually you can just use JauntePE or portable apps packer things but... Jaunte and similar sandbox making programs are so slow and not compatible with all. Even causing crashes. Portable apps approach is a bit bloated regarding to my strict spped and size standards. That's why I do it myself about for 10 years (yes even people was not talking about portability)
Note: I'm not a programmer, and you also don't need to be to do these.
I never released my portables, and you also shouldn't (read EULA's) for respect to authors.
But never forget to demand portable version from all authors. Force them to quit installers ;)
Best regards
inovasyon did a great job!
If you want to make some portable app that will work on every computer you move it to, then 99.9% of apps can be made portable.
If you also expect the app to not leave any files, folders or registry entries behind and not change or break things on the host PC's setup, then that limits things a bit further.
Apps requiring admin privileges to write to protected areas of the registry or file system will break when used on PCs with locked-down privileges.
Apps requiring services to be installed on the host PC will often leave them behind.
You must to know there are apps that are locked to specific PCs - Microsoft's recent versions of Office are a great example of this. They simply will not run when moved to another PC.
Also, you'll need some tools for making portable app: cameyo, thinapp, boxedapp, portableapps, spoon, app-v and other.
Portable applications will run from a flash drive, and from the computer.
Good Luck!
Here is a primer for setting up a portable app using the PortableApps.com tools. They have a page for developers that is quite helpful for some specifics, but the overall process is not well summarized. Here is the general outline for creating a portable application:
1. Investigate your application's footprints
Find all the files, registry locations and settings of the application you want to make portable (make use of point (1) and (2) in inovasyon's answer, and maybe take a look at Zsoft). It is usally a good idea to fire-up a virtual machine and track the application's changes without much clutter.
2. The PortableApp generator
Download, extract, and open the PortableApps.com Platform, and follow [The system tray icon] →[Apps] →[Get More Apps] →[By Category] to install the PortableApps.com Launcher, and NSIS (Unicode) needed to Portabilize your app. Alternatively, but with some added hassle, download both the PortableApps.com Launcher and NSIS Portable (Unicode version) as standalones.
You can now compile a project by running the PortableApps.com Launcher and pointing it to your project.
3. PortableApp layout and structure
Download the PortableApp.com Application Template (search for it here) to structure the data and files obtained in (1.) according to the specifications. Also, download some apps from portableapps.com for some practical examples of how they are structured, and to learn more about the struggles of portability (such as the substitution of drive letters in settings files to correspond to the movement of a portable drive).
As a "Hello World" example, try portability this simple program: helloworld.bat, with content:
#echo off
echo Hello World > log.txt
It writes all local environmental variables to the log file log.txt. You can play around a bit by trying to writing files to an %APPDATA% subdirectory and see if you can make your project redirect it to a portable directory.
4. Additional usage
If you need to do some additional coding that is not achievable with the default .ini capabilities (such as forcing only one instance of an app), add a NSIS script with file location App\AppInfo\Launcher\Custom.nsh to your project. Note that PortableApps.com's custom code guide incorrectly states the file location as Other\Source\Custom.nsh. It is also quite unhelpful regarding the layout of this script. Rather look at examples from other Apps and learn the NSIS syntax by Google-ing a bit.

Creating a new installer for an old VB6 program

Recently my boss told me that he wants a new installer for his program he created in Visual Basic 6 back in 2001, moreover he said "he want's it to be like one of those Adobe installers".
so to make a long story short, for the past few days I've been using everything i could find but none of the solutions I've found(mostly software) yielded any results
To clarify, he specifically told me to do it without the source code of the program
all i have to work with is the programs actual installer (which is not even .msi) the .CAB file of the program and a file folder where he keeps some support files for the actual installation method.
Your old setup is PDW based and should have a Setup.lst file which lists all the files, where and how to install them.
This can easily converted to an Inno Setup script that provides a much nice and more up to date "installation experiance" than the PDW can natively.

How do I make my program work in Windows Vista and Windows 7?

I have an application written in Delphi 2006 that was working fine in Windows XP. I packed the application using Inno Setup, using Program Files as the default folder. A few users migrated to Windows Vista and Windows 7. The issue here is that the application creates some files inside its installation folder by its own. This was working in XP but in Windows Vista the users were having problems with the created files (they don't appear and so on). After investigating the users' reports I discovered KB 927387: "Common file and registry virtualization issues in Windows Vista or in Windows 7."
Running the application with administrator rights just solves the problem, but that is (I think) an awful workaround. I would like to know if there are any directives or tips for making the application compatible with Vista and 7, because more users will migrate to these OS soon.
You need to re-write your application to store its files in the proper locations, even in XP, but especially in Vista onwards, particularly if UAC is enabled. This is becoming more and more important to get right as Microsoft keeps locking down and enforcing its security models with each new OS version. The rules for how to properly manage application- and user-related files is documented on MSDN, for example: "Application Specification for Microsoft Windows 2000 for Desktop Applications, Chapter 4: Data and Settings Management" and "Application Specification for Microsoft Windows 2000 for Desktop Applications Appendix A: Best Practices" (yes, they are old, but are still quite relevant). Look at SHGetSpecialFolderLocation(), SHGetFolderPath(), SHGetKnownFolderPath() and other related functions to help you.
For Vista/Win7, your app can't put the files in a subfolder of Program Files / Programs unless UAC is turned off or the app is running as elevated. Note that "elevated" does not necessarily mean "logged in as Administrator." Non-administrator users can elevate, and Administrator isn't necessarily elevated.
If the app does attempt to write to Program Files but is not elevated, the OS will either block the app or "virtualize" the write (put the files somewhere else), depending upon how UAC is configured. Neither one helps the app succeed at what it was trying to od.
So it needs to put them somewhere else. Where depends on why the files are being created, and you haven't told us that. You can read this article to learn about the options. Note that in addition to the user's AppData and Roaming folders, there is also an "All Users" (shared) profile.
You should probably look at this article and screencast, which discusses UAC in depth from a Delphi point of view.
Files you create for use by your application other than at installation time should go into the ProgramData directory if its global to the workstation, or into the users ApplicationData directory if its specific to the user.
For cases where you absolutely must place a file in the program files directory, you can use com to request elevation. This is discussed in great detail, and delphi specific bits are also available. One example that I have used this is in patching my users installation base. They are warned by UAC that the system needs to make changes, so if your doing this as an automated task, you might need to rethink the logic to be more user driven.
Here is another article, by Zarko Gajic, which shows how to get different system directories. Also have a look at this related question.
I had a similar enquiry here (Stack Overflow).
In the end I realised that I needed to put my application into Program Files at install time (requiring UAC/elevation) and then store my app's data in the user's App Data folder. I had to change the way my program generated 'default' configuration settings and also where I was saving this stuff, but it was worth the effort in the end - we ended up with something that installs and runs fine on XP, Vista and Windows 7.
The only UAC hit we get is at installation time, which makes sense to me (and you get a similar hit at install-time on the Mac too). We didn't have any data that would be common to all users in this particular case but I would have looked at the Program Data special folder if that had been the case.
The installer software we use (Setup Factory) made this fairly straightforward (we just wrote a small bit of code to detect XP versus Vista/Win7 and choose the right special folder accordingly). It would be easy to do this in Inno Setup too, from what limited experience I have of it.

Resources