Add experimental shell support

- Issue MatterHackers/MCCentral#4591
Make MC run single instance
- Issue MatterHackers/MCCentral#4638
Open passed in stl files to a new design tab
This commit is contained in:
John Lewin 2018-11-27 12:22:38 -08:00
parent 38e8fd84fd
commit 92a89367ec
4 changed files with 140 additions and 5 deletions

View file

@ -44,6 +44,7 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />

View file

@ -261,6 +261,8 @@ namespace MatterHackers.MatterControl
public ThemeConfig MenuTheme => AppContext.MenuTheme;
public event EventHandler<string> ShellFileOpened;
public RunningTasksConfig Tasks { get; set; } = new RunningTasksConfig();
public IReadOnlyList<PrinterConfig> ActivePrinters => _activePrinters;
@ -2497,6 +2499,11 @@ If you experience adhesion problems, please re-run leveling."
};
}
public void ShellOpenFile(string file)
{
UiThread.RunOnIdle(() => this.ShellFileOpened?.Invoke(this, file));
}
public class CloudSyncEventArgs : EventArgs
{
public bool IsAuthenticated { get; set; }

View file

@ -29,12 +29,15 @@ either expressed or implied, of the FreeBSD Project.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using MatterHackers.Agg;
using MatterHackers.Agg.Platform;
using MatterHackers.Agg.UI;
using MatterHackers.DataConverters3D;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.Library;
using MatterHackers.MatterControl.PartPreviewWindow.PlusTab;
using MatterHackers.MatterControl.PrintLibrary;
using MatterHackers.MatterControl.SlicerConfiguration;
@ -280,6 +283,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
ApplicationController.Instance.Tasks.TasksChanged += Tasks_TasksChanged;
tabControl.ActiveTabChanged += TabControl_ActiveTabChanged;
ApplicationController.Instance.ShellFileOpened += this.Instance_OpenNewFile;
UpdateControlData.Instance.UpdateStatusChanged.RegisterEvent((s, e) =>
{
SetLinkButtonsVisibility(s, new StringEventArgs("Unknown"));
@ -288,6 +293,40 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
ApplicationController.Instance.MainView = this;
}
private async void Instance_OpenNewFile(object sender, string filePath)
{
var history = ApplicationController.Instance.Library.PlatingHistory;
var workspace = new PartWorkspace()
{
Name = Path.GetFileName(filePath),
SceneContext = new BedConfig(history)
};
ApplicationController.Instance.Workspaces.Add(workspace);
var scene = new Object3D();
scene.Children.Add(
new Object3D
{
MeshPath = filePath,
Name = Path.GetFileName(filePath)
});
await workspace.SceneContext.LoadContent(
new EditContext()
{
ContentStore = ApplicationController.Instance.Library.PlatingHistory,
SourceItem = new InMemoryLibraryItem(scene)
});
ApplicationController.Instance.Workspaces.Add(workspace);
var newTab = CreatePartTab(workspace);
tabControl.ActiveTab = newTab;
}
private void TabControl_ActiveTabChanged(object sender, EventArgs e)
{
if (this.tabControl.ActiveTab?.TabContent is PartTabPage tabPage)
@ -473,11 +512,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
BackgroundColor = menuTheme.BackgroundColor
};
widget.Closed += (s2, e2) =>
{
themePanel.BackgroundColor = panelBackgroundColor;
};
var section = ApplicationSettingsPage.CreateThemePanel(menuTheme);
widget.AddChild(section);
@ -617,6 +651,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
UserSettings.Instance.SettingChanged -= SetLinkButtonsVisibility;
ApplicationController.Instance.OpenPrintersChanged -= OpenPrinters_Changed;
ApplicationController.Instance.Tasks.TasksChanged -= Tasks_TasksChanged;
ApplicationController.Instance.ShellFileOpened -= Instance_OpenNewFile;
tabControl.ActiveTabChanged -= TabControl_ActiveTabChanged;
unregisterEvents?.Invoke(this, null);

View file

@ -30,9 +30,13 @@ either expressed or implied, of the FreeBSD Project.
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Threading;
using MatterHackers.Agg.Platform;
using MatterHackers.MatterControl.DataStorage;
using MatterHackers.MatterControl.PrintQueue;
using MatterHackers.MatterControl.SlicerConfiguration;
using MatterHackers.SerialPortCommunication.FrostedSerial;
using Microsoft.Extensions.Configuration;
@ -41,6 +45,10 @@ namespace MatterHackers.MatterControl
{
class Program
{
private static EventWaitHandle waitHandle;
private static string mainServiceName = "";
[STAThread]
static void Main(string[] args)
{
@ -64,6 +72,40 @@ namespace MatterHackers.MatterControl
string userProfilePath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
//#if IS_WINDOWS
waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset, "MatterControl#Startup", out bool created);
if (!created)
{
// If an instance is already running, create a service proxy and execute ShellOpenFile
var proxy = new ServiceProxy();
// and at least one argument is an acceptable shell file extension
var itemsToAdd = args.Where(f => File.Exists(f) && shellFileExtensions.Contains(Path.GetExtension(f).ToLower()));
if (itemsToAdd.Any())
{
// notify the running instance of the event
proxy.ShellOpenFile(itemsToAdd.ToArray());
}
System.Threading.Thread.Sleep(1000);
// Finally, close the process spawned by Explorer.exe
return;
}
//#endif
var serviceHost = new ServiceHost(
typeof(LocalService),
new Uri[] { new Uri("net.pipe://localhost/") });
serviceHost.AddServiceEndpoint(typeof(IMainService), new NetNamedPipeBinding(), mainServiceName);
serviceHost.Open();
Console.Write(
"Service started: {0};",
string.Join(", ", serviceHost.Description.Endpoints.Select(s => s.ListenUri.AbsoluteUri).ToArray()));
// Load optional user configuration
IConfiguration config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: true)
@ -97,5 +139,55 @@ namespace MatterHackers.MatterControl
var systemWindow = Application.LoadRootWindow(width, height);
systemWindow.ShowAsSystemWindow();
}
private static string[] shellFileExtensions = new string[] { ".stl", ".amf" };
private static readonly object locker = new object();
public class LocalService : IMainService
{
public void ShellOpenFile(string[] files)
{
// If at least one argument is an acceptable shell file extension
var itemsToAdd = files.Where(f => File.Exists(f)
&& shellFileExtensions.Contains(Path.GetExtension(f).ToLower()));
if (itemsToAdd.Any())
{
lock (locker)
{
// Add each file
foreach (string file in itemsToAdd)
{
ApplicationController.Instance.ShellOpenFile(file);
}
}
}
}
}
public class ServiceProxy : ClientBase<IMainService>
{
public ServiceProxy()
: base(
new ServiceEndpoint(
ContractDescription.GetContract(typeof(IMainService)),
new NetNamedPipeBinding(),
new EndpointAddress($"net.pipe://localhost/{mainServiceName}")))
{
}
public void ShellOpenFile(string[] files)
{
Channel.ShellOpenFile(files);
}
}
}
[ServiceContract]
public interface IMainService
{
[OperationContract]
void ShellOpenFile(string[] files);
}
}