It often happens that that UGS throws and error because udpate fails due to other instance of UGS running and having locked files inside the Latest folder: “…\AppData\Local\UnrealGameSync\Latest”
One way to reproduce this is:
1) Launch UGS and leave it running (normally or even in a tray).
2) Make sure that update for UGS is available (either modify the information about current version in the Latest folder or make update available,
or force execution of code branch for available udpate when attached to process, …)
3) Launch UGS again.
4) Second instantance of UGS will try to delete Latest folder but will fail as there are locked files by first process.
Is that something that you are aware of or plan to adjust in the future?
At the moment we implemented our own solution. UGS already checks whether the current process is running in the Latest folder and does not attempt the update
in that case. We changed the functionality so we check if any UGS process is running in that folder and if so, do not attempt an update. In combination
with having the periodic check enabled during runtime this seems to work for us. We were mainly curious whether we should expect any code changes from your part
and be prepared for merges and conflicts in the future.
Here is the current code and change:
// Also check we're not running under the
DirectoryReference applicationFolder = new DirectoryReference(GetSyncFolder());
if (new FileReference(Assembly.GetExecutingAssembly().Location).IsUnderDirectory(applicationFolder))
{
return LauncherResult.Continue;
}
And the change:
// Also check UGS process is not running from the sync folder
// If there is a process running there, there is no point in even attempting an update
// as it will fail on the folder modification. We leave update checks to a running
// instance (as we expect to have them enabled).
DirectoryReference applicationFolder = new DirectoryReference(GetSyncFolder());
if (IsUgsProcessRunningInDirectory(applicationFolder))
{
return LauncherResult.Continue;
}
private static bool IsUgsProcessRunningInDirectory(DirectoryReference directory)
{
// Under certains circumstances UGS can stay running as UnrealGameSyncLauncher process (e.g. when
// updates are disabled).
string[] ugsProcessNames = { "UnrealGameSync", "UnrealGameSyncLauncher" };
List<Process> ugsProcesses = Process.GetProcesses()
.Where(p => ugsProcessNames.Contains(p.ProcessName, StringComparer.OrdinalIgnoreCase))
.ToList();
foreach (Process process in ugsProcesses)
{
if (process.HasExited)
{
continue;
}
string? fileName = process.MainModule?.FileName;
if (fileName is null)
{
continue;
}
if (new FileReference(fileName).IsUnderDirectory(directory))
{
return true;
}
}
return false;
}