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...
Related
Microsoft has multiple versions of the Defender executable (MpCmdRun.exe) installed on my computer. There is an obvious one in "C:\Program Files\Windows Defender\MpCmdRun.exe" but then two others in "C:\ProgramData\Microsoft\Windows Defender\Platform\4.18.2010.7-0\MpCmdRun.exe" and "C:\ProgramData\Microsoft\Windows Defender\Platform\4.18.2011.6-0\MpCmdRun.exe". The folders all have different versions of MpCmdRun.exe.
Per Microsoft, the latest version is the 4.18.2011.6-0 version, but how would I know this if I hadn't researched? And if I encode some dependency on this location (see below), how would I know when it's been superceded?
My goal is to create a custom scheduled task for Defender that runs full scans rather than quick scans. I tried whacking on the existing Windows Defender task definitions (in Task Scheduler -> Task Scheduler Library -> Microsoft -> Windows -> Windows Defender), but the tasks periodically modify themselves (after updates, etc.) and my changes are lost. I can readily create my own custom task, but I have to know the location of MpCmdRun.exe which, as I pointed out above, seems to move around.
Does anyone know of a reliable way to determine what the location of the latest Defender executable is, preferably easy enough to use in a command line?
Also, anyone have any clues about why Microsoft did it this way? Why not just keep the latest version in "C:\Program Files\Windows Defender"? And why leave old version laying around?
Slow down.
I found the instructions in 30 seconds.
https://learn.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-antivirus/scheduled-catch-up-scans-microsoft-defender-antivirus
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.
The app I work on is written mainly in VB6.
Some users report that when they start up my app a different MSI installer will automatically run and try to repair its own installation. Often this is for AutoCAD but sometimes other programs also.
Usually this occurs every time they start the app.
What is a procedure that we can use to diagnose why this occurs? Since it is a third-party's installer which is running we don't have any visibility into what it is doing.
AutoDesk does have some info published on this:
Unexpected installer launches
Windows Installer displayed unexpectedly
but these do not directly provide enough information. Ideally I want to be able to completely prevent this from occurring to my end users, rather than just telling them how to avoid it or clean it up.
Your installer is acting on a directory, file or registry key that Windows Installer knows is part of the AutoCad installation.
First, I would turn on global Windows Installer logging. This means that any Windows Installer activity - including AutoCad's installer - is written to an external log file (in %temp%).
How to Enable Windows Installer Logging
Next, run your installer, and let the AutoCad installer run.
Now go to %temp% and you should find files MSIXXXX.LOG - one for your installer, one for AutoCad. Open these and you can work your way through them and identify which file or registry key the AutoCad MSI find is missing or changed.
You may find WiLogUtl.exe helpful for this:
Wilogutl.exe
With any luck you will identify that the directory, file or registry key triggering autorepair is also in your installer. If you're really in luck you can identify it as an item you should not be installing anyway - perhaps you are referencing a system component that would be present anyway, something protected by Windows File Protection.
If not, you will have to look at something like RegFree COM to move files out of shared directories into your private directory and reduce registry conflicts. Also, if you are using (consuming) the Visual C++ Runtime MSMs to make your MSI, consider using the Microsoft EXE installer instead or (best of all) placing the DLLs directly in your program folder, since I've found that the MSMs can cause just this sort of problem.
With regards to Peter Cooper Jr's comment on VB6 causing self-repair. Please check out the heat.exe documentation for Wix. You will see that there is a special switch the tool supports to suppress extracting certain registry values that are owned by the VB6 runtime itself (and hence shouldn't be messed with or updated by any other MSI): http://wixtoolset.org/documentation/manual/v3/overview/heat.html
Go down the list to the switch -svb6 and read the description to the right. (Reproduced here:)
When registering a COM component created in VB6 it adds registry
entries that are part of the VB6 runtime component:
CLSID{D5DE8D20-5BB8-11D1-A1E3-00A0C90F2731}
Typelib{EA544A21-C82D-11D1-A3E4-00A0C90AEA82}
Typelib{000204EF-0000-0000-C000-000000000046}
[as well as] Any Interfaces that reference these two type libraries
Does your installer write to these keys? If so try to exclude them - this is good to do even if it isn't the culprit in this particular case.
Other than that there is a lengthy description of what can cause Windows Installer self-repair here: How can I determine what causes repeated Windows Installer self-repair?. It is a long article because there are so many different ways self-repair can occur. The common denominator is that different installers on your system are fighting over a shared setting that they keep updating with their own values on each application launch in an endless loop.
According to the Windows installation rules, programs should be installed to
C:\Program Files (64-bit program / x86-64) or C:\Program Files (x86) (32-bit program / x86). The program is copied into a sub-sub-folder containing the vendor name and the program name.
But why doesn't Chocolatey install packages into C:\Program Files\<Vendor>\<Program>\?
10. Apps must install to the correct folders by default
Users should have a consistent and secure experience with the default installation location of files, while maintaining the option to install an app in the location of their choice. It is also necessary to store app data in the correct location to allow several people to use the same computer without corrupting or overwriting each other's data and settings. Windows provides specific locations in the file system to store programs and software components, shared app data, and app data specific to a user
10.1 Your app must be installed in the Program Files folder by default
For native 32-bit and 64-bit apps in %ProgramFiles%, and %ProgramFiles(x86)% for 32-bit apps running on x64. User data or app data must never be stored in this location because of the security permissions configured for this folder.
Source: Certification requirements for Windows desktop apps
Version: 10 (July 29, 2015)
It depends on your version of Chocolatey, it's settings and the packages themselves.
To start, see Tools vs Applications and Chocolatey's distinction (
https://github.com/chocolatey/chocolatey/wiki/ChocolateyFAQs at the
bottom).
If the package does not use a native installer (a tool), it depends on
if the package author has used the bin_root concept that is up and
coming in a future version.
For example, SysInternals will go to c:/sysinternals right now unless
you have a defined $env:chocolatey_bin_root variable. The concept in
the code will change as well as right now this requires it to be a
subfolder of the system drive and I don't see us developing the final
feature with that limitation.
If the package doesn't have that concept yet, one can always ask the
package author to incorporate it.
If the package uses a native installer (an application), one can use
installArgs to pass arguments to the native installer
(https://github.com/chocolatey/chocolatey/wiki/CommandsInstall) and
tell it the directory to install the application to. This does require
you to know what you need to pass to the native installer. If you want
your applications in a custom directory, there is an assumption that
you are already an advanced user so it is expected that you would know
what to pass the installer if you were doing a silent install.
Slightly paraphrased from: https://groups.google.com/forum/#!msg/chocolatey/uucAz8GxebA/HEPAKp69d90J
Also,
NOTICE: As of 0.9.8.24, Chocolatey's default install location is
C:\ProgramData\Chocolatey
This reduces the attack surface on a local installation of chocolatey
and limits who can make changes to the directory.
Source: https://github.com/chocolatey/chocolatey/wiki/DefaultChocolateyInstallReasoning
And from personal experience I can attest that that concept is an excellent line of defense (when properly configured, used and understood).
PS:
As you already added to your answer, technically the requirement is %ProgramFiles% and %ProgramFiles(x86)% environment variable(s where applicable).
For example, %ProgramFiles(x86)% could as well point to P:\Software\Programs\x86\ (instead of C:\Program Files (x86)\).
There is obviously a lot of legacy software (now (re-)packaged) that never used a <vendor> section in the path-name.
Hope this helps!
I have an old game (Westwood Monopoly CD-ROM) that only has a 16-bit installer so it won't run on my Windows 7 x64. To get around this I decided to use Inno Setup to make a new installer. The game itself is 32-bit but not LFN aware and will run on Vista/7, however the game will crash if the installer I built with Inno Setup is not run with Windows 95 compatibility checked.
There are no file or attribute differences between the folder generated by having compatibility mode on and the folder generated with no compatibility settings checked. However, the game will only run in the folder installed with compatibility mode, the game exe (Monopoly.exe) itself cannot have any compatibility mode option enabled or the game terminates whenever you try to save, load, or choose one of the computer ai player files. If compatibility mode for 95 is turned on for Monopoly.exe in the folder created without compatibility mode set for the installer, the game will load but will be unplayable for the above reasons.
My guess is that the Windows 95 setting forces short filenames to be created, while without it the game cannot find it's files because the short filename information isn't there. Having compatibility mode set for the installer is not the ideal solution since I need to be able to copy a different exe based on the version of Windows detected (Aero causes part of the screen to be cut off so I use a hex edited exe with a bigger default size).
So my question is this: Is there a way to force Inno setup to create the short filename information as it copies, or is there a way to add that with a command after it is finished (ie. repair the broken folder so the game can find its files)?
As far as I am aware, the problem is that the newer version of Windows Installer and Windows itself no longer support the use of short names. That property has been phased out of use and as of (AFIK) Vista it is flat out not used. Most modern installer technologies will give you an error if you try to include them. Have you tried looking at DosBox? That might also allow you to run it without the need for a special installer.