StephaneLenclud@238
|
1 |
using System;
|
StephaneLenclud@238
|
2 |
using System.Collections.Generic;
|
StephaneLenclud@238
|
3 |
using System.Diagnostics;
|
StephaneLenclud@238
|
4 |
using System.IO;
|
StephaneLenclud@238
|
5 |
using System.Linq;
|
StephaneLenclud@238
|
6 |
using System.Runtime.Serialization;
|
StephaneLenclud@238
|
7 |
using System.Text;
|
StephaneLenclud@238
|
8 |
using System.Threading.Tasks;
|
StephaneLenclud@238
|
9 |
|
StephaneLenclud@238
|
10 |
namespace SharpLib.Ear
|
StephaneLenclud@238
|
11 |
{
|
StephaneLenclud@238
|
12 |
[DataContract]
|
StephaneLenclud@238
|
13 |
[AttributeObject(Id = "Action.Launch.App", Name = "Launch application", Description = "Launch an application.")]
|
StephaneLenclud@238
|
14 |
public class ActionLaunchApp : Action
|
StephaneLenclud@238
|
15 |
{
|
StephaneLenclud@238
|
16 |
[DataMember]
|
StephaneLenclud@238
|
17 |
[AttributeObjectProperty
|
StephaneLenclud@238
|
18 |
(
|
StephaneLenclud@238
|
19 |
Id = "Action.Launch.App.File",
|
StephaneLenclud@238
|
20 |
Name = "File to launch",
|
StephaneLenclud@238
|
21 |
Description = "Specifies the application file to launch.",
|
StephaneLenclud@238
|
22 |
Filter = "EXE files (*.exe)|*.exe"
|
StephaneLenclud@238
|
23 |
)
|
StephaneLenclud@238
|
24 |
]
|
StephaneLenclud@238
|
25 |
public PropertyFile File { get; set; } = new PropertyFile();
|
StephaneLenclud@238
|
26 |
|
StephaneLenclud@238
|
27 |
[DataMember]
|
StephaneLenclud@238
|
28 |
[AttributeObjectProperty
|
StephaneLenclud@238
|
29 |
(
|
StephaneLenclud@238
|
30 |
Id = "Action.Launch.App.SwitchTo",
|
StephaneLenclud@238
|
31 |
Name = "Switch to",
|
StephaneLenclud@238
|
32 |
Description = "Specifies if we should switch the application if it's already launched."
|
StephaneLenclud@238
|
33 |
)
|
StephaneLenclud@238
|
34 |
]
|
StephaneLenclud@238
|
35 |
public bool SwitchTo { get; set; } = true;
|
StephaneLenclud@238
|
36 |
|
StephaneLenclud@238
|
37 |
[DataMember]
|
StephaneLenclud@238
|
38 |
[AttributeObjectProperty
|
StephaneLenclud@238
|
39 |
(
|
StephaneLenclud@238
|
40 |
Id = "Action.Launch.App.MultipleInstance",
|
StephaneLenclud@238
|
41 |
Name = "Multiple Instance",
|
StephaneLenclud@238
|
42 |
Description = "Specifies if We should launch multiple instance."
|
StephaneLenclud@238
|
43 |
)
|
StephaneLenclud@238
|
44 |
]
|
StephaneLenclud@238
|
45 |
public bool MultipleInstance { get; set; } = false;
|
StephaneLenclud@238
|
46 |
|
StephaneLenclud@238
|
47 |
public override string Brief()
|
StephaneLenclud@238
|
48 |
{
|
StephaneLenclud@238
|
49 |
return Name + ": " + Path.GetFileName(File.FullPath);
|
StephaneLenclud@238
|
50 |
}
|
StephaneLenclud@238
|
51 |
|
StephaneLenclud@239
|
52 |
public override bool IsValid()
|
StephaneLenclud@239
|
53 |
{
|
StephaneLenclud@239
|
54 |
// This is a valid configuration only if our file exists
|
StephaneLenclud@239
|
55 |
return System.IO.File.Exists(File.FullPath);
|
StephaneLenclud@239
|
56 |
}
|
StephaneLenclud@239
|
57 |
|
StephaneLenclud@238
|
58 |
[System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "SwitchToThisWindow")]
|
StephaneLenclud@238
|
59 |
public static extern void SwitchToThisWindow([System.Runtime.InteropServices.InAttribute()] System.IntPtr hwnd, [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)] bool fUnknown);
|
StephaneLenclud@238
|
60 |
|
StephaneLenclud@238
|
61 |
|
StephaneLenclud@238
|
62 |
protected override void DoExecute()
|
StephaneLenclud@238
|
63 |
{
|
StephaneLenclud@238
|
64 |
//First check if the process we want to launch already exists
|
StephaneLenclud@238
|
65 |
string procName = Path.GetFileNameWithoutExtension(File.FullPath);
|
StephaneLenclud@238
|
66 |
Process[] existingProcesses = Process.GetProcessesByName(procName);
|
StephaneLenclud@238
|
67 |
if (existingProcesses == null || existingProcesses.Length == 0 || MultipleInstance)
|
StephaneLenclud@238
|
68 |
{
|
StephaneLenclud@238
|
69 |
// Process do not exists just try to launch it
|
StephaneLenclud@238
|
70 |
ProcessStartInfo start = new ProcessStartInfo();
|
StephaneLenclud@238
|
71 |
// Enter in the command line arguments, everything you would enter after the executable name itself
|
StephaneLenclud@238
|
72 |
//start.Arguments = arguments;
|
StephaneLenclud@238
|
73 |
// Enter the executable to run, including the complete path
|
StephaneLenclud@238
|
74 |
start.FileName = File.FullPath;
|
StephaneLenclud@238
|
75 |
start.WindowStyle = ProcessWindowStyle.Normal;
|
StephaneLenclud@238
|
76 |
start.CreateNoWindow = true;
|
StephaneLenclud@238
|
77 |
start.UseShellExecute = true;
|
StephaneLenclud@238
|
78 |
// Run the external process & wait for it to finish
|
StephaneLenclud@238
|
79 |
Process proc = Process.Start(start);
|
StephaneLenclud@238
|
80 |
|
StephaneLenclud@238
|
81 |
//SL: We could have used that too
|
StephaneLenclud@238
|
82 |
//Shell32.Shell shell = new Shell32.Shell();
|
StephaneLenclud@238
|
83 |
//shell.ShellExecute(Properties.Settings.Default.StartFileName);
|
StephaneLenclud@238
|
84 |
}
|
StephaneLenclud@238
|
85 |
else if (SwitchTo)
|
StephaneLenclud@238
|
86 |
{
|
StephaneLenclud@238
|
87 |
//This won't work properly until we have a manifest that enables uiAccess.
|
StephaneLenclud@238
|
88 |
//However uiAccess just won't work with ClickOnce so we will have to use a different deployment system.
|
StephaneLenclud@238
|
89 |
SwitchToThisWindow(existingProcesses[0].MainWindowHandle, true);
|
StephaneLenclud@238
|
90 |
}
|
StephaneLenclud@238
|
91 |
|
StephaneLenclud@238
|
92 |
}
|
StephaneLenclud@238
|
93 |
}
|
StephaneLenclud@238
|
94 |
}
|