Is it possible to prevent multiple instances of ShotGrid Desktop from loading? Current behavior is a new instance is started every time a user clicks the program icon. Have seen cases of 10+ SG icons hiding in the notification area. The problem is this can cause errors downloading updated configs if someone switches unknowingly between instances on the same project.
I’m jumping in to support this request as we are still hitting this issue regularly. It’s more than just a cluttered system tray; it’s a genuine pipeline risk.
The main pain points for us:
Version Mismatch: Multiple instances often lead to errors when downloading or switching between project configurations.
User Error: Artists often launch a new instance because they don’t realize it’s already minimized in the tray, leading to confusion about which instance is controlling their current DCC session.
I propose the following UI/UX changes:
Standard Close Behavior: Clicking the “X” button should actually Quit/Exit the application by default.
Dedicated Minimize Button: Provide a clear “Minimize to Tray” icon or ensure the standard underscore (_) button handles the backgrounding.
Single Instance Lock: Even if the above is implemented, the app should still check if an instance is already running in the tray to prevent duplicates
Is there any official update on the roadmap for this?
There are situations where you do want to have multiple instance running, but I agree it should be an option to prevent clients or certain users from running multiple.
Perhaps a Bootstrap core hook could check this and quit if it detects multiple instances?
That leaves the functionality open to extra hookable logic.
I took my own thoughts and mocked up this pick_environment core hook.
You will need to take over the Site config for this to work (I think).
This works on Windows and basically closes the previous instance and allows the current instance to continue loading.
# Copyright (c) 2018 Shotgun Software Inc.
#
# CONFIDENTIAL AND PROPRIETARY
#
# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit
# Source Code License included in this distribution package. See LICENSE.
# By accessing, using, copying or modifying this work you indicate your
# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights
# not expressly granted therein are reserved by Shotgun Software Inc.
"""
Hook which chooses an environment file to use based on the current context.
"""
import psutil
from tank import Hook
class PickEnvironment(Hook):
def execute(self, context, **kwargs):
"""
The default implementation assumes there are three environments, called shot, asset
and project, and switches to these based on entity type.
"""
if context.source_entity:
if context.source_entity["type"] == "Version":
return "version"
elif context.source_entity["type"] == "PublishedFile":
return "publishedfile"
elif context.source_entity["type"] == "Playlist":
return "playlist"
if context.project is None:
# Our context is completely empty. We're going into the site context.
shotgun_procs = _detect_shotgun_processes()
if len(shotgun_procs) > 1:
# If there are multiple shotgun.exe processes running,
# close the last one to prevent conflicts with the Toolkit engine.
last_proc_id = shotgun_procs[-1]
try:
proc = psutil.Process(last_proc_id)
proc.terminate()
proc.wait(timeout=5)
self.logger.warning(
f"Terminated shotgun.exe process with PID: {last_proc_id} to prevent conflicts with Toolkit engine.")
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.TimeoutExpired):
self.logger.warning(
f"Could not terminate shotgun.exe process with PID: {last_proc_id}. Please check your system processes to ensure there are no conflicts with the Toolkit engine.")
return "site"
if context.entity is None:
# We have a project but not an entity.
return "project"
if context.entity and context.step is None:
# We have an entity but no step.
if context.entity["type"] == "Shot":
return "shot"
if context.entity["type"] == "Asset":
return "asset"
if context.entity["type"] == "Sequence":
return "sequence"
if context.entity and context.step:
# We have a step and an entity.
if context.entity["type"] == "Shot":
return "shot_step"
if context.entity["type"] == "Asset":
return "asset_step"
if context.entity["type"] == "Sequence":
return "sequence"
return None
def _detect_shotgun_processes():
"""
Detects how many shotgun.exe processes are currently running on the system.
Returns a list of process IDs for shotgun.exe processes.
"""
shotgun_processes = []
for proc in psutil.process_iter(['pid', 'name']):
if proc.info['name'] and proc.info['name'].lower() == 'shotgun.exe':
shotgun_processes.append(proc.info['pid'])
return shotgun_processes
I’ve run into this issue too, so I put together a small toolkit app called tk-singleton.
It runs as a site-level tk-desktop app and simply creates a local socket so SG Desktop can detect when another instance is already running and close the duplicate one.
You can use it by adding the app to your site’s primary config.
Hello, we have this feature request recorded internally but we have not been able to prioritize it yet unfortunately.
The tk-singleton is a great quick fix. However, we might want to have this behaviour implemented in tk-desktop instead.
Also, instead of a warning message, we were thinking that the second instance would “contact” the first instance to bring the window in the foreground. This way, it would be totaly Ok for users to re-launch the app all the time instead of using the systray icon.
I would love to hear your feedback on this alternative plan.
Also, as I said, we are not able to prioritize this effort for the moment but feel free to raise a Pull Request in tk-desktop about it.
@Ricardo_Musch, could you tell me more about use cases where multiple instances of FlowPT Desktop is useful, please?
Clients working on multiple projects at once, need to be able to launch their tools from the desktop interface and would otherwise need to switch over each time.
I know ideally tools are launched from the Toolkit Action menu’s but these are still quite unreliable with caching, thye can take ages to re-cache and can fail.
Particularly if you run multiple projects that all have their own config uploaded.
When developing for multiple sites, it’s handy I can have multiple desktops open at the same time.
Use cases where the VFX studio uses SG Toolkit for their pipeline and also need to login to a client’s toollkit for sending files or deliveries.