Skip to content

Commit c54087f

Browse files
Merge pull request #17 from flowdevs-io/another-branch
final push hopefully lol
2 parents d64129c + d1520a0 commit c54087f

1 file changed

Lines changed: 84 additions & 4 deletions

File tree

FlowVision/lib/Plugins/CMDPlugin.cs

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Diagnostics;
55
using System.Linq;
66
using System.Text;
7+
using System.Threading;
78
using System.Threading.Tasks;
89
using System.Windows.Forms;
910
using FlowVision.lib.Classes;
@@ -13,13 +14,18 @@ namespace FlowVision.lib.Plugins
1314
{
1415
class CMDPlugin
1516
{
17+
private static readonly string[] BrowserProcesses = { "msedge", "chrome", "firefox", "iexplore", "opera" };
18+
private static readonly string[] NonWaitingCommands = { "start ", "explorer " };
1619

1720
[KernelFunction, Description("Executes a CMD command and returns the output.")]
1821
public async Task<string> ExecuteCommand([Description("Command Prompt Command")] string command)
1922
{
2023
// Log the plugin usage
2124
PluginLogger.LogPluginUsage("CMDPlugin", "ExecuteCommand", command);
2225

26+
// Detect if this is likely launching an external application
27+
bool shouldWaitForExit = !ShouldSkipWaiting(command);
28+
2329
try
2430
{
2531
var startInfo = new ProcessStartInfo()
@@ -35,13 +41,32 @@ public async Task<string> ExecuteCommand([Description("Command Prompt Command")]
3541
using (var process = new Process { StartInfo = startInfo })
3642
{
3743
process.Start();
38-
string output = await process.StandardOutput.ReadToEndAsync();
39-
string errors = await process.StandardError.ReadToEndAsync();
40-
process.WaitForExit();
44+
45+
// Use tasks to read output with timeout
46+
var outputTask = process.StandardOutput.ReadToEndAsync();
47+
var errorTask = process.StandardError.ReadToEndAsync();
48+
49+
if (shouldWaitForExit)
50+
{
51+
// Wait for process with reasonable timeout
52+
if (!process.WaitForExit(10000)) // 10 second timeout
53+
{
54+
return $"Command started but may still be running: {command}";
55+
}
56+
}
57+
else
58+
{
59+
// For non-waiting commands, give a short time to collect initial output
60+
await Task.Delay(500);
61+
return $"Command launched: {command}";
62+
}
63+
64+
// Complete reading output
65+
string output = await outputTask;
66+
string errors = await errorTask;
4167

4268
if (!string.IsNullOrWhiteSpace(errors))
4369
{
44-
4570
return $"Error: {errors}";
4671
}
4772

@@ -53,5 +78,60 @@ public async Task<string> ExecuteCommand([Description("Command Prompt Command")]
5378
return $"Exception: {ex.Message}";
5479
}
5580
}
81+
82+
[KernelFunction, Description("Launches an external application without waiting for it to exit.")]
83+
public string LaunchApplication([Description("Application to launch")] string application,
84+
[Description("Arguments for the application")] string arguments = "")
85+
{
86+
// Log the plugin usage
87+
PluginLogger.LogPluginUsage("CMDPlugin", "LaunchApplication", $"{application} {arguments}");
88+
89+
try
90+
{
91+
var startInfo = new ProcessStartInfo()
92+
{
93+
FileName = application,
94+
Arguments = arguments,
95+
UseShellExecute = true,
96+
CreateNoWindow = false
97+
};
98+
99+
Process.Start(startInfo);
100+
return $"Successfully launched: {application}";
101+
}
102+
catch (Exception ex)
103+
{
104+
return $"Failed to launch {application}: {ex.Message}";
105+
}
106+
}
107+
108+
private bool ShouldSkipWaiting(string command)
109+
{
110+
if (string.IsNullOrWhiteSpace(command))
111+
return false;
112+
113+
// Check if command contains any browser names (case-insensitive)
114+
if (BrowserProcesses.Any(browser =>
115+
command.IndexOf(browser, StringComparison.OrdinalIgnoreCase) >= 0))
116+
{
117+
return true;
118+
}
119+
120+
// Check for commands that typically launch external processes
121+
if (NonWaitingCommands.Any(cmd =>
122+
command.StartsWith(cmd, StringComparison.OrdinalIgnoreCase)))
123+
{
124+
return true;
125+
}
126+
127+
// Check for URLs or web addresses
128+
if (command.IndexOf("http://", StringComparison.OrdinalIgnoreCase) >= 0 ||
129+
command.IndexOf("https://", StringComparison.OrdinalIgnoreCase) >= 0)
130+
{
131+
return true;
132+
}
133+
134+
return false;
135+
}
56136
}
57137
}

0 commit comments

Comments
 (0)