MSI Installer and custom folders - installation

I have an interesting problem. I created a MSI Installer for a .NET 3.5 Application. During the install process I ask the user for a custom folder name where application output files should be stored.
To solve this task I have added a "Textboxes A" user interface item. I assigned TextBox Edit1 a property.
This property I used in "Registry" view to store that path in the registry - that worked. But:
I also used this property in the "File System" view to specify the target folder.
The result is: registry is stored correctly. But the installer created always a directory which is named like the default value of the Textbox Edit1. I've changed that name to ensure that there is no place where I could get that value.
I seems that the property is not being updated by the installer UI although the registry value is set correctly.
Does anyone had the same or similar troubles and found a solution/workaround?
Thanks, Arthur
EDIT: If I change the order of the UI Items (Ask for custom folder first, then ask for the target folder) it works. But this is - what should I say - not a solution. It's a sad workaround.
EDIT: With Edit1 I mean the Edit Control 1 of the "TextBox View A" which is bound to the Property "DATAFOLDERPROPERTY".

A verbose MSI log should tell you more about what exactly is happening. There are two things that jump out at me. One is that your property, Edit1, is not a public property. For it to be public, all letters must be upper-case, e.g. EDIT1. The other is that you are trying to edit a folder location after CostFinalize has set directory locations. To update directories at this time, you cannot merely change their associated properties. You need to add a Set Directory custom action (type 35) to the sequence or a SetTargetPath control event to the dialog - I'd use the control event if possible.

Related

Adding a context menu item in Windows for a specific file extension

I am trying to add a context menu item to a DLL file. The reason is that I have written an application which retracts and deployed a managed DLL file to the GAC. The application is all good, but now I want the ability to right-click a DLL and just click "copy to GAC".
I've tried to follow instructions as per this question: How add context menu item to Windows Explorer for folders but to no avail. When I right click a DLL, nothing new is appearing.
I've also tried the following: https://winaero.com/blog/add-register-dll-context-menu-commands-for-dll-files-in-windows-10/#comment-22928 - ran the reg file but no result as well.
Maybe there's a hardcoded restriction on DLL files for such actions?
Here's my current registry setup:
Any guidance would be appreciated.
The general steps to achieve this are as follows:
Fire up regedit
Identify the ProgID for your extension - go to HKCR\.yourextension and take note of the default value (in your case, dllfile)
Navigate to HKCU\Software\Classes (for user) or HKLM\Software\Classes (for all users)
Look for a matching key (in your case dllfile) - if it's not there, create it
Ensure it has a sub-key called shell
Add a sub-key to shell named as the command you want (refer to image below)
Add a sub-key to your new key called command
Modify the (Default) value to be the command you want to execute. %1 will give you the path of the file in context (remember to wrap it in " due to potential white-space in the path)
You seem to have done all the above, so you may be doing something wrong, as this is my result after a quick sanity test:
So, here are a few things I can think of that would make it behave non-intuitively:
You're adding this to HKLM rather than HKCU - due to how inheritance works, I do believe adding it to HKLM would require a restart, or at best, a shell restart
You've added this to HKCU but your dll requires elevated permissions to access
You have some silly syntax error somewhere ;)
The sample command I used to test this was a good old boring "C:\Windows\notepad.exe" "%1"
This is based on andromeda947's answer here:
If you have admin rights you can use HKEY_CLASSES_ROOT\SystemFileAssociations\.yourextension, which is simpler as it doesn't require an intermediate ProgID.
Option 1: edit the registry manually
add a new key at HKEY_CLASSES_ROOT\SystemFileAssociations\.yourextension\shell\your menu entry text\command creating any keys you need to in that path (if there's not one for .yourextension add it; if there's not one for shell add it; etc)
set the default value for command (the last key you created) to C:\path\to\yourapp.exe "%1"
Option 2: I made a tool to do this
you can download it here. This is an example of how to register notepad.exe as a context menu item for dll files.
regwincontext.exe dll "notepad it" C:\Windows\notepad.exe

Update Edit Field with property set by FileBrowse dialog

I have an Edit field that begin's empty. The user uses a button that launches the FileBrowse dialog and allows them to choose a file. This is all working, the file is stored into a property and the functionality is as intended.
However, the Edit Field is not being updated once the user chooses the file. Going forward then back a dialog shows the property in the field, but I can't ask the user to do this. I have read that this is an MSI limitation and was wondering if there are any ways around it.
Essentially I need to "refresh" the dialog, or at least the edit field control after the user chooses their file.
Thanks
This is indeed a limitation from Windows Installer. The only solution to overcome this from an MSI package is to use the twin dialog method.

How to add an entry in the Windows context menu for files with a specific extension?

I know that many questions are asked about how customizing the shell context menu, but what I've tried yet doesn't work so I'm adding a new question.
I'd like to add an entry "Open with Log Viewer" in the context menu when right-clicking on files with ".log" extension, to not change the default application associated with .log files (notepad) but allow the user to choose a custom application to open them.
To do this, I opened the registry key HKEY_CLASSES_ROOT\.log, and added some keys shell\OpenWithLogViewer\command with the correct values, but the entry is not displayed when I right-click on a file with .log extension.
Would you know how to fix this?
The key HKEY_CLASSES_ROOT\.log has for default value txtfile, and contains a subkey called PersistentHandler. Can this subkey be the origin of the problem?
Add another registry key (e.g. HKEY_CLASSES_ROOT\logfile), create the shell structure below that key and change the default value of the .log key to logfile. One way to do this is by saving the following lines to a .reg file and merging that file into the registry.
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\.log]
#="logfile"
[HKEY_CLASSES_ROOT\logfile]
[HKEY_CLASSES_ROOT\logfile\shell]
#="OpenWithLogViewer"
; make OpenWithLogViewer the default action
[HKEY_CLASSES_ROOT\logfile\shell\OpenWithLogViewer]
#="Open with &Log Viewer"
; set label and access key
[HKEY_CLASSES_ROOT\logfile\shell\OpenWithLogViewer\command]
#="\"C:\\path\\to\\logviewer.exe\" %1"
This separates the type (logfile) from the extension (.log). That way you can define the possible actions for a type in one place and associate arbitrary extensions with that type.
Note that you can also define this on a per-user basis by using HKEY_CURRENT_USER\Software\Classes instead of HKEY_CLASSES_ROOT. User entries take precedence over system entries. This is useful when you want to change file associations or add custom actions for your own user, but don't have admin privileges on the system.
If you want to add a entry for a file extension you don't "own" and you never want to be the default action then you can use the SystemFileAssociations key:
[HKEY_CLASSES_ROOT\SystemFileAssociations\.log\shell\mycommand]
#="My Command"
[HKEY_CLASSES_ROOT\SystemFileAssociations\.log\shell\mycommand\command]
#="\"c:\\path\\myapp.exe\" \"%1\""
To deal proactively with the consequences of a change to default programs, you can use HKEY_CLASSES_ROOT\SystemFileAssociations to register verbs and other association information. Due to their location after the ProgID in the association array, these registrations are lower priority. These SystemFileAssociationsregistrations are stable even when users change the default programs, and provide a location to register secondary verbs that will always be available for a particular file type.
This key is available on Windows XP and higher...

How do I specify a custom special folder for a setup project?

I know how to add a special folder to "File System on Target Machine" and make it a custom folder. I create one called "Program X" for example. The msi gets passed a parameter, 'ProgramXInstallPath', at the command line which is set to 'D:\SomeFolder\ProgramX'. I use the method from the following link to get and set the parameter in another project that I have for custom actions.
http://www.codeproject.com/KB/install/command_lines_setups.aspx
How do I set the location of my custom folder to the value of the parameter, 'ProgramXInstallPath' that was passed into the msi?
I played around some more with my setup project and the "Property" property on Special Folders and ended up getting no where. I found a solution of setting the "Default Location" for the Special Folder to the parameter that I pass into the msi, '[ProgramXInstallPath]'. Make sure that you have the square brackets.

How to find out defaults when executing MSI with /qn (silent mode)?

When I run an MSI (without parameters) I usually have to click my way through dialog boxes and choose if I want to install to current user/all users, the target directory, etc etc.
What happens when I run the MSI with /qn (silent mode). How do I find what answers where automatically chosen for all those dialog boxes?
An MSI is a basically a database. You can use Orca to open it and view/change settings.
Information on Orca can be found
here.
A quick walkthrough on how
to use Orca can be found here.
Somewhat pertaining to your
question, you can edit which users
the installer will install in silent
mode. Information is here.
I hope this has at least geared you in the right direction.
Edit:
For instance, download the installer for WiX 3.0 and open it in Orca.
Go to the Property table and you will see a list of public (uppercase) and private properties.
Notice that the WIXUI_INSTALLDIR property is set to APPLICATIONFOLDER.
Go to the Directory table, you'll see that APPLICATIONFOLDER is set to have a default of "vqee3ld3|Windows Installer XML v3" or something similar.
To find which dialog sets this property, go to the ControlEvent table. Here, you'll see the InstallDirDlg fires the event SetTargetPath when the user clicks the Next control. The Argument this event sets is WIXUI_INSTALLDIR, which in turn sets APPLICATIONFOLDER
You could try editing these properties and running the installer to see how the properties are changed. If you have default properties you'd like to set you can run. For instance, close Orca to release the lock on the msi file and run:
msiexec /i Wix3.msi APPLICATIONFOLDER="C:\Program Files\WiX" /qn
More on MSI table structures in this powerpoint
It is correct that you can set PUBLIC properties via the command line. These properties are always uppercase, and generally always listed in the Property table, though this isn't guaranteed to be the case. By reviewing the Property table you should be able to decode what each public property does. If not, there is usually documentation accompanying the MSI in form of a PDF or readme.txt that can help.
With the right tool you can also view the details of each MSI dialog and check the events that have been defined to set them. This requires a tool such as Installshield or Wise.
Another possible option for silent installation is a built-in MSI feature that I have just become aware of: the AdminProperties property. See information here: http://msdn.microsoft.com/en-us/library/aa367542(v=vs.85).aspx

Resources