Hello DXL’ers, |
Re: communicating between doors processes https://www.ibm.com/developerworks/forums/thread.jspa?threadID=388530&start=0&tstart=0 It would probably be more direct to generate my own dll using something like c#, but I can remember having horrible trouble inadvertantly shutting down DOORS when the process finished (see thread below), you would think it would be a better way to go for DOORS 9.X than java though, certainly neater. https://www.ibm.com/developerworks/forums/thread.jspa?messageID=14462778� Seems as though there should be a better way of communicating between two DOORS databases. |
Re: communicating between doors processes Richard_Good - Mon Mar 04 13:53:36 EST 2013 https://github.com/domoran/DriveDOORS The idea would be to have a stable DXL Interface for marshalling data into DOORS and out from DOORS and implement language interfaces for java, python, etc. to talk to that interface. Additionally I envision a server component, that will allow to expose this interface over network. If you are interested to join, things will certainly make faster progress when more people work at this. I will try to sketch the idea in a basic design and keep this post up to date with progress. Regards, Mathias Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS |
Re: communicating between doors processes Mathias Mamsch - Tue Mar 05 14:40:46 EST 2013 Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS > https://github.com/domoran/DriveDOORS The file design.uml, which program did you have used? Thanks Wolfgang |
Re: communicating between doors processes Mathias Mamsch - Tue Mar 05 14:40:46 EST 2013 Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS By batch mode I expect you mean more than simply firing dxls using system commands from one doors session to open another. I imagine various dlls could be loaded and utilised to get running processes, but this did seem laborious and time consuming to think through I find writing C# applications much quicker and easier than utilising dlls in DOORS so I tried writing a .net dll and converting it into a type library that can be called from DOORS - this worked, only got as far as doing a hello world and getting the parent DOORS process, then I stopped to reflect. The trouble is it required me to put the generated type library next to the door exe and required access to the registry that users do not usually have. Ideally any system I/we create will not require the user to have access to the registry and to the doors install directories. More than happy to share any of this in your project area/ here. I think you are much more used to working at the DOORS sharp end than I am, your posts certainly suggest that, writing a server component sounds like a good idea, willing to admit I might have taken a wrong turn with the .net dll! Still it is an interesting aside. Can't wait to see your plan! Richard |
Re: communicating between doors processes Mathias Mamsch - Tue Mar 05 14:40:46 EST 2013 Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS By batch mode I expect you mean more than simply firing dxls using system commands from one doors session to open another. I imagine various dlls could be loaded and utilised to get running processes, but this did seem laborious and time consuming to think through I find writing C# applications much quicker and easier than utilising dlls in DOORS so I tried writing a .net dll and converting it into a type library that can be called from DOORS - this worked, only got as far as doing a hello world and getting the parent DOORS process, then I stopped to reflect. The trouble is it required me to put the generated type library next to the door exe and required access to the registry that users do not usually have. Ideally any system I/we create will not require the user to have access to the registry and to the doors install directories. More than happy to share any of this in your project area/ here. I think you are much more used to working at the DOORS sharp end than I am, your posts certainly suggest that, writing a server component sounds like a good idea, willing to admit I might have taken a wrong turn with the .net dll! Still it is an interesting aside. Can't wait to see your plan! Richard |
Re: communicating between doors processes Richard_Good - Wed Mar 06 10:50:51 EST 2013 For this I envision a 'DataMapper' library, that allows deserializing different data structures from files, at the moment I envision:
So this library allows transforming data from and to strings. Then I envision language APIs for C#, java, python, etc.: These have to implement the data mappers themselfes to write data structures that the DXL can understand. The language API basically should have functions to run what I call 'Datalet' (like servelet). A datalet receives data, decodes it using the data mapper and can then process it and return data to the calling program. The communication between the language API will be done by a 'Runner' component. This component is responsible for being able to call rapidly many small datalets and get a quick response. Additionally we need a server component for being able to interact with a remote DOORS. Nice features, that I also see are, that Datalets contain their own test code and are runnable on its own. Running them directly in the DOORS interpreter execute the test code (for ease of development). The DOORS runner will run the production code. The datalets are separated from the framework, so a new datalet can be deployed by deploying a new file and a non-working datalet will not disturb other files. So far for this large scope. The stuff I checked in has nothing of that and the design does not really contain a lot of info yet (it was created with StarUML by the way). But with time this will grow, I will try to work on it here and there, of course it will be more motivating and quicker if you guys want to chime in ;-) But in that case, we should get together outside of the forum. You can reach me under mmamsch at google mail dot com. Regards, Mathias Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS |
Re: communicating between doors processes Mathias Mamsch - Wed Mar 06 14:40:52 EST 2013
So this library allows transforming data from and to strings. Then I envision language APIs for C#, java, python, etc.: These have to implement the data mappers themselfes to write data structures that the DXL can understand. The language API basically should have functions to run what I call 'Datalet' (like servelet). A datalet receives data, decodes it using the data mapper and can then process it and return data to the calling program. The communication between the language API will be done by a 'Runner' component. This component is responsible for being able to call rapidly many small datalets and get a quick response. Additionally we need a server component for being able to interact with a remote DOORS. Nice features, that I also see are, that Datalets contain their own test code and are runnable on its own. Running them directly in the DOORS interpreter execute the test code (for ease of development). The DOORS runner will run the production code. The datalets are separated from the framework, so a new datalet can be deployed by deploying a new file and a non-working datalet will not disturb other files. So far for this large scope. The stuff I checked in has nothing of that and the design does not really contain a lot of info yet (it was created with StarUML by the way). But with time this will grow, I will try to work on it here and there, of course it will be more motivating and quicker if you guys want to chime in ;-) But in that case, we should get together outside of the forum. You can reach me under mmamsch at google mail dot com. Regards, Mathias Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
Hi Mathias and any other interested parties,
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using DOORSCOMLib;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Security.Permissions;
namespace ConnectDoorsServers
{
/// To use the class in DOORS you need to generate a type library from this dll and put it next to the door.exe, probably some other way of doing it via GAC
/// I have a post build event that runs the following line, this also registers the dll and gives it a GUID
/// regasm "D:\Visual Studio 2008\Projects\ConnectDoorsServers\ConnectDoorsServers\bin\Release\ConnectDoorsServers.dll" /tlb:"C:\Program Files\IBM\Rational\DOORS\9.2\bin\ConnectDoorsServers.tlb"
///
///You can use the following DXL to test its working
/////initiate my dll - note that type library has to be registered and installed next to doors.exe
/////might want to use this as an executable if possible to get around the issue
///OleAutoObj conDoorsServerTool = oleCreateAutoObject("ConnectDoorsServers.ControlDoors")
///string testStr
///oleGet(conDoorsServerTool, "test", testStr)
///print testStr
///oleCloseAutoObject(conDoorsServerTool)
/// </summary>
/// <summary>
/// This needs to have an interface and a delegate we can subscribe to in dxl ideally we want to raise and recieve events from the
/// .net system we are building - doubt this will work, worth a little experiment though
/// may have to poll the results in dxl using oleSetResult command and poll it here by looking at the DoorClass.Result property or standardout of process
/// </summary>
//[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
//public interface IFinishedProcessing
//{
// void OnFinishing(string finishMessage)
//}
/// <summary>
/// Methods exposed to doors here
/// </summary>
public interface IControlDoors
{
string test { get; }
void firstConnect();
}
//public delegate void FinishingDelegate(string finishMessage);
/// <summary>
/// Need to be able to establish one or more connections and sendxl between them, we also need to be able to connect to already running instances
/// Need to be able to wait for dxls to be ran and accept back statuses, standard outs, data structures etc
/// not sure dll referenced by doors is best way forward
/// </summary>
[ClassInterface(ClassInterfaceType.None)]//,ComSourceInterfaces("IFinishedProcessing")]
public class ControlDoors : IControlDoors
{
/// <summary>
/// Constructor need to do something
/// </summary>
private Process firstDatabase;
public ControlDoors()
{
System.Windows.Forms.MessageBox.Show("I am Working");
//firstConnect();
}
public string test
{
get { return "just a test"; }
}
public void firstConnect()
{
// Get all instances of doors running on the local computer. this works when debugged from another project but not when
//compiled into a dll and not from DOORS! Why?
Process[] doorsProcArray = Process.GetProcessesByName("doors");
if (doorsProcArray.Length.Equals(0))
{
System.Windows.Forms.MessageBox.Show("This dll should only be loaded from doors");
}
else if (doorsProcArray.Length.Equals(1))
{
firstDatabase = doorsProcArray[0];
System.Windows.Forms.MessageBox.Show("Working correctly in debug mode");
}
else {
System.Windows.Forms.MessageBox.Show("More than one doors process running, don't know how to get right one");
}
//get the correct doors process
//Fire the event out
//push the dxl to the process
//wait for the event to occur
//trouble is we are firing the event from here the way I have done it, need to fire the event from DOORS and handle it here
//try again with brain inserted.
//need to cast the process into doors com lib class or get it off the process somehow
//dlls can't be static, not what they do can only poll the other DOORS processes, this is not a dll task I guess.
//DOORSClass d = (DOORSCOMLib.DOORSClass);
//d.runStr("print \"Have we found the parent process\"");
}
}
/// <summary>
/// Pinched from internet should be in seperate class, could consider using ntdll from inside DOORS
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct ParentProcessUtilities
{
// These members must match PROCESS_BASIC_INFORMATION
internal IntPtr Reserved1;
internal IntPtr PebBaseAddress;
internal IntPtr Reserved2_0;
internal IntPtr Reserved2_1;
internal IntPtr UniqueProcessId;
internal IntPtr InheritedFromUniqueProcessId;
[DllImport("ntdll.dll")]
private static extern int NtQueryInformationProcess(IntPtr processHandle, int processInformationClass, ref ParentProcessUtilities processInformation, int processInformationLength, out int returnLength);
/// <summary>
/// Gets the parent process of the current process.
/// </summary>
/// <returns>An instance of the Process class.</returns>
public static Process GetParentProcess()
{
return GetParentProcess(Process.GetCurrentProcess().Handle);
}
/// <summary>
/// Gets the parent process of specified process.
/// </summary>
/// <param name="id">The process id.</param>
/// <returns>An instance of the Process class.</returns>
public static Process GetParentProcess(int id)
{
Process process = Process.GetProcessById(id);
return GetParentProcess(process.Handle);
}
/// <summary>
/// Gets the parent process of a specified process.
/// </summary>
/// <param name="handle">The process handle.</param>
/// <returns>An instance of the Process class.</returns>
public static Process GetParentProcess(IntPtr handle)
{
ParentProcessUtilities pbi = new ParentProcessUtilities();
int returnLength;
int status = NtQueryInformationProcess(handle, 0, ref pbi, Marshal.SizeOf(pbi), out returnLength);
if (status != 0)
throw new Win32Exception(status);
try
{
return Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32());
}
catch (ArgumentException)
{
// not found
return null;
}
}
}
}
//You can use the following DXL to test its working
//initiate my dll - note that type library has to be registered and installed next to doors.exe
OleAutoObj conDoorsServerTool = oleCreateAutoObject("ConnectDoorsServers.ControlDoors")
string testStr
oleGet(conDoorsServerTool, "test", testStr)
print testStr
oleCloseAutoObject(conDoorsServerTool)
|
Re: communicating between doors processes Richard_Good - Fri Mar 08 04:15:26 EST 2013
Hi Mathias and any other interested parties,
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using DOORSCOMLib;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Security.Permissions;
namespace ConnectDoorsServers
{
/// To use the class in DOORS you need to generate a type library from this dll and put it next to the door.exe, probably some other way of doing it via GAC
/// I have a post build event that runs the following line, this also registers the dll and gives it a GUID
/// regasm "D:\Visual Studio 2008\Projects\ConnectDoorsServers\ConnectDoorsServers\bin\Release\ConnectDoorsServers.dll" /tlb:"C:\Program Files\IBM\Rational\DOORS\9.2\bin\ConnectDoorsServers.tlb"
///
///You can use the following DXL to test its working
/////initiate my dll - note that type library has to be registered and installed next to doors.exe
/////might want to use this as an executable if possible to get around the issue
///OleAutoObj conDoorsServerTool = oleCreateAutoObject("ConnectDoorsServers.ControlDoors")
///string testStr
///oleGet(conDoorsServerTool, "test", testStr)
///print testStr
///oleCloseAutoObject(conDoorsServerTool)
/// </summary>
/// <summary>
/// This needs to have an interface and a delegate we can subscribe to in dxl ideally we want to raise and recieve events from the
/// .net system we are building - doubt this will work, worth a little experiment though
/// may have to poll the results in dxl using oleSetResult command and poll it here by looking at the DoorClass.Result property or standardout of process
/// </summary>
//[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
//public interface IFinishedProcessing
//{
// void OnFinishing(string finishMessage)
//}
/// <summary>
/// Methods exposed to doors here
/// </summary>
public interface IControlDoors
{
string test { get; }
void firstConnect();
}
//public delegate void FinishingDelegate(string finishMessage);
/// <summary>
/// Need to be able to establish one or more connections and sendxl between them, we also need to be able to connect to already running instances
/// Need to be able to wait for dxls to be ran and accept back statuses, standard outs, data structures etc
/// not sure dll referenced by doors is best way forward
/// </summary>
[ClassInterface(ClassInterfaceType.None)]//,ComSourceInterfaces("IFinishedProcessing")]
public class ControlDoors : IControlDoors
{
/// <summary>
/// Constructor need to do something
/// </summary>
private Process firstDatabase;
public ControlDoors()
{
System.Windows.Forms.MessageBox.Show("I am Working");
//firstConnect();
}
public string test
{
get { return "just a test"; }
}
public void firstConnect()
{
// Get all instances of doors running on the local computer. this works when debugged from another project but not when
//compiled into a dll and not from DOORS! Why?
Process[] doorsProcArray = Process.GetProcessesByName("doors");
if (doorsProcArray.Length.Equals(0))
{
System.Windows.Forms.MessageBox.Show("This dll should only be loaded from doors");
}
else if (doorsProcArray.Length.Equals(1))
{
firstDatabase = doorsProcArray[0];
System.Windows.Forms.MessageBox.Show("Working correctly in debug mode");
}
else {
System.Windows.Forms.MessageBox.Show("More than one doors process running, don't know how to get right one");
}
//get the correct doors process
//Fire the event out
//push the dxl to the process
//wait for the event to occur
//trouble is we are firing the event from here the way I have done it, need to fire the event from DOORS and handle it here
//try again with brain inserted.
//need to cast the process into doors com lib class or get it off the process somehow
//dlls can't be static, not what they do can only poll the other DOORS processes, this is not a dll task I guess.
//DOORSClass d = (DOORSCOMLib.DOORSClass);
//d.runStr("print \"Have we found the parent process\"");
}
}
/// <summary>
/// Pinched from internet should be in seperate class, could consider using ntdll from inside DOORS
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct ParentProcessUtilities
{
// These members must match PROCESS_BASIC_INFORMATION
internal IntPtr Reserved1;
internal IntPtr PebBaseAddress;
internal IntPtr Reserved2_0;
internal IntPtr Reserved2_1;
internal IntPtr UniqueProcessId;
internal IntPtr InheritedFromUniqueProcessId;
[DllImport("ntdll.dll")]
private static extern int NtQueryInformationProcess(IntPtr processHandle, int processInformationClass, ref ParentProcessUtilities processInformation, int processInformationLength, out int returnLength);
/// <summary>
/// Gets the parent process of the current process.
/// </summary>
/// <returns>An instance of the Process class.</returns>
public static Process GetParentProcess()
{
return GetParentProcess(Process.GetCurrentProcess().Handle);
}
/// <summary>
/// Gets the parent process of specified process.
/// </summary>
/// <param name="id">The process id.</param>
/// <returns>An instance of the Process class.</returns>
public static Process GetParentProcess(int id)
{
Process process = Process.GetProcessById(id);
return GetParentProcess(process.Handle);
}
/// <summary>
/// Gets the parent process of a specified process.
/// </summary>
/// <param name="handle">The process handle.</param>
/// <returns>An instance of the Process class.</returns>
public static Process GetParentProcess(IntPtr handle)
{
ParentProcessUtilities pbi = new ParentProcessUtilities();
int returnLength;
int status = NtQueryInformationProcess(handle, 0, ref pbi, Marshal.SizeOf(pbi), out returnLength);
if (status != 0)
throw new Win32Exception(status);
try
{
return Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32());
}
catch (ArgumentException)
{
// not found
return null;
}
}
}
}
//You can use the following DXL to test its working
//initiate my dll - note that type library has to be registered and installed next to doors.exe
OleAutoObj conDoorsServerTool = oleCreateAutoObject("ConnectDoorsServers.ControlDoors")
string testStr
oleGet(conDoorsServerTool, "test", testStr)
print testStr
oleCloseAutoObject(conDoorsServerTool)
You mustn't believe all error messages of a program. The atachment should work. Attachments attachment_14954759_Design.uml |
Re: communicating between doors processes SystemAdmin - Fri Mar 08 04:21:25 EST 2013 |
Re: communicating between doors processes Richard_Good - Fri Mar 08 04:48:46 EST 2013 |
Re: communicating between doors processes SystemAdmin - Fri Mar 08 07:19:02 EST 2013 At Home I've the same situation in IE and FF. Before I've installed StarUml, the browser show the content of the file and after it, they download it. No Damaging. Best regards Wolfgang |
Re: communicating between doors processes Richard_Good - Fri Mar 08 04:48:46 EST 2013 2. When downloading the attachment from Wolfgang's post, make sure the file is saved as "Design.uml" and not as "Design.uml.xml" as some browsers tend to do. 3. If in doubt, open the file in notepad.exe and check if it begins with "<?xml version="1.0" encoding="UTF-8"?><XPD:PROJECT " and ends with "</XPD:OBJ></XPD:OBJ></XPD:BODY></XPD:PROJECT>" 4. I use the version 5.0.2.1570 of StarUml, have no problem when opening the file. 5. see the png imghttp://up.picr.de/13716734bz.png[/img] which shows you diagram Mathias drew (for whatever reasons, ibm does not allow me to attach this picture, "file contains virus" ???.) HTH Mike |
Re: communicating between doors processes SystemAdmin - Sun Mar 10 08:27:59 EDT 2013 |
Re: communicating between doors processes Richard_Good - Mon Mar 11 07:42:06 EDT 2013 I find it impossible to get a connection to the DOORSCOMLib type library for the required doors process, I can create one or use an existing one, but I cannot get a connection to a particular one, I only ever get a reference to which ever database I loaded first. Maybe the second processes could be made current or first in the running object table forcing the DOORSCOMLib to be reference in the required DOORS process, massive guess work here. Tried a lot of hacks, nothing wanted to work today, not been this stuck in a long while. I would like if possible to have fewer moving parts than in your example, I imagined that I could add a DOORSCOMLIB reference to each doors process, maybe using a moniker. I also hoped it may be possible to hack the doors process to force a particular one to come to the front, this does not seem to work, I can only ever get a reference to the first database I fired up, possibly because there can be only one. Obviously not understanding some key part of this as I have been getting it wrong for the last 5 hours!! I think its possible otherwise I would already have given up. Maybe need to create the reference at DOORS startup time, by using a oleCreateObject(“DOORSCOMLIB.DOORSClass”) trouble is I expect that would point to the first database fired as well ;-) and I don’t want to add dependencies that only a few users need |