- C#实际选择 STK11版本 or STK12版本的问题备注。
【C#自动化客户端调用STK时,实际选择 STK11版本 or STK12版本 的调试运行备注】
以下代码“更新并重新打包备份为”〔testSTKQualNetInterface备份08.1_★避坑★【种子卫星:天线直接安装在卫星上,中间不能有Sensor传感器】.zip〕
源码文件: g:\teststkqualnetinterface\starlinksimulationclient.cs
private void button_OpenSTK_Click(object sender, EventArgs e)
{
#region 打开STK引擎:首先尝试打开现有STK软件,没有现成打开的STK;则新建打开一个STK软件实例
try
{ //尝试获取现在已经在运行的 STK实例
m_uiApp = System.Runtime.InteropServices.Marshal.GetActiveObject("STK11.Application") as AgUiApplication;
#region C#自动化客户端调用STK时,实际选择 STK11版本 or STK12版本 的调试运行备注 @2024-5-7 09:16:28
// 貌似上面的 GetActiveObject("STK11.Application") 指定调用 STK11版本,
// 其实不是,真正决定C#调用哪个版本的的STK,即【实际选择 STK11版本 or STK12版本】,
// 是由【[testSTKQualNetInterface]】C#工程里引用的[AGI.STKObjects.Interop]系列【.Net互操作程序集】的STK版本决定的!
// 比如,目前这个工程引用的[AGI.STKObjects.Interop.dll]是 12.0.0.0,那么运行时调用的就是 STK12版本
// 所以,貌似 GetActiveObject("STK11.Application") 中的 "STK11.Application" 对 STK11版本 or STK12版本 都适用。
#endregion C#自动化客户端调用STK时,实际选择 STK11版本 or STK12版本 的调试运行备注
- 将〔testSTKQualNetInterface备份08.1_★避坑★【种子卫星:天线直接安装在卫星上,中间不能有Sensor传感器】.zip〕中的《 Program.cs StarlinkSimulationClient.cs StarlinkSimulationClient.Designer.cs XLsatNPF.cs 》源码文件重新替换到〔F:\WS_STK_use_Interop\test_Client 〕解决方案中的‘testSTKQualNetInterface’工程中,调试运行:
- 编译通过、运行正常,未报错;
- ‘一键自动化测试’,最后一步是调用[button_SaveToVDF_Click]加密保存场景为*.vdf,密码为 roottoor ;
- 调试运行时,C#调用STK11.6正常;保存的[D:\Temp\Starlink5x4_20SAT-SimScenario.vdf],既能用 STK11.6 也能用 STK12.2 打开(密码roottoor);
【STK11.6逆向编译生成的Exata插件,测试运行正常 → 卫星节点位置可以正常调用STK进行更新】★STK+Exata联合仿真★
-
- 【STK11.6逆向编译生成的Exata插件,测试运行正常】用STK11.6重新打开加密保存的[D:\Temp\Starlink5x4_20SAT-SimScenario.vdf],调出‘软件逆向(反编译后重新编译)JSLS生成的’【QualNet Interface】场景管理器,对卫星Antenna天线建立网络连接并且建立星间链路,再在【QualNet Interface】场景管理器里单击‘go’,能够正常调用Exata进行网络仿真!
- STK11.6调用Exata插件进行网络仿真,生成的仿真*.config配置文件及目录,可以正常用Exata7.3打开(Exata6.2设置了调试断点会报错),卫星节点位置可以正常调用STK进行更新!
- 因为【QualNet Interface Scenario Explorer】场景管理器,本质上在操作时,是调用‘作为组件服务的[AGI.StkQualnetUiControls]服务器’,所以跟踪调试的时候:
★客户端服务器CS模式 调试运行 【QualNet Interface Scenario Explorer】场景管理器STK.Net组件插件★
-
- 首先还是运行【[F:\WS_STK_use_Interop\test_Client]】解决方案里的“C#客户端”,单击‘一键自动化测试’,等待C#客户端操作STK服务器,创建仿真场景完毕;
- 然后打开【[F:\WS_STK_use_Interop\test_Server]】解决方案,:
- 第三,在打开的【[F:\WS_STK_use_Interop\test_Server]】解决方案中,附加到进程,附加到[AgUiApplication.exe]STK软件进程;
- 在【[F:\WS_STK_use_Interop\test_Server]】解决方案的《NetworkInterfaceForm.cs》(位于[F:\WS_STK_use_Interop\test_Server\AGI.StkQualnetUiControls\]工程),找到构造函数,下断点以便跟踪调试;
public NetworkInterfaceForm(NetworkInterface networkInterface, Entity parentEntity, AgStkObjectRoot stkRoot)
-
- 在【[test_Client]】客户端解决方案运行的C#程序打开的STK11.6软件中,手动操作调出【QualNet Interface Scenario Explorer】场景管理器,选定某颗卫星(比如XL11),右键‘Add’,目的是为该卫星添加网络接口Interface; è 马上可以发现【[test_Server]】里的NetworkInterfaceForm(NetworkInterface networkInterface, Entity parentEntity, AgStkObjectRoot stkRoot)断点被拦截命中,这时的调用堆栈是:
> AGI.StkQualnetUiControls.dll!AGI.StkQualnetUiControls.NetworkInterfaceForm.NetworkInterfaceForm(AGI.StkQualnetObjectModel.NetworkInterface networkInterface, AGI.StkQualnetObjectModel.Entity parentEntity, AGI.STKObjects.AgStkObjectRoot stkRoot) 行 24 C#
AGI.StkQualnetUiControls.dll!AGI.StkQualnetUiControls.StkQualnetScenarioExplorer.OnEntityAddNetworkInterfaceMenuItemClick(object sender, System.EventArgs e) 行 253 C#
AGI.StkQualnetUiControls.dll!AGI.StkQualnetUiControls.StkQualnetScenarioExplorer.networkInterfacesContextMenuAdd_Click(object sender, System.EventArgs e) 行 266 C#
- 经跟踪调试,锁定【QualNet Interface Scenario Explorer】场景管理器‘针对Antenna天线添加Interface网络接口’的关键代码:
★调试找到关键代码★【场景管理器‘针对Antenna天线添加Interface网络接口’】
-
- 【《F:\WS_STK_use_Interop\test_Server\AGI.StkQualnetUiControls\StkQualnetScenarioExplorer.cs》】的[ OnEntityAddNetworkInterfaceMenuItemClick ],其中,两句最关键的是【 new NetworkInterfaceForm(null, entityTreeNode.Entity, this.StkRoot); 】和【 NetworkInterface networkInterface = networkInterfaceForm.GetNetworkInterface(); 】;
- 【《F:\WS_STK_use_Interop\test_Server\AGI.StkQualnetUiControls\NetworkInterfaceForm.cs》】的[ public NetworkInterface GetNetworkInterface() ];
- 最终结果:对[AGI.StkQualnetObjectModel.NetworkInterface]类型的【[networkInterface]类成员变量】进行赋值。
① 【《StkQualnetScenarioExplorer.cs》】的[ OnEntityAddNetworkInterfaceMenuItemClick ]:
源码如下:
private void OnEntityAddNetworkInterfaceMenuItemClick(object sender, EventArgs e)
{
EntityTreeNode entityTreeNode = this.EntityContextMenu.Tag as EntityTreeNode;
if (entityTreeNode != null && entityTreeNode.Entity != null)
{
NetworkInterfaceForm networkInterfaceForm = new NetworkInterfaceForm(null, entityTreeNode.Entity, this.StkRoot);
if (networkInterfaceForm.ShowDialog() == DialogResult.OK)
{
NetworkInterface networkInterface = networkInterfaceForm.GetNetworkInterface();
entityTreeNode.Entity.NetworkInterfaces.Add(networkInterface);
entityTreeNode.InterfacesNode.Nodes.Add(new NetworkInterfaceTreeNode(networkInterface));
}
}
}
② 【《NetworkInterfaceForm.cs》】的[ public NetworkInterface GetNetworkInterface() ]
源码如下:
public NetworkInterface GetNetworkInterface()
{
if (this.m_networkInterface == null)
{
this.m_networkInterface = new NetworkInterface(this.InterfaceName);
}
else
{
this.m_networkInterface.Name = this.InterfaceName;
}
IAgStkObject agStkObject = null;
if (this.transmitterInstanceNameCombo.SelectedIndex < 0)
{
IAgStkObject agStkObject2 = this.m_stkRoot.GetObjectFromPath(this.m_parentEntity.StkObjectPath.PathString);
if (this.useTransmitterSensor.Checked)
{
if (this.transmitterSensorCombo.SelectedIndex < 0)
{
try
{
agStkObject = (agStkObject2 = agStkObject2.Children.New(AgESTKObjectType.eSensor, this.transmitterSensorCombo.Text));
goto IL_B5;
}
catch
{
agStkObject2 = null;
goto IL_B5;
}
}
agStkObject2 = (this.transmitterSensorCombo.SelectedItem as ComboBoxItem).Item as IAgStkObject;
}
IL_B5:
try
{
if (agStkObject2 != null)
{
IAgStkObject agStkObject3 = agStkObject2.Children.New(AgESTKObjectType.eAntenna, this.transmitterInstanceNameCombo.Text);
this.m_networkInterface.TransmitAntennaStkPath = agStkObject3.Path;
}
goto IL_11E;
}
catch
{
goto IL_11E;