private static CyPhyMetaLink.CyPhyMetaLinkAddon GetMetaLinkAddon(MgaProject project) { CyPhyMetaLink.CyPhyMetaLinkAddon cyPhyMLSyncComponent = null; MgaComponents mgaComponents = project.AddOnComponents; foreach (IMgaComponent iMgaComponent in mgaComponents) { if (iMgaComponent.ComponentName == "CyPhyMetaLinkAddon") { cyPhyMLSyncComponent = (CyPhyMetaLink.CyPhyMetaLinkAddon)iMgaComponent; break; } } return(cyPhyMLSyncComponent); }
protected void RunCyPhyMLSync(System.Action <MgaProject, CyPhyMetaLink.CyPhyMetaLinkAddon, CyPhyMetaLink.CyPhyMetalinkInterpreter> testAction) { try { if (debugMetalinkStartup) { metalink.WaitForExit(); string stderr = metalink.StandardError.ReadToEnd(); string stdout = metalink.StandardOutput.ReadToEnd(); } Exception exception = null; AutoResetEvent workEvent = new AutoResetEvent(false); Thread work = new Thread(new ThreadStart(delegate { try { // Import XME file to create an MGA String xmeFullPath = Path.Combine(TestModelDir, testXMEFilename); String mgaFullPath = TestModelDir + testInputFilename; MgaUtils.ImportXME(xmeFullPath, mgaFullPath); Assert.True(File.Exists(mgaFullPath), "MGA file not found. XME import may have failed."); MgaProject project = new MgaProject(); project.EnableAutoAddOns(true); project.OpenEx("MGA=" + mgaFullPath, "", true); CyPhyMetaLink.CyPhyMetaLinkAddon propagate = null; try { Assert.Contains("MGA.Addon.CyPhyMLPropagate", project.AddOnComponents.Cast <IMgaComponentEx>().Select(x => x.ComponentProgID)); propagate = (CyPhyMetaLink.CyPhyMetaLinkAddon)project.AddOnComponents.Cast <IMgaComponent>().Where(comp => comp is CyPhyMetaLink.CyPhyMetaLinkAddon).FirstOrDefault(); CyPhyMetaLink.CyPhyMetalinkInterpreter interpreter = new CyPhyMetaLink.CyPhyMetalinkInterpreter(); propagate.TestMode = true; propagate.TestMode_NoAutomaticCreoStart = true; propagate.TestMode_CreoJobObject = JobObjectPinvoke.CreateKillOnCloseJob(); interpreter.GMEConsole = GME.CSharp.GMEConsole.CreateFromProject(project); interpreter.MgaGateway = new MgaGateway(project); var task = Task.Run(async() => await interpreter.ConnectToMetaLinkBridge(project, 128)); task.Wait(); propagate.bridgeClient.SocketQueue.EditMessageReceived += msg => addonMessagesQueue.Add(msg); testAction(project, propagate, interpreter); } finally { if (propagate != null) { JobObjectPinvoke.CloseHandle(propagate.TestMode_CreoJobObject); propagate.TestMode_CreoJobObject = IntPtr.Zero; } project.Save(project.ProjectConnStr + "_posttest.mga", true); project.Close(true); } } catch (Exception e) { exception = e; KillMetaLink(); } finally { workEvent.Set(); } })); work.SetApartmentState(ApartmentState.STA); work.Start(); ManualResetEvent metalinkEvent = new ManualResetEvent(true); metalinkEvent.SafeWaitHandle = new SafeWaitHandle(metalink.Handle, false); int handle = WaitHandle.WaitAny(new WaitHandle[] { metalinkEvent, workEvent }); if (exception != null) { throw new Exception("Test failed", exception); } if (handle == 0) { work.Abort(); throw new Exception("metalink exited"); } } finally { KillMetaLink(); lock (metalinkLogStream) metalinkLogStream.Dispose(); } }
public bool ConnectToMetaLinkBridge(MgaProject project, int param) { bool connected = false; if (propagateAddon == null) { propagateAddon = GetPropagateAddon(project); } if (propagateAddon.EstablishConnection()) { connected = true; } else { //GMEConsole.Error.WriteLine("Failed to establish connection to MetaLink Bridge."); if (param != 128) { string metaLinkPath = Path.Combine(META.VersionInfo.MetaPath, @"src\MetaLink\meta-bridge\java-server\target\metalink-java-server-1.0.0.jar"); // dev machine if (!File.Exists(metaLinkPath)) { metaLinkPath = Path.Combine(META.VersionInfo.MetaPath, @"bin\metalink-java-server-1.0.0.jar"); // installed machine } if (File.Exists(metaLinkPath)) { string java_path = GetJavaInstallationPath(); if (java_path == null) { throw new ApplicationException("Could not find java.exe. Is Java installed?"); } string java_exe = Path.Combine(java_path, "bin\\java.exe"); //DialogResult res = MessageBox.Show("Could not connect to MetaLink.\n\nDo you want to start MetaLink?", "MetaLink", MessageBoxButtons.YesNo); //if (res == DialogResult.Yes) { ProcessStartInfo startInfo = new ProcessStartInfo() { FileName = java_exe, // Arguments = String.Format("-jar \"{0}\" -r \"{1}\"", metaLinkPath, Path.GetTempFileName()), Arguments = String.Format("-jar \"{0}\"", metaLinkPath), WindowStyle = ProcessWindowStyle.Minimized, UseShellExecute = false, }; #if DEBUG // startInfo.Arguments += String.Format(" -r \"{0}\"", Path.Combine(Path.GetTempPath, "metalink_recordedmessages.mlp"); #endif Process metalink = new Process(); metalink.StartInfo = startInfo; metalink.Start(); #if DEBUG metalink.BeginErrorReadLine(); metalink.BeginOutputReadLine(); #endif for (int i = 0; i < 100; i++) { if (propagateAddon.EstablishConnection()) { connected = true; break; } Thread.Sleep(100); } int WM_SETICON = 0x80; int ICON_SMALL = 0; int ICON_BIG = 1; Icon icon = Properties.Resources.CyPhyMLSync; IntPtr result = SendMessage(metalink.MainWindowHandle, WM_SETICON, (IntPtr)ICON_SMALL, icon.Handle); result = SendMessage(metalink.MainWindowHandle, WM_SETICON, (IntPtr)ICON_BIG, icon.Handle); int WM_SYSCOMMAND = 0x0112; var SC_MINIMIZE = (IntPtr)0xF020; SendMessage(metalink.MainWindowHandle, WM_SYSCOMMAND, SC_MINIMIZE, IntPtr.Zero); if (!connected) { GMEConsole.Error.WriteLine("Failed to start MetaLink Bridge."); metalink.Dispose(); } else { propagateAddon.metalinkBridge = metalink; } } } else { GMEConsole.Error.WriteLine("Meta-Link Bridge executable is missing. Please check that Meta-Link Bridge is installed."); } } } if (connected) { GMEConsole.Info.WriteLine("Established connection to MetaLink Bridge."); } return connected; }
public void InvokeEx(MgaProject project, MgaFCO currentobj, MgaFCOs selectedobjs, int param) { if (!enabled) { return; } try { GMEConsole = GMEConsole.CreateFromProject(project); MgaGateway = new MgaGateway(project); propagateAddon = GetPropagateAddon(project); if (propagateAddon == null) { GMEConsole.Error.WriteLine("CyPhyMLSync: Unable to contact CyPhyMLPropagate."); return; } if (propagateAddon.bridgeClient.IsConnectedToBridge() == false) { ConnectToMetaLinkBridge(project, param); } string currentobjKind = null; MgaFCO selectedCADModel = null; string componentVersion = null; MgaGateway.PerformInTransaction(delegate { if (currentobj != null) { currentobjKind = currentobj.Meta.Name; if (currentobjKind == "CADModel") { selectedCADModel = currentobj; currentobj = (MgaFCO)currentobj.ParentModel; currentobjKind = currentobj.Meta.Name; } else { Func<MgaFCO, bool> isCADCreoModel = fco => fco.Meta.Name == "CADModel" && CyPhyMLClasses.CADModel.Cast(fco).Attributes.FileFormat == CyPhyMLClasses.CADModel.AttributesClass.FileFormat_enum.Creo; selectedCADModel = (selectedobjs ?? (System.Collections.IEnumerable)(new List<MgaFCO>())).Cast<MgaFCO>() .FirstOrDefault(isCADCreoModel); if (selectedCADModel == null && currentobj.ObjType == GME.MGA.Meta.objtype_enum.OBJTYPE_MODEL) { // TODO: show dialog instead of picking one at random selectedCADModel = ((MgaModel)currentobj).ChildFCOs.Cast<MgaFCO>().FirstOrDefault(isCADCreoModel); } } if (currentobj != null && currentobj.Meta.Name == typeof(CyPhyMLClasses.Component).Name) { componentVersion = CyPhyMLClasses.Component.Cast(currentobj).Attributes.Version; } } }, transactiontype_enum.TRANSACTION_GENERAL, abort: false); if (currentobjKind != null && currentobjKind != "Component" && currentobjKind != "CADModel" && currentobjKind != "ComponentAssembly") { System.Windows.Forms.MessageBox.Show("Please open a Component or a Component Assembly"); return; } if (currentobjKind == "Component") { CyPhyML.Component component = CyPhyMLClasses.Component.Cast(currentobj); if (selectedCADModel == null) { GMEConsole.Error.WriteLine("This component has no CADModels to edit."); return; } bool connected = true; if (propagateAddon.bridgeClient.IsConnectedToBridge() == false) { connected = ConnectToMetaLinkBridge(project, param); } if (connected) { LinkComponent(component, selectedCADModel); } return; } if (currentobjKind == null) { propagateAddon.StartCreoEmpyMode(); return; } //GMEConsole.Out.WriteLine("Running CyPhySync interpreter..."); if (propagateAddon.AssemblyID != null) { GMEConsole.Warning.WriteLine("A ComponentAssembly is already synced"); } else { bool connected = propagateAddon.bridgeClient.IsConnectedToBridge(); if (connected == false) { GMEConsole.Info.WriteLine("Connecting to MetaLink Bridge ..."); connected = ConnectToMetaLinkBridge(project, param); } if (connected) { StartAssemblySync(project, currentobj, param); } } //GMEConsole.Out.WriteLine("End of CyPhySync interpreter..."); } finally { MgaGateway = null; project = null; currentobj = null; selectedobjs = null; GMEConsole = null; GC.Collect(); GC.WaitForPendingFinalizers(); } }
private async Task <bool> _ConnectToMetaLinkBridge(MgaProject project, int param) { bool connected = false; if (metalinkAddon == null) { metalinkAddon = GetMetaLinkAddon(project); } bool firstTimeConnect = metalinkAddon.bridgeClient.ConnectionWasRequested == false; if (await metalinkAddon.EstablishConnection()) { connected = true; } else { //GMEConsole.Error.WriteLine("Failed to establish connection to MetaLink Bridge."); if (param != 128) { string metaLinkPath = Path.Combine(META.VersionInfo.MetaPath, @"src\MetaLink\meta-bridge\java-server\target\metalink-java-server-1.1.0.jar"); // dev machine if (!File.Exists(metaLinkPath)) { metaLinkPath = Path.Combine(META.VersionInfo.MetaPath, @"bin\metalink-java-server-1.1.0.jar"); // installed machine } if (File.Exists(metaLinkPath)) { string java_path = GetJavaInstallationPath(); if (java_path == null) { throw new ApplicationException("Could not find java.exe. Is Java installed?"); } string java_exe = Path.Combine(java_path, "bin\\java.exe"); //DialogResult res = MessageBox.Show("Could not connect to MetaLink.\n\nDo you want to start MetaLink?", "MetaLink", MessageBoxButtons.YesNo); //if (res == DialogResult.Yes) { ProcessStartInfo startInfo = new ProcessStartInfo() { FileName = java_exe, // Arguments = String.Format("-jar \"{0}\" -r \"{1}\"", metaLinkPath, Path.GetTempFileName()), Arguments = String.Format("-jar \"{0}\"", metaLinkPath), WindowStyle = ProcessWindowStyle.Hidden, CreateNoWindow = true, UseShellExecute = false, RedirectStandardError = true, RedirectStandardOutput = true, }; #if DEBUG // startInfo.Arguments += String.Format(" -r \"{0}\"", Path.Combine(Path.GetTempPath, "metalink_recordedmessages.mlp"); #endif Process metalink = new Process(); metalink.StartInfo = startInfo; string logPath = Path.Combine(ProjectDirectory, "log", "MetaLinkBridge_" + Process.GetCurrentProcess().Id.ToString() + ".log"); Directory.CreateDirectory(Path.GetDirectoryName(logPath)); var log = new StreamWriter(logPath); int streamsClosed = 0; TaskCompletionSource <bool> bridgeListening = new TaskCompletionSource <bool>(); DataReceivedEventHandler handler = (sender, e) => { lock (log) { if (e.Data == null) { streamsClosed += 1; if (streamsClosed == 2) { log.Close(); log.Dispose(); } return; } if (bridgeListening.Task.IsCompleted == false && e.Data.Contains("AssemblyDesignBridgeServer started and listening")) { bridgeListening.SetResult(true); } log.WriteLine(e.Data); // log.Flush(); } }; metalink.OutputDataReceived += handler; metalink.ErrorDataReceived += handler; metalink.Start(); metalink.BeginErrorReadLine(); metalink.BeginOutputReadLine(); if (Task.WaitAny(new Task[] { bridgeListening.Task }, 20 * 1000) == -1) { // throw new TimeoutException(); } // n.b. ensure that even if GME is killed or crashes, MetaLinkBridge will exit // this is important because we are reading its output, and it may block when we are not around to read it IntPtr job = JobObjectPinvoke.AssignProcessToKillOnCloseJob(metalink); for (int i = 0; i < 100; i++) { if (await metalinkAddon.EstablishConnection()) { connected = true; break; } await Task.Delay(100); } if (!connected) { if (GMEConsole != null) { GMEConsole.Error.WriteLine("Failed to start MetaLink Bridge."); } if (metalink.HasExited) { metalink.Kill(); } metalink.Dispose(); JobObjectPinvoke.CloseHandle(job); } else { metalinkAddon._metalinkBridge = metalink; metalinkAddon._metalinkBridgeJob = job; } } } else { if (GMEConsole != null) { GMEConsole.Error.WriteLine("Meta-Link Bridge executable is missing. Please check that Meta-Link Bridge is installed."); } } } } if (connected && firstTimeConnect) { if (GMEConsole != null) { GMEConsole.Info.WriteLine("Established connection to MetaLink Bridge."); } } return(connected); }
public void InvokeEx(MgaProject project, MgaFCO currentobj, MgaFCOs selectedobjs, int param) { if (!enabled) { return; } try { GMEConsole = GMEConsole.CreateFromProject(project); MgaGateway = new MgaGateway(project); ProjectDirectory = Path.GetDirectoryName(project.ProjectConnStr.Substring("MGA=".Length)); metalinkAddon = GetMetaLinkAddon(project); if (metalinkAddon == null) { GMEConsole.Error.WriteLine("MetaLink: Unable to find CyPhyMetaLinkAddon. Was it disabled under Tools>Register Components?"); return; } ConnectToMetaLinkBridge(project, param); string currentobjKind = null; string currentobjName = null; MgaFCO selectedCADModel = null; string componentVersion = null; Guid currentobjGuid = Guid.Empty; if (currentobj != null) { MgaGateway.PerformInTransaction(delegate { currentobjKind = currentobj.Meta.Name; currentobjName = currentobj.Name; currentobjGuid = CyPhyMLClasses.DesignElement.Cast(currentobj).Guid; if (currentobjKind == "CADModel") { selectedCADModel = currentobj; currentobj = (MgaFCO)currentobj.ParentModel; currentobjKind = currentobj.Meta.Name; currentobjName = currentobj.Name; currentobjGuid = CyPhyMLClasses.DesignElement.Cast(currentobj).Guid; } else { Func <MgaFCO, bool> isCADCreoModel = fco => fco.Meta.Name == "CADModel" && CyPhyMLClasses.CADModel.Cast(fco).Attributes.FileFormat == CyPhyMLClasses.CADModel.AttributesClass.FileFormat_enum.Creo; selectedCADModel = (selectedobjs ?? (System.Collections.IEnumerable)(new List <MgaFCO>())).Cast <MgaFCO>() .FirstOrDefault(isCADCreoModel); if (selectedCADModel == null && currentobj.ObjType == GME.MGA.Meta.objtype_enum.OBJTYPE_MODEL) { // TODO: show dialog instead of picking one at random selectedCADModel = ((MgaModel)currentobj).ChildFCOs.Cast <MgaFCO>().FirstOrDefault(isCADCreoModel); } } if (currentobj != null && currentobj.Meta.Name == typeof(CyPhyMLClasses.Component).Name) { componentVersion = CyPhyMLClasses.Component.Cast(currentobj).Attributes.Version; } }, transactiontype_enum.TRANSACTION_NON_NESTED, abort: false); } if (currentobjKind != null && currentobjKind != "Component" && currentobjKind != "CADModel" && currentobjKind != "ComponentAssembly") { System.Windows.Forms.MessageBox.Show("Please open a Component or a Component Assembly"); return; } if (currentobjKind == "Component") { CyPhyML.Component component = CyPhyMLClasses.Component.Cast(currentobj); if (selectedCADModel == null) { GMEConsole.Error.WriteLine("This component has no CADModels to edit."); return; } bool connected = true; ConnectToMetaLinkBridgeTask.Wait(); connected = ConnectToMetaLinkBridgeTask.Result; if (connected) { LinkComponent(component, selectedCADModel); } return; } if (currentobjKind == null) { bool connected = true; ConnectToMetaLinkBridgeTask.Wait(); connected = ConnectToMetaLinkBridgeTask.Result; if (connected) { metalinkAddon.StartCreoEmpyMode(); } return; } //GMEConsole.Out.WriteLine("Running CyPhySync interpreter..."); if (metalinkAddon.AssemblyID != null) { if (currentobjGuid == Guid.Parse(metalinkAddon.AssemblyID)) { metalinkAddon.assemblySyncPaused = !metalinkAddon.assemblySyncPaused; if (metalinkAddon.assemblySyncPaused) { GMEConsole.Info.WriteLine(String.Format("Pausing MetaLink for {0}", SecurityElement.Escape(currentobjName))); } else { GMEConsole.Info.WriteLine(String.Format("Resuming MetaLink for {0}", SecurityElement.Escape(currentobjName))); if (metalinkAddon.assembliesToRestart.Count > 0) { MgaGateway.PerformInTransaction(delegate { // n.b. end of current transaction will trigger MetaLinkAddon RestartAssemblySync }); } } } else { GMEConsole.Warning.WriteLine("A different ComponentAssembly is already synced"); } } else { StartAssemblySync(project, currentobj, param); } //GMEConsole.Out.WriteLine("End of CyPhySync interpreter..."); } catch (AggregateException e) { foreach (var exception in e.InnerExceptions) { GMEConsole.Error.WriteLine(exception.Message); } throw new ApplicationException(e.InnerException.Message, e.InnerException); } finally { MgaGateway = null; project = null; currentobj = null; selectedobjs = null; GMEConsole = null; GC.Collect(); GC.WaitForPendingFinalizers(); } }