Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Task after closing unity

Discussion in 'Scripting' started by DaJDC, May 13, 2023.

  1. DaJDC

    DaJDC

    Joined:
    Jul 24, 2021
    Posts:
    5
    Im new to c# and I want to run a task that unzip downloaded zip in application directory AND reopen (if it is possible) application.
    code that i have right now:
    Code (CSharp):
    1.  
    2. //launches after downloading
    3. private void Unpacking(string execute,string zip)
    4.     {
    5.         Task.Run(() => {
    6.             string dir = Directory.GetCurrentDirectory();
    7.             ZipFile.ExtractToDirectory(zip, dir, true); // not working
    8.             Process.Start(execute);
    9.         });
    10.         Application.Quit();
    11.     }
    i tried to use powershell but it is kinda slow and hard to me
     
    Last edited: May 13, 2023
  2. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,494
    Wait, why do you close your application? Do you talk about downloading and importing data into the editor or is this for a build game? If it's for a build game you probably want to create a separate updater application. That's the main reason why most such games have launchers in the first place. So the actual application can be closed, updated and relaunched. A running application can not replace itself while its running. The file would be locked. So having a separate updater you can start the updater and exit your main application. Then the Updater can wait until the main application is terminated, perform the update and when finished start the main application again. I guess that's what you're after? You haven't mentioned your actual usecase.
     
    DaJDC and Yoreki like this.
  3. DaJDC

    DaJDC

    Joined:
    Jul 24, 2021
    Posts:
    5
    >or is this for a build game?. Yes it is
    > You haven't mentioned your actual usecase. Yes you are guessed it right. I want to make self-updating launcher
    >you probably want to create a separate updater application.
    I made a c# application that accept ProcessStartInfo.Arguments and after do all that mentioned in my (almost similary) code above. However when I close my application, started process with that script also shutting down. Could you say how can I create process (or smth that can run my .exe file with arguments (want to mention that I Russian and some folder paths might be with Russian chars) ) and that still will be working after closing application?
    (sorry for bad english)
     
    Last edited: May 14, 2023
  4. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,494
    Well, this usually only happens with UI applications because they are bound to the parent process that started them. So when an UI application terminates it takes down all its child processes as well. The usual trick is to start the new process after calling Application.Exit. Though in a Unity application that's not really an option. However there's another trick that usually works. When you start an intermediate process that starts your updater and that intermediate process ends immediately (a simple console application) the chain would be broken as the immediate parent of our new process is already gone, so when the original process ends now it has no connection to the updater. This can actually be done by the updater itself by using a commandline argument.

    So your actual game could start the update process with a special command line argument to instruct it to run itself again (of course this time without that argument) and then terminate itself.

    Code (CSharp):
    1.         static void Main(string[] args)
    2.         {
    3.             string ownProcessPath = Process.GetCurrentProcess().MainModule.FileName;
    4.             string arg = args.Length > 0 ? args[0] : "";
    5.             if (arg == "delegate")
    6.             {
    7.                 var info = new ProcessStartInfo();
    8.                 info.FileName = ownProcessPath;
    9.                 info.UseShellExecute = true;
    10.                 Process.Start(info);
    11.                 return;
    12.             }
    13.             // your actual updater stuff goes here.
    14.  
    So here we have to pass the argument "delegate" to the process which will cause it to start itself again and then terminate itself by leaving the main method. This should not terminate the just spawned child process and breaks the connection to the Unity application.

    Note that the Unity application should probably wait until the intermediate process has terminated (maybe with a small timeout of a few sec.) and your actual updater should wait for the Unity main application to terminate by checking the running application. So in Unity you would do:
    Code (CSharp):
    1.             var info = new System.Diagnostics.ProcessStartInfo();
    2.             info.FileName = "Path to your updater";
    3.             info.Arguments = "delegate"; // the argument the updater needs to delegate itself one time
    4.             info.UseShellExecute = true;
    5.             var p = System.Diagnostics.Process.Start(info);
    6.             // this should wait until the intermediate process terminated, so our updater has been "detached".
    7.             p.WaitForExit(5000);
    8.             // actually quit the Unity application.
    9.             Application.Quit();
    10.  
    The Updater may simply wait a certain amount of time or to be on the save side, check that the Unity application has terminated before trying to update it.
     
    DaJDC likes this.
  5. DaJDC

    DaJDC

    Joined:
    Jul 24, 2021
    Posts:
    5
    I figure out why my c# script wasnt working. i forgot to add files that need to launch .exe file like name.dll. so stupid mistake....
    Also your code that you send above helped me to a little bit improve my code, thanks!
    (btw how can i mark that this thread is solved? just add in the name?)