Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SquirrelAwareApp events not getting called #435

Closed
bwarthur opened this issue Sep 9, 2015 · 13 comments
Closed

SquirrelAwareApp events not getting called #435

bwarthur opened this issue Sep 9, 2015 · 13 comments

Comments

@bwarthur
Copy link

bwarthur commented Sep 9, 2015

I am having issues getting any of the SquirrelAwareApp events to execute. I have tried code very similar to the documentation and none of the shortcuts are getting created. I also have [assembly: AssemblyMetadata("SquirrelAwareVersion", "1")] in the last line of my AssemblyInfo.cs.

using (var manager = new UpdateManager(SGGlobalState.UpdateUrl))
{
    SquirrelAwareApp.HandleEvents(
        onInitialInstall: _ => manager.CreateShortcutForThisExe(),
        onAppUpdate: _ => manager.CreateShortcutForThisExe(),
        onAppUninstall: _ => manager.RemoveShortcutForThisExe(),
        onFirstRun: OnFirstRun);
}

I also tried creating my own event handlers however none of the methods are getting called. I my wpf app, configuring squirrel is the second thing to happen, just after starting logging.

public App()
{
    Logging.Start();
    ConfigureSquirrel();
}

private void ConfigureSquirrel()
{
    Logging.Log.Info("Creating SquirrelAwareApp event handlers...");
    SquirrelAwareApp.HandleEvents(
        onInitialInstall: OnInitialInstall,
        onAppUpdate: OnAppUpdate,
        onAppUninstall: OnAppUninstall,
        onFirstRun: OnFirstRun);
}

private static void OnFirstRun()
{
    Logging.Log.Info("Triggered OnFirstRun...");
}

private static void OnAppUninstall(Version version)
{
    Logging.Log.Info("Triggered OnAppUninstall...");

    using (var manager = new UpdateManager(SGGlobalState.UpdateUrl))
    {
        manager.RemoveShortcutsForExecutable("MyApp.exe", ShortcutLocation.Desktop);
        manager.RemoveShortcutsForExecutable("MyApp.exe", ShortcutLocation.StartMenu);
        manager.RemoveShortcutsForExecutable("MyApp.exe", ShortcutLocation.AppRoot);

        manager.RemoveUninstallerRegistryEntry();
    }
}

private static void OnAppUpdate(Version version)
{
    Logging.Log.Info("Triggered OnAppUpdate...");

    using (var manager = new UpdateManager(SGGlobalState.UpdateUrl))
    {
        manager.CreateShortcutsForExecutable("MyApp.exe", ShortcutLocation.Desktop, true);
        manager.CreateShortcutsForExecutable("MyApp.exe", ShortcutLocation.StartMenu, true);
        manager.CreateShortcutsForExecutable("MyApp.exe", ShortcutLocation.AppRoot, true);

        manager.RemoveUninstallerRegistryEntry();
        manager.CreateUninstallerRegistryEntry();
    }
}

private static void OnInitialInstall(Version version)
{
    Logging.Log.Info("Triggered OnInitialInstall...");

    using (var manager = new UpdateManager(SGGlobalState.UpdateUrl))
    {
        manager.CreateShortcutForThisExe();

        manager.CreateShortcutsForExecutable("MyApp.exe", ShortcutLocation.Desktop, false);
        manager.CreateShortcutsForExecutable("MyApp.exe", ShortcutLocation.StartMenu, false);
        manager.CreateShortcutsForExecutable("MyApp.exe", ShortcutLocation.AppRoot, false);

        manager.CreateUninstallerRegistryEntry();
    }
}
@douglasascosta-zz
Copy link

Same problem here with SquirrelAwareApps. I followed exactly as in the docs, but nothing happens.

In Squirrel log says that it detects that my exe is SquirrelAware, but when executed it times out after 15s, whether in install, uninstall or updated event, and nothing is executed.

@ivanovit
Copy link

I had similar problems. The app was detected as squirrel aware but the installer timeout after 15 sec. In my case the problem was caused by the .exe startup time(the executable needed more than 15 seconds to start because of a problem in our build process).

So to troubleshot this I would recommend:

  1. Double check the logs from squirrel. They are very useful when you trying for diagnostics. You can find then in %localAppData%\SquirrelTemp\SquirrelSetup.log and *%localAppData%\YourAppFolder*
  2. See if your executable which is marked as squirrel aware is called. You could do this by starting the installer and then check in process explorer if the process is started. You also could check the parameters of the process.

You could also try to start your .exe manually with "--squirrel-install" args. For example %localAppData%\app-\YouApp.exe --squirrel-install and see what is happening.

@anaisbetts
Copy link
Contributor

You could also try to start your .exe manually with "--squirrel-install" args. For example %localAppData%\app-\YouApp.exe --squirrel-install and see what is happening.

This is the easiest way to debug Squirrel hooks for sure - just run them!

@Lakritzator
Copy link

I don't know if you have solved it by now, here are my 2¢:

I was also having problems getting the events, even after I noticed that I somehow forgot to add the SquirrelAwareVersion meta-data to my assembly.

Than I noticed that most events actually would come, e.g. the first run, just that my application wasn't updating.

After adding the UpdateApp code:

using (var updateManager = new UpdateManager(<url>) {
  await updateManager.UpdateApp();
}

and doing another setup, as the application didn't update, future updates finally started working.

Maybe I overlooked something, but in the article on Squirrel Events I couldn't find anything on still needing the UpdateApp() call. This threw me off, I thought that adding the assembly information and handling the events was all I needed.

It does make sense though, I am not complaining about the functionality, just that I also had difficulties making it work.

@anaisbetts
Copy link
Contributor

You don't need the UpdateApp call - you do need to handle Squirrel events as early as possible in your app though, which many folx mess up, they try to handle it in their update code. Like, you should be running HandleEvents in Main or in your WPF App.xaml.cs constructor. The earlier, the better!

@Lakritzator
Copy link

The HandleEvents, in my test application, was called in the startup event of the Application (the Startup="MyStartupHandler" in App.xml).

The startup handler was async, might this have an influence that the update didn't work?
Events where handled, the uninstall and firstrun events were certainly working...

As I no longer am at work, I created a new WPF application and called the following in the constructor of App.xaml.cs:

using (var updateManager = new UpdateManager(ReleasesLocation))
{
    SquirrelAwareApp.HandleEvents(
        v => {
            updateManager.CreateShortcutForThisExe();
            MessageBox.Show("OnInitialInstall: " + v);
        },
        v => {
            updateManager.CreateShortcutForThisExe();
            MessageBox.Show("OnAppUpdate: " + v);
        },
        v => MessageBox.Show("OnAppObsoleted: " + v),
        v => {
            updateManager.RemoveShortcutForThisExe();
            MessageBox.Show("OnAppUninstall: " + v);
        },
        () => MessageBox.Show("OnFirstRun"));
}

The events are working fine as before, but updates still don't work.
So I was using 1.0.3 and made a releasify for 1.0.4, starting the 1.0.3 doesn't do anything else than show the application window. Everything will only work when calling UpdateApp myself, so I guess I must have done something wrong.

I know you wrote the thing :), but which part makes the update if an application is Squirrel-Aware?

P.S.
Just in case you are wondering:
Tested on Windows 7 at work, and at home I used Windows 10.

@Lakritzator
Copy link

Lakritzator commented Jan 5, 2016

Hi Ani,

I had a quick look at https://github.com/Squirrel/Squirrel.Windows/blob/master/src/Squirrel/SquirrelAwareApp.cs, at least in HandleEvents there is no update being called (which doesn't surprise me).

Is the update for Squirrel-Aware applications done in the update.exe?
I would say "no" as in my shortcut it says "Update.exe --processStart TestExe.exe", and I believe that the update.exe doesn't know the "releases" url. So I somehow don't understand what would be doing the updating if I don't do it myself?

As I said before, the event handling in general works fine. Except that there is no update even, or rather no update at all, when I don't call the update code myself. And this too is fine, just that it is not clearly documented.

Best wishes,
Robin

@anaisbetts
Copy link
Contributor

As I said before, the event handling in general works fine. Except that there is no update even, or rather no update at all, when I don't call the update code myself.

I think you're misunderstanding how this works - HandleEvents is a mechanism for Squirrel to tell you when things happen. Squirrel never automatically updates, because it's the developer's job to decide when updates happen. Sorry if that wasn't clear in the docs! Squirrel is much more a library, than an automated "framework" like Clickonce et al

@Lakritzator
Copy link

Lakritzator commented Jan 5, 2016

Thanks Ani, your answer "You don't need the UpdateApp call" just threw me off.

So I guess the squirrel-events documentation here should be enhanced with a hint that an update check and the update itself needs to be added.

For me, placing the following as soon as possible in the application worked:

    static bool ShowTheWelcomeWizard;

    using (var mgr = new UpdateManager(updateUrl))
    {
        // Note, in most of these scenarios, the app exits after this method completes!
        SquirrelAwareApp.HandleEvents(
          onInitialInstall: v => mgr.CreateShortcutForThisExe(),
          onAppUpdate: v => mgr.CreateShortcutForThisExe(),
          onAppUninstall: v => mgr.RemoveShortcutForThisExe(),
          onFirstRun: () => ShowTheWelcomeWizard = true);

          await mgr.UpdateApp();
    }

@cwoolum
Copy link

cwoolum commented Jun 22, 2016

The above code works for me for updating but the initial instance does not close after update so 2 versions of my app end up being open.

@phw198
Copy link

phw198 commented Apr 24, 2017

Running Squirrel 1.5.2 I'm having trouble getting anything but the onFirstRun event to fire. The main issue right now is the onUninstall event, as this is causing the desktop shortcut to be left behind and the Splash screen is displayed when the app is uninstalled.

AssemblyInfo.cs - line appended:
[assembly: AssemblyMetadata("SquirrelAwareVersion", "1")]

Main.cs excerpt:

private static void myOnFirstRun() {
  try {
    using (var mgr = new Squirrel.UpdateManager("\\\\UNC\\Squirrel", "AppName")) {
    log.Debug("Creating shortcuts...");
    mgr.CreateShortcutsForExecutable(Path.GetFileName(System.Windows.Forms.Application.ExecutablePath), Squirrel.ShortcutLocation.Desktop, false);

    log.Debug("Creating uninstaller...");
    mgr.CreateUninstallerRegistryEntry().Wait();
    log.Debug("... done creating uninstaller.");
  } catch (System.Exception ex) {
    log.Error("myOnFirstRun. "+ ex.Message);
  }
}

private static void onAppUpdate(Version version) {
  try {
    using (var mgr = new Squirrel.UpdateManager("\\\\UNC\\Squirrel", "AppName")) {
      MessageBox.Show("Thanks for updating!");
      log.Debug("Rereating shortcuts...");
      mgr.CreateShortcutsForExecutable(Path.GetFileName(System.Windows.Forms.Application.ExecutablePath), Squirrel.ShortcutLocation.Desktop, false);
    }
        
  } catch (System.Exception ex) {
    log.Error("onAppUpdate. "+ ex.Message);
  }
}

private static void myOnAppUninstall(Version version) {
  try {
    System.Diagnostics.Process.Start("https://www.google.com");

    using (var mgr = new Squirrel.UpdateManager("\\\\UNC\\Squirrel", "AppName")) {
        log.Debug("Removing shortcuts...");
        mgr.RemoveShortcutsForExecutable(Path.GetFileName(System.Windows.Forms.Application.ExecutablePath), Squirrel.ShortcutLocation.Desktop);
    }
  } catch (System.Exception ex) {
    log.Error("myOnAppUninstall. "+ ex.Message);
  }
}

private static void myOnInitialInstall(Version version) {
  try {
    log.Debug("Welcome! v" + version.ToString());
  } catch (System.Exception ex) {
    log.Error("myOnInitialInstall. "+ ex.Message);
  }
}


[STAThread]
private static void Main(string[] args) {
    //Set up logging
    initialiseFiles();

    try {
      log.Debug("Setting up Squirrel handlers.");
      Squirrel.SquirrelAwareApp.HandleEvents(
            onFirstRun: myOnFirstRun,
            onInitialInstall: v => myOnInitialInstall(v),
            //onAppUpdate: v => onAppUpdate(v),
            onAppUninstall: myOnAppUninstall
       );
    
    } catch (System.Exception ex) {
        log.Error("Failed setting up handlers.");
        OGCSexception.Analyse(ex, true);
    }
    
    Splash.ShowMe();

Can anyone point out what I'm doing wrong? Passing the version variable into the function or not doesn't appear to make any difference.

@phw198
Copy link

phw198 commented Apr 27, 2017

OK, I worked it down to a problem with HandleEvents() - if the application is pre-release, eg 2.5.0-beta, then it fails. Given this is a valid SemVer, I'm feeling like this is a bug.

I've subsequently come across issue #892 and a comment that also need to strip the pre-release detail.

For the moment, my workaround is:

Squirrel.SquirrelAwareApp.HandleEvents(
  onFirstRun: myOnFirstRun,
  onInitialInstall: v => myOnInitialInstall(v),
  onAppUpdate: v => onAppUpdate(v),
  onAppUninstall: v => myOnAppUninstall(v),
  arguments: FixCliArgs()
);

private static String[] FixCliArgs() {
  try {
    String[] cliArgs = Environment.GetCommandLineArgs().Skip(1).ToArray();
    if (cliArgs.Length == 2) {
      cliArgs[1] = cliArgs[1].Split('-')[0];
    }
    return cliArgs;
  } catch (System.Exception ex) {
    return null;
  }
}

@hansschaa
Copy link

Any solution for this? Im learn Squirrel but onInitialInstall is never called, but onFirstRun works

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants