-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Stub Executables #868
Stub Executables #868
Conversation
I forgot what else I wanted to do with this |
One other problem that may be affected (solved) by this PR is custom url protocol mappings (like |
|
I appear to be having issues with the stub executable as well, it doesn't want to actually launch the application. Which also means that the shortcut doesn't work as desired. I think this stub executable is the last piece I need to get this thing running =) I will say there is some unadulterated joy seeing my app update from a delta |
@afreeland - I'm having an issue with the stub executable at the minute too (:squirrel: 1.5.2) It seems to have replaced my application exe in the Copying the correct exe (from a similar Visual Studio build), into the folder, then launching the stub, makes it work. Is this an issue known in the stub step? |
@simquad My .exe works in the |
@afreeland - Neither works for me sadly. Both of the executables are the same (stub and the "proper" one in the I confirmed this with BeyondCompare. Checking the server contents of the |
I've resolved my issues, big thanks to comments from @lukeskinner in #918 The issue was I had This article on stackoverflow assisted: http://stackoverflow.com/questions/30142229/what-creates-the-directory-app-publish-in-visual-studio-2013 Not sure if @paulcbetts would see this as a bug, or whether user error for the Either way, I'm now a happy developer again! |
Hey @simquad, can you file a separate bug about this? While this is an odd case, Squirrel still shouldn't blindly be paving your actual executables with stubs |
@anaisbetts Is this supposed to resolve the firewall exception request every update issue? I'm using v 1.9.1 and still running into this, the firewall creates the rule for the exe in the specific version (e.g. app-0.0.1). I looked around but couldn't find any extra configs I was supposed to set or anything. |
Okay, in case anyone else runs into this issue, I came up with a workaround that at least satisfies my needs. I'm not going to call it pretty, but you basically check (on app launch) whether you are the "current" folder, and if not, you copy the folder that the current exe is in, and then start that copied exe and return from the current one. Couple of things to note about this approach:
public const string DesiredAppFolderName = "current";
private const int AttemptDurationSeconds = 20; // The duration of time before giving up trying to copy the current exe
private string currentExeLocation = null;
private string appLocalRoot = null;
private string fullDesiredCurrentPath = null;
[STAThread]
public static void Main()
{
try
{
// All of these default to null, which is what we want since we don't want to create a shortcut
// from an app that squirrel launches as it will be in the folder app-[some-version]
// NOTE: You probably want to handle the uninstall event to remove any shortcuts, etc. that you
// manually added
SquirrelAwareApp.HandleEvents();
currentExeLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
appLocalRoot = Directory.GetParent(CurrentExeDirectory).FullName;
fullDesiredCurrentPath = Path.Combine(appLocalRoot, DesiredAppFolderName);
if (!currentExeLocation.ToLower().Contains(DesiredAppFolderName))
{
// We're not in the desired "current" folder, so copy to the current folder
if (MoveToDesiredCurrentFolder())
{
// We successfully copied the new version over to the desired current folder,
// so kick that process off and exit this one
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = System.AppDomain.CurrentDomain.FriendlyName;
psi.WorkingDirectory = fullDesiredCurrentPath;
Process.Start(psi);
return;
}
else
{
// The copying failed, handle this how it makes sense for your app,
// maybe just let this current exe run so that the user at least can
// have *something*
}
}
// We are in the "current" folder, so business as usual
var application = new App();
application.InitializeComponent();
application.Run();
}
catch (Exception e)
{
TelemetryManager.TrackException("Main failed", e);
}
} And then the helper functions just for code completeness public static bool MoveToDesiredCurrentFolder()
{
try
{
DateTime giveUpTime = DateTime.Now + TimeSpan.FromSeconds(AttemptDurationSeconds);
// Hot looping here without a sleep isn't the best way of handling this,
// so you probably want to do something better
while (DateTime.Now < giveUpTime)
{
try
{
DirectoryCopy(currentExeLocation, fullDesiredCurrentPath, true);
return true;
}
catch
{
// If the system is bogged down, it might take a bit to release all resources, so
// try again
}
}
// Copying attempts timed out
return false;
}
catch (Exception e)
{
TelemetryManager.TrackException("Failed to move app to current", e);
return false;
}
}
// This is just a slightly modified version of https://docs.microsoft.com/en-us/dotnet/standard/io/how-to-copy-directories
// which deletes the destination directory before copying over, which is what we want in this case
private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
{
// Get the subdirectories for the specified directory.
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
if (!dir.Exists)
{
throw new DirectoryNotFoundException(
"Source directory does not exist or could not be found: "
+ sourceDirName);
}
DirectoryInfo[] dirs = dir.GetDirectories();
// If folder already exists, delete it
if (Directory.Exists(destDirName))
{
Directory.Delete(destDirName, true);
}
Directory.CreateDirectory(destDirName);
// Get the files in the directory and copy them to the new location.
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
string temppath = Path.Combine(destDirName, file.Name);
file.CopyTo(temppath, false);
}
// If copying subdirectories, copy them and their contents to new location.
if (copySubDirs)
{
foreach (DirectoryInfo subdir in dirs)
{
string temppath = Path.Combine(destDirName, subdir.Name);
DirectoryCopy(subdir.FullName, temppath, copySubDirs);
}
}
} |
This PR changes the strategy we use for creating shortcuts. To work around the fact that our executable moves around, we've made shortcuts point to Update.exe with special parameters. Unfortunately, Windows just does not like this:
Instead, during the build process, we're going to create a "stub" executable for every app in your package, and put it in the directory above it. All the shortcuts / file associations / w/e get pointed to that instead of the real EXE, and Windows stops losing its mind about apps moving around.
Stub executables are a copy of all of the executables in the folder, and simply call the latest version of the executable with the same name.