views:

1062

answers:

5

I have a C# application that uses the built-in MSI builder in Visual Studio 2005.

After deploying the application using the MSI (via CD) onto the target computer, I launch the Desktop shortcut (as privileged user) and the program runs as expected. But, if I log out and then back in as an unprivileged user and try to run the application, the computer starts looking for the MSI because it wants to fix/configure it. Of course this fails because it can't find the MSI again.

I can, however, browse to the application's folder in Program Files and copy a shortcut to the desktop and run that perfectly fine.

How dow I get around this? I've changed a number of settings trying to get around this without luck.

EDIT: I have InstallAllUsers=True set.

A: 
Joel Coehoorn
Yeah, I have InstallAllUsers=True set.
Steve Kalemkiewicz
Yes, I MS Office still seems to exhibit that *feature*. I'm trying to stay away from doing manual setups like that since this is being deployed on a workstation with many users without knowing who they will be in advance.
Steve Kalemkiewicz
A: 

Basically the desktop shortcut is a special shortcut that triggers windows installer resiliency check - trying to restore for missing files, folders and registry entries.

Most likely I'd say you've got some per-user registry entries (HKCU or HKCR) that are missing and so Windows Installer tries to find the MSI to recreate them.

sascha
Yes, I suppose that might be true but I'm not creating or modifying any explicitly as part of the setup/MSI.
Steve Kalemkiewicz
A: 

EDIT Jun 2010: The MSI I created was under VS 2005 on Windows XP. When I tried to use the same MSI to install/uninstall under Vista, the uninstall was not very clean. I have not assessed the extent or cause, but I don't recommend using this solution on Vista without further investigation.

ORIGINAL POST:

I've still not found a real solution to my problem although the workaround -- a bit of a hack -- works well enough for my purposes. I found the suggestion on some other site (I will post a link to it if I can ever find it again).

I created a VBS file that has two functions: one creates a shortcut and the other creates the directory structure as necessary. When the file executes, it calls MakeShortcut as many times as the developer sees fit.

The second VBS file works the same way but deletes the shortcuts.

I call the first file as part of a Custom Action (right click on Setup project, VIEW, CUSTOM ACTIONS) in the Install folder. I call the second in the Uninstall folder.

The problem is that the two VBS files get installed into the target directory as well as the rest of the program. There is probably a way to get rid of them but I really don’t care that they stay there. Again, this is a bit of a hack and not as elegant as I was hoping but it works well enough until I can find a better solution.

Here are the two files in case anyone wants to use them:

'CREATE SHORTCUTS.VBS

MakeShortcut "%AllUsersProfile%\Start Menu\Programs\My Prog Folder", _
             "My Prog", _
             "%ProgramFiles%\My prog\prog.exe"


Function MakeShortcut (location, text, target)

    Dim objShortcut
    Dim objShell
    Dim expLocation

    Set objShell = CreateObject("WScript.Shell")
    expLocation  = objShell.ExpandEnvironmentStrings(location)
    expTarget    = objShell.ExpandEnvironmentStrings(target)

    MakeDirectory(expLocation)

    set objShortcut = objShell.CreateShortcut(expLocation & "\" & text & ".lnk") 
    objShortcut.TargetPath = expTarget
    objShortcut.Save
End Function


Function MakeDirectory (newPath)

    Dim objFSO
    Dim arrPath
    Dim length
    Dim count
    Dim path

    Set objFSO = CreateObject("Scripting.FileSystemObject")

    If objFSO.FolderExists(newPath) Then    
        Exit Function
    End If

    path = ""
    count = 0
    arrPath = split(newPath, "\")
    length = ubound(arrPath)
    While count <= length 
        path = path + arrPath(count) + "\"
        count = count + 1
        If Not objFSO.FolderExists(path) Then 
            objFSO.CreateFolder(path)
        End If
    Wend
End Function

DELETE SHORTCUTS.VBS

DeleteShortcut "%AllUsersProfile%\Start Menu\Programs\My Prog Folder", _
               "My Prog.lnk", _
               True


Function DeleteShortcut (location, shortcut, delLoc)

    Dim objShortcut
    Dim objShell
    Dim expLocation

    Set objShell = CreateObject("WScript.Shell")
    Set objFSO   = CreateObject("Scripting.FileSystemObject")
    expLocation  = objShell.ExpandEnvironmentStrings(location)

    DeleteDirectory(expLocation)

    If objFSO.FileExists(expLocation) Then
       objFSO.DeleteFile expLocation & "\" & shortcut
    End If 

    If delLoc = True Then
        DeleteDirectory location
    End If

End Function


Function DeleteDirectory (path)

    Dim objFSO

    Set objFSO = CreateObject("Scripting.FileSystemObject")

    If objFSO.FolderExists(path) Then  
        objFSO.DeleteFolder path, True
    End If
End Function
Steve Kalemkiewicz
I guess this answer was accepted before Julien N's answer was posted. Notice that Julien N's answer is far better than this one. Julien N's customers can use any language version of Windows.
Windows programmer
Yes, as I commented to Julien N's response, I needed to solve the problem quickly. I've changed the accepted solution to his.
Steve Kalemkiewicz
+3  A: 

As explained here, the Visual Studio can only create "advertised shortcuts" that uses the MSI file to check that all the files and registry values are present.

In the same link you can find the solution : edit the MSI database to add a value in the Property table. I tested it, you just have to add "DISABLEADVTSHORTCUTS" with the value "1".

To add it, you can use the ORCA tool which is part of the Windows Installer SDK. This is the manual way... And I suppose you won't like it.

So I looked further and found that you can do that with a command line and a VBS script provided by the Window Installer SDK :

Cscript WiRunSQL.vbs Test.msi "INSERT INTO `Property` (`Property`.`Property`,`Property`.`Value`) VALUES ('DISABLEADVTSHORTCUTS',1)"

Now you just have to set a post build event for your setup project (it's a little different from "regular" projects, see here) in order to execute this script.

It works very well for me !

Additional resources :
MSI property table reference
Edit MSI with command line

Julien N
This is actually exactly what I was looking for. I ended up using my own solution (below) for what I was working on at the time because time was short. However, I've used your approach for an older installer package I've subsequently had to modify and will use it in the future! I was pretty excited that now only did you solve the problem, but you also told me how to automate it! Thanks!
Steve Kalemkiewicz
A: 

If the MSI writes any registry entries to HKCU, then when a new user runs the app for the first time, Windows Installer sees that the entries aren't present for that user and tries to create them. Why Windows Installer thinks it needs the original MSI file for this is beyond me (the stub in C:\Windows\Installer should be sufficient, yet doesn't seem to be).

In any case, replacing the shortcut isn't a complete shortcut, since other operations, such as invoking COM components, can invoke the same self-healing process that the advertised shortcut invokes.

Edward Brey

related questions