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

Hot Reload Plugins #2791

Open
HorridModz opened this issue Jun 19, 2024 · 15 comments
Open

Hot Reload Plugins #2791

HorridModz opened this issue Jun 19, 2024 · 15 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@HorridModz
Copy link

I'm developing a plugin for FlowLauncher, and of course, the process involves frequently building and reloading the plugin. This is pretty annoying, as I can't just build the plugin. Instead, I have to exit FlowLauncher, build the plugin, open the plugin's directory in FlowLauncher's UserData folder and the folder which my plugin has been built to, copy the files over, and restart FlowLauncher.

Describe the solution you'd like

It would be great if there was a way to hot reload plugins from a specified folder, specifically for development purposes. I would love if FlowLauncher let me run a command like plugin reload <plugin> <plugin_folder>, and it would reload the plugin using the specified folder instead of the plugin's UserData folder. It couldn't directly reload from the UserData folder, though, because that would require first killing FlowLauncher so the folder could be edited - thus killing the point.

Describe alternatives you've considered

FlowLauncher has a command Reload Plugin Data, which reinitializes all plugins. However, editing the plugins in their UserData folder requires first killing FlowLauncher so the folder could be edited, so for development it's useless. And anyway, it's still a pain to have to copy the files into the UserData folder.

I could make a script to automate the process - I'm on the verge of doing that right now. But I think that a feature like this should inherently be included, as I'm sure I'm not the only plugin developer who finds this an inconvenience.

@HorridModz HorridModz added the enhancement New feature or request label Jun 19, 2024
@Yusyuriv
Copy link
Member

Yusyuriv commented Jun 19, 2024

I also faced this issue when I started developing plugins for myself. I found two possible solutions:

  1. I made it so the build configuration in my IDE builds into FlowLauncher\Plugins\PluginName directly. That way I don't have to copy anything manually, I just need to stop Flow Launcher, build my plugin, run Flow Launcher again. This is the solution I use because if anyone else were to build my plugins, they wouldn't need to edit anything.
  2. You could theoretically add something like this to your .csproj file:
      <Target Name="PreBuild" Condition="'$(Configuration)' == 'Debug'" BeforeTargets="PreBuildEvent">
        <Exec Command="taskkill /f /fi &quot;IMAGENAME eq Flow.Launcher.exe&quot;" />
      </Target>
    
      <Target Name="PostBuild" Condition="'$(Configuration)' == 'Debug'" AfterTargets="PostBuildEvent">
        <Exec Command="start &quot;&quot; /d C:\Users\YOUR_USERNAME\AppData\Local\FlowLauncher\ Flow.Launcher.exe" />
      </Target>
    This will stop Flow Launcher process before build (if you're building with debug configuration), build the plugin, start Flow Launcher again. I don't know if it's a good idea or not. Anyone trying to build your plugin themselves would have to adjust the path before they can build with debug configuration.

Both of these solutions are not great, but it's the best I've found without Flow Launcher natively supporting hot reload.

@HorridModz
Copy link
Author

I also faced this issue when I started developing plugins for myself. I found two possible solutions:

  1. I made it so the build configuration in my IDE builds into FlowLauncher\Plugins\PluginName directly. That way I don't have to copy anything manually, I just need to stop Flow Launcher, build my plugin, run Flow Launcher again. This is the solution I use because if anyone else were to build my plugins, they wouldn't need to edit anything.

  2. You could theoretically add something like this to your .csproj file:

      <Target Name="PreBuild" Condition="'$(Configuration)' == 'Debug'" BeforeTargets="PreBuildEvent">
        <Exec Command="taskkill /f /fi &quot;IMAGENAME eq Flow.Launcher.exe&quot;" />
      </Target>
    
      <Target Name="PostBuild" Condition="'$(Configuration)' == 'Debug'" AfterTargets="PostBuildEvent">
        <Exec Command="start &quot;&quot; /d C:\Users\YOUR_USERNAME\AppData\Local\FlowLauncher\ Flow.Launcher.exe" />
      </Target>
    

    This will stop Flow Launcher process before build (if you're building with debug configuration), build the plugin, start Flow Launcher again. I don't know if it's a good idea or not. Anyone trying to build your plugin themselves would have to adjust the path before they can build with debug configuration.

Both of these solutions are not great, but it's the best I've found without Flow Launcher natively supporting hot reload.

Gee, thanks! I said I was on the verge of making a script to automate the process, but I guess you already have! Obviously not a solution, like you said, but at least now I have something to help.

@taooceros
Copy link
Member

Hotreload is hard. We have so many interdependencies of the current plugin system. I could share some resource if anyone would like to tackle the potential of reloadable plugins. Probably they will need to be loaded differently and with different features set.

@HorridModz
Copy link
Author

Hotreload is hard. We have so many interdependencies of the current plugin system. I could share some resource if anyone would like to tackle the potential of reloadable plugins. Probably they will need to be loaded differently and with different features set.

Interesting; can you elaborate on what exactly is meant by "interdependencies"? Because, with my limited understanding as a plugin author, I can't see why replacing the functions in my plugin's code would affect anything else. Anyway, if it did, it would be possible to reload all of the affected plugins from their normal directories (like the existing Reload Plugin Data command does) after hot reloading the designated plugin. Just some thoughts, but correct me as I'm probably missing something.

@taooceros
Copy link
Member

Basically the current method I know about hot reloading plugin requires flow to cleanup all references to the plugin assembly. However that seems very hard when I tried it years ago. https://learn.microsoft.com/en-us/dotnet/standard/assembly/unloadability

@HorridModz
Copy link
Author

Basically the current method I know about hot reloading plugin requires flow to cleanup all references to the plugin assembly. However that seems very hard when I tried it years ago. learn.microsoft.com/en-us/dotnet/standard/assembly/unloadability

Interesting. So you're making it sound like with all the effort / required reloading, you might as well just reload FlowLauncher and hot reloading is really not worth it.

@taooceros
Copy link
Member

Yeah that's what I am thinking. However it is certainly possible that I am not knowledgeable enough to make this feature.

On the other hand, hotreload doesn't gain us too much. Restarting flow with some script copying the plugin around does not consume too much time and resource. It is also possible to attach the ide automatically.

.net does have a hotreload feature via dotnet watch. However I don't know whether it is possible to adapt it to flow...

@HorridModz
Copy link
Author

By the way, I've been trying to make my silly post-build script work for my FlowLauncher, which is tough because it runs as admin. I ended up with this, which works in terminal but for some reason exits with error code 1 in visual studio, so I'll dump it here. Not that it matters or anything.

<!--
	Post-build script to make sure FlowLauncher is closed, copy build output to plugin path, and restart FlowLauncher when building as Debug
	Make sure to close FlowLauncher before building
	-->
	<Target Name="PostBuild" Condition="'$(Configuration)' == 'Debug'" AfterTargets="PostBuildEvent">
		<Exec Command="@tasklist /FI &quot;IMAGENAME eq Flow.Launcher.exe&quot; 2&gt;NUL | find /I &quot;Flow.Launcher.exe&quot; &gt;NUL &amp;&amp; (echo Cannot copy files to plugin directory - Flow.Launcher.exe is running. Close FlowLauncher and rebuild. &amp; exit /b 1) &amp;&amp; copy &quot;C:\Users\zachy\VSCodeProjects\Flow.Launcher.Plugin.Add2Path\bin\Debug&quot; &quot;C:\Users\zachy\AppData\Roaming\FlowLauncher\Plugins\Add2Path-1.0.0&quot; /Y &amp;&amp; &quot;C:\Users\zachy\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Flow Launcher\Flow Launcher.lnk&quot;" />
	</Target>

@taooceros
Copy link
Member

I think you can task kill flow?

@taooceros
Copy link
Member

Maybe when you test plugin you don't have to run flow as admin. I am not sure when would you need to though.

@HorridModz
Copy link
Author

Maybe when you test plugin you don't have to run flow as admin. I am not sure when would you need to though.

Yes, but unfortunately my plugin needs it because it is working with system environment variables. It's a special case.

@taooceros
Copy link
Member

What about run visual studio as admin?

@HorridModz
Copy link
Author

What about run visual studio as admin?

Doesn't carry over to build commands. Of course, it's pretty easy to just make powershell scripts for pre and post build and call then from the csproj pre / post build commands. Not as elegant, but it's a workaround and seems to be the best you can do.

@HorridModz
Copy link
Author

@taooceros Would you like me to close the issue or keep it open? Or maybe assign a label. This is obviously just a pipe dream, so it might be better to just close it.

@taooceros taooceros added the help wanted Extra attention is needed label Jun 26, 2024
@taooceros
Copy link
Member

I add a lebel for help wanted. We can leave it open I think.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants