Windows Develop Bookmark and Share   
 index > ClickOnce and Setup & Deployment Projects > ClickOnce Won't Update a Application if it's passed command line arguments. Bug?
 

ClickOnce Won't Update a Application if it's passed command line arguments. Bug?

I have a ClickOnce application deployed to many workstations in my office. On it's first run it adds a registry key to the HKCU run group that adds itself with a "-minimize" argument. On each login the program starts and seeing the command line argument minimizes itself . However when a update is published the program does not update. If the program is run from its menu shortcut without arguments it runs fine. I then looked up how to update programmaticaly and put that code into my program to run at startup but a my.application.isnetworkdeployed returns FALSE when command line arguments are passed to the app and TRUE when run without command line arguments even though in both cases it is network deployed.

Since my program starts up with command line arguments and stays minimized while the computer is on there is no reason for a user to close the program and reopen it through a menu item but as of right now that's the only way the program updates. Is this a bug or how ClickOnce is supposed to work?

Example: Create a new program. On the form add a textbox. In the Form load event put something like:

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
TextBox1.Text = My.Application.Info.DirectoryPath.ToString & "\" & My.Application.Info.AssemblyName & ".exe"
MsgBox("Is my app network deployed?: " & My.Application.IsNetworkDeployed)
End Sub

Deploy the app. Start it with a menu item and it returns True. Start it with any command like argument (use the path from the box) and it returns false. Why? How is that possible? The app didn't magically become non network deployed because it was passed a command line argument. How do I "fix" this?

-Allan

Note: VS 2008 SP1 (VB.Net) - .Net 2.0
  • Edited bySprint Thursday, July 09, 2009 2:37 PM
  •  
Sprint  Thursday, July 09, 2009 1:21 PM
Hi Allan,

The shortcut to an installedClickOnce application in the Startup menu is an application reference (.appref-ms). When you open this shortcut, it actually launch the ClickOnce application using a URL. If you open the .appref-ms file with Notepad, you'll see the .appref-ms file only contains a URL toa .application file.

The file path shown in the TextBox is the ClickOnce isolation store on the client machine where the installed ClickOnce application is installed. The ClickOnce isolation store is considered private to the implementation of ClickOnce, so it's not recommended to run the .exe file from the ClickOnce isolation store directly. If you do like that, the application will run only as a normal program and ClickOnce functionality won't work in this case.

To pass parameters to a ClickOnce application, you can append "?paramname=paramvalue". For more information, please visit the following link:
http://msdn.microsoft.com/en-us/library/ms172242(VS.80).aspx

Hope this helps.

Sincerely,
Linda Liu
Please remember to mark the replies as answers if they help and unmark them if they provide no help. end us any feedback you have about the help from MSFT at fbmsdn@microsoft.com.
Linda Liu  Tuesday, July 14, 2009 9:41 AM
My "solution" to this problem

    ''' <summary>
    ''' Update Run on Startup - Updates our registry key based on our settings
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub UpdateRunOnStartup()
        If My.Settings.RunOnStartup Then
            Dim myShortcut As String = My.Computer.FileSystem.SpecialDirectories.Programs & "\" & My.Application.Info.CompanyName & "\" & My.Application.Info.ProductName & ".appref-ms"
            If File.Exists(myShortcut) Then
                WriteRegistryValue(Registry.CurrentUser, "Software\Microsoft\Windows\CurrentVersion\Run", My.Application.Info.AssemblyName & "Startup", Chr(34) & myShortcut & Chr(34), RegistryValueKind.String)
            End If
        Else
            If ReadRegistryString(Registry.CurrentUser, "Software\Microsoft\Windows\CurrentVersion\Run", My.Application.Info.AssemblyName & "Startup", "") <> Nothing Then
                DeleteRegistryValue(Registry.CurrentUser, "Software\Microsoft\Windows\CurrentVersion\Run", My.Application.Info.AssemblyName & "Startup")
            End If
        End If
    End Sub

So I write a shortcut to the appref-ms file into the run group and made my program default to minimized instead of normal and it's working fine. It's not the solution I wanted but it works.
Sprint  Wednesday, July 15, 2009 3:18 PM
Anyone from Microsoft that can confirm or deny this being a bug? How can adding a command line argument make the IsNetworkDeployed check flip?
Sprint  Monday, July 13, 2009 2:20 PM
Hi Allan,

The shortcut to an installedClickOnce application in the Startup menu is an application reference (.appref-ms). When you open this shortcut, it actually launch the ClickOnce application using a URL. If you open the .appref-ms file with Notepad, you'll see the .appref-ms file only contains a URL toa .application file.

The file path shown in the TextBox is the ClickOnce isolation store on the client machine where the installed ClickOnce application is installed. The ClickOnce isolation store is considered private to the implementation of ClickOnce, so it's not recommended to run the .exe file from the ClickOnce isolation store directly. If you do like that, the application will run only as a normal program and ClickOnce functionality won't work in this case.

To pass parameters to a ClickOnce application, you can append "?paramname=paramvalue". For more information, please visit the following link:
http://msdn.microsoft.com/en-us/library/ms172242(VS.80).aspx

Hope this helps.

Sincerely,
Linda Liu
Please remember to mark the replies as answers if they help and unmark them if they provide no help. end us any feedback you have about the help from MSFT at fbmsdn@microsoft.com.
Linda Liu  Tuesday, July 14, 2009 9:41 AM
On the initial startup of my program it adds itself to the Run key in the registry using something like this:

WriteRegistryValue(Registry.CurrentUser, "Software\Microsoft\Windows\CurrentVersion\Run", "MyAppStartup", My.Application.Info.DirectoryPath.ToString & "\" & My.Application.Info.AssemblyName & ".exe -minimize", RegistryValueKind.String)

This works as intended, starting the program each time the user that installed the program logs in. How else would I go about doing the same thing in the "proper" way? I.e. what should my string in the Run key look like? I think I understand how to enable the passing of parameters in my app and from your link I can figure out how to read them (all I'm looking for is something telling me to run minimized or not).
Sprint  Tuesday, July 14, 2009 5:34 PM
Did you check out the article that Linda posted? The point is that there are two ways to pass parameters to a ClickOnce application.

(1) Use the URL that points to the application file and pass them as query parameters to the URL, as she has noted above.
(2) Track down and run the actual EXE file located in the ClickOnce cache under the user's profile, and add arguments to it and pick them up like a non-ClickOnce program.

You are using approach #2, which means it is NOT running as a ClickOnce application, it is running as any other application, so it will not perform the updates.

In order to perform updates, you must run the application via the link to the .application file and pass the parameters in as explained in the article to which Linda posted a link.

The shortcut added to the start menu merely does the same thing, i.e. calling the link to the application file.

RobinDotNet
Click here to visit my ClickOnce blog!
RobinDotNet  Wednesday, July 15, 2009 5:46 AM
I did check the url and you are correct I am using method #2 in your example. I figured if a app was deployed through ClickOnce then it's always a ClickOnce app....I guess that's too simple. :) So I understand how to enable the passing of parameters (allow url setting in publish tab) and I understand how to check for something like "?WindowState=Minimized" (well I understnad but HttpUtility is coming up not declared in the example post...).

So how do I add a link to the startup group (HKCU run group) that points to my application? Is there a easy way to see what URL was used to execute the program and then add the ?WindowState=Minimized" to it then write it to the registry?
Sprint  Wednesday, July 15, 2009 1:16 PM
So I wrote this up:

            If My.Application.IsNetworkDeployed = True Then
                Try
                    Dim value As New Uri(Deployment.Application.ApplicationDeployment.CurrentDeployment.ActivationUri.ToString & "?WindowState=Minimized")
                    MsgBox(value.ToString)
                Catch ex As Exception
                    MsgBox("The URI value thing didn't work: " & ex.Message & vbCrLf & ex.InnerException.Message.ToString)
                    Debug.WriteLine(ex.Message & vbCrLf & ex.InnerException.Message.ToString)
                End Try
            End If

And on the install from my website it came back with "http://MySite/MyApp.application?WindowState=Minimized" and I thought to myself Perfect! So I run the app from the start menu and I get a unhandled exception (Object reference not set to an instance of an object.) in the same routine above.

This seems to be WAAAYYY more work then it should be. I'm simply going to have my app start minimized by default until there is a easier solution out there.
  • Edited bySprint Wednesday, July 15, 2009 2:21 PMupdated code
  •  
Sprint  Wednesday, July 15, 2009 2:20 PM
My "solution" to this problem

    ''' <summary>
    ''' Update Run on Startup - Updates our registry key based on our settings
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub UpdateRunOnStartup()
        If My.Settings.RunOnStartup Then
            Dim myShortcut As String = My.Computer.FileSystem.SpecialDirectories.Programs & "\" & My.Application.Info.CompanyName & "\" & My.Application.Info.ProductName & ".appref-ms"
            If File.Exists(myShortcut) Then
                WriteRegistryValue(Registry.CurrentUser, "Software\Microsoft\Windows\CurrentVersion\Run", My.Application.Info.AssemblyName & "Startup", Chr(34) & myShortcut & Chr(34), RegistryValueKind.String)
            End If
        Else
            If ReadRegistryString(Registry.CurrentUser, "Software\Microsoft\Windows\CurrentVersion\Run", My.Application.Info.AssemblyName & "Startup", "") <> Nothing Then
                DeleteRegistryValue(Registry.CurrentUser, "Software\Microsoft\Windows\CurrentVersion\Run", My.Application.Info.AssemblyName & "Startup")
            End If
        End If
    End Sub

So I write a shortcut to the appref-ms file into the run group and made my program default to minimized instead of normal and it's working fine. It's not the solution I wanted but it works.
Sprint  Wednesday, July 15, 2009 3:18 PM

You can use google to search for other answers

Custom Search

More Threads

• Stdole & ClickOnce Application
• Windows Installer Package
• 2 questions re VS 2005 setup project
• .NET 2.0 on the server or only the client?
• Smart Client and DLL searching
• Cancel during Uninstall
• Signtool can't timestamp through ISA Server
• app from website - not trusted?
• Getting a "Could not find required file 'setup.bin'" error
• ScheduleReboot