3

I'm creating an MSI using WiX, and that MSI accepts as a user-input property, the path to a file name that the installer logic will be using. I'm trying to validate the property by determining whether that file exists, but with a full file path I can't figure out how to get that to cooperate with the DirectorySearch and FileSearch pattern.

So, say the user runs the MSI like: msiexec /i myinstaller.msi CUSTOMFILE="C:\test\input.txt"

I would then need to run something like:

<Property Id="CUSTOMFILEEXISTS">
  <DirectorySearch 
    Id="LocationConfigDirSearch" 
    Path="[CUSTOMFILE_DIR]" Depth="0">

    <FileSearch Name="[CUSTOMFILE_FILENAME]"></FileSearch>
  </DirectorySearch>
</Property>

But I:

  1. Can't figure out how to split the filename into its parts. Something like Path.GetDirectory([CUSTOMFILE]) and Path.GetFileName([CUSTOMFILE]) would be ideal. or;
  2. Can't figure out how to determine whether the file exists using the full file name as-is. Say for example, a property on DirectorySearch for IgnoreFileName="true", but I know such a property does not exist.

Do I need to go to the extent of writing extension code or a custom action? I'm hoping this is a simple enough requirement that it won't need to go that far.

Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164
Snixtor
  • 4,239
  • 2
  • 31
  • 54

3 Answers3

1

The FileSearch element is an abstraction for the Signature table in Windows Installer. The FileName column doesn't support the Formatted data type so you can't put a property in that attribute.

What you might be able to do is standardize on a fixed filename and have the user provide a property with the directory path rather then the file path. Then I think you'd be able to use AppSearch to find a file in that directory without writing a custom action.

Otherwise a custom action to do simple discovery without any state changes isn't the worst thing in the world. Just be careful to not introduce any hosting fragility. ActiveScript (VB/JScript) support in Windows Installer is notoriously fragile. I find C#/DTF managed custom actions acceptable but not everyone does. That leaves C/C++ which can be very solid but harder to code. This is a simple CA so it should be pretty straightforward.

Christopher Painter
  • 54,556
  • 6
  • 63
  • 100
  • Though this doesn't bring any new ideas to the situation, it's a rational enough assessment of the options that I'm going to accept it as answer. The inner-workings detail on the `FileSearch` element is appreciated too. Pointing out the dangers of ActiveScript custom actions is also wise. – Snixtor Jun 19 '14 at 04:26
0

Checks that don't make any changes to the target system are actually OK to perform via a custom action VBScript. As long as there are no system changes, there is no need for a rollback feature and a script is actually normally easier to use than complex file searching mechanisms. Just make sure to keep the script simple, and test it well.

A question that comes to mind is what is inside this text file, though, and how it is specified for the install session. Do you just pass it on the command line, or is there a browse dialog to specify the path?

Here is just a simple check file script from a script repository:

Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists("C:\FSO\ScriptLog.txt") Then
    Set objFolder = objFSO.GetFile("C:\FSO\ScriptLog.txt")
Else
    'Wscript.Echo "File does not exist."
End If

Note that I don't think you can call Wscript in a VBScript custom action. You will, however, have access to the MSI file's Session object in immediate mode. Deferred mode access is more difficult as explained here, but that's sort of out of scope for the use you indicate.

Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164
  • Sorry, script custom actions are never OK. True, you don't have the complexity of transactional state change to deal with but I can't tell you how many times I've seen script custom actions fial in the way Rob talks about or in that the FileSystemObject was corrupt. Just don't go there. http://blogs.msdn.com/b/robmen/archive/2004/05/20/136530.aspx – Christopher Painter Jun 18 '14 at 12:31
  • This isn't accurate - simple, read-only VBScript custom actions work OK. We use them all the time in large companies doing repackaging. Granted that is a standard operating environment, but it is just as error prone as any other machine. You recommend .NET custom actions yourself - very error prone, and they rely just as much on an uncorrupted system? I normally do things in C++ for high profile setups that are hitting lots of machines with read-write code. This script is just inspecting. – Stein Åsmul Jun 18 '14 at 13:51
  • "Standard operating environment" is the key. When you get out into the wild with different policy, different antivirus, different O/S builds it all changes. Trust me, I've been doing this for 18 years. :) I believe my answer below is a "no custom action" based design or otherwise use C/C++ that we both agree on. – Christopher Painter Jun 18 '14 at 14:19
  • This isn't as clear cut. This is a read-only file inspection script. It isn't doing anything on the system, and I would accept its use even in high profile setups. A VBScript is also transparent and can even mean your software is easier accepted for corporate use. No fanaticism or fanboyism should decide, just rational thinking and evaluation of benefits and drawbacks. A simple cab extraction can trigger an anti-virus problem, we use them anyway. – Stein Åsmul Jun 18 '14 at 14:45
  • Let me also add that I am against any script or custom action that performs actions easier and more reliably implemented via standard MSI mechanisms. However, scripts are OK to inspect the system, set properties and do read-only stuff. Never had problems when using scripts like this. – Stein Åsmul Jun 18 '14 at 14:48
  • Be my guest. I've spent enough of my life chasing down error 1720 and 1001 error messages to know what technologies to avoid for even the simplest of custom actions. DTF custom actions are transparent also. It's clear that you and I have different levels of acceptability. Rob would be a 10 on the purity scale, I'm a 9.9 and you are a 9.8. :) – Christopher Painter Jun 18 '14 at 14:51
  • Not to worry, we generally agree. We had such a discussion before on admin installs - you were wrong then too ;-) http://stackoverflow.com/a/5751980/129130 – Stein Åsmul Jun 18 '14 at 15:44
  • "And don't get me started on CAB files and anti-virus... " and yet you use VBSCript and extract CABS. Tsskk.... – Christopher Painter Jun 18 '14 at 15:59
0

Without running a custom action to search the system explicitly, whatever the language, another choice would be to write code to create your own AppSearch in the running MSI file. The key would adding the file to the Path table in the DrLocator table. You'd do this before AppSearch of course.

I don't think it would be a big deal to say that file must have a fixed name and be located somewhere such as next to the MSI file or in the user's AppDataFolder, then you can do an AppSearch for the specific file based on [SourceDir] or [AppDataFolder]

Is this a silent install? Is there a reason why you can't add a custom dialog to browse to the file?

PhilDW
  • 20,260
  • 1
  • 18
  • 28