The following examples will show you how to list all of the files in a folder and sub folder.
static void GetFilesInFoldersAndSubFolders(Args _args)
{
System.String[] filePaths = System.IO.Directory::GetFiles(@"folder location", "*.*", System.IO.SearchOption::AllDirectories); //get listing of all files within the folder
int fileCount = filepaths.get_Length(); //get how many files were found
int currentFileCount;
//go throw each one of the files that were found
for(currentFileCount = 0; currentFileCount < fileCount ; ++currentFileCount)
{
info(filepaths.GetValue(currentFileCount));
}
}
Friday, December 19, 2014
Send xml to BarTender via TCP sockets and get response back using UTF-8 encoding
This is an example that can be used to send print jobs/print previews (return jpgs/images via raw text) to the BarTender labeling system or using this example as a foundation to talk to your own servers via tcp sockets
/// <summary>
/// Send print job btxml string to bartender and get a response back
/// </summary>
/// <param name="defaultXML">
/// the BTXML to send to bartender
/// </param>
/// <returns>
///BarTenderStaus if it was successfull or not
/// </returns>
public BarTenderStaus sendPrintJobTCP(str defaultXML)
{
str response;
XmlTextReader xmlTextReader;
boolean msgFound;
System.Text.Encoding encoding;
str errorId;
boolean errorsFound;
str message;
SysOperationProgress previewProgress;
System.Net.Sockets.TcpClient barTenderClient;
System.Net.Sockets.NetworkStream stream;
System.IO.StreamReader reader;
System.Byte[] send_bytes;
#avifiles
try
{
//setup progress bar so we can let the user know what we are doing
previewProgress = SysOperationProgress::newGeneral(#AviPublish2Web, 'Sending Print Job To BarTender', 7);
if(serverSettings.BarTenderServerName == "" || serverSettings.BarTenderServerPortNumber == 0)
{
throw error("No valid BarTender server has been defined. Please contact IT.");
}
//update progress bar
previewProgress.incCount();
previewProgress.setText("Task: Reading XML...");
message = defaultXML;
//check to see if we have something available to send to the server
if(message == "")
{
throw error("No items are available to print");
}
//update progress bar
previewProgress.incCount();
previewProgress.setText("Task: Connecting to BarTender Server...");
//make connection to bartender and open stream with UTF8 encoding
barTenderClient = new System.Net.Sockets.TcpClient(serverSettings.BarTenderServerName, serverSettings.BarTenderServerPortNumber);
stream = barTenderClient.GetStream();
reader = new System.IO.StreamReader(stream, System.Text.Encoding::get_UTF8());
//update progress bar
previewProgress.incCount();
previewProgress.setText("Task: Sending Label to BarTender...");
//define the stream encoding as UTF8
encoding = System.Text.Encoding::get_UTF8();
//convert the xml to bytes to send to bartender
send_bytes = encoding.GetBytes(message);
//send the xml bytes to bartender
stream.Write(send_bytes, 0, send_bytes.get_Length());
//update progress bar
previewProgress.incCount();
previewProgress.setText("Task: Reading Response From BarTender...");
//get the response bartender sends back
response = reader.ReadToEnd();
//close the bartender stream
stream.Close();
//update progress bar
previewProgress.incCount();
previewProgress.setText("Task: Analyzing XML Response from BarTender...");
//we need to parse the xml response string into xml nodes
xmlTextReader = XmlTextReader::newXml(response, true);
//loop through all of the xml nodes
while(xmlTextReader.read())
{
//check to see what type of xml node we are currently on
switch (xmlTextReader.NodeType())
{
case XmlNodeType::Element:
//check to see if we are on the message node
if(xmlTextReader.Name() == "Message")
{
//read the message attributes
while (xmlTextReader.MoveToNextAttribute())
{
//check to see if the attributes node is severity
if(xmlTextReader.Name() == "Severity")
{
//check to see if we are looking at an error
if(xmlTextReader.Value() == "Error")
{
//error has been found
msgFound = true;
errorsFound = true;
}
}
else if(xmlTextReader.Name() == "Id")
{
//define what the id attribute is incase it is an error
errorId = xmlTextReader.Value();
}
}
}
break;
case XmlNodeType::Text:
//check to see if the last node we were on was a message and if it was an error
if(msgFound)
{
//display error message to user in a friendly manner
setPrefix("BarTender Error " + errorId);
error(xmlTextReader.Value());
//reset message found flag
msgFound = false;
}
break;
case XmlNodeType::EndElement: //Display the end of the element.
break;
default:
break;
}
}
//update progress bar
previewProgress.setText("Task: Finished");
previewProgress.setTotal(7);
previewProgress.hide();
//check to see if any errors occured
if(!errorsFound)
{
return BarTenderStaus::Success;
}
else
{
return BarTenderStaus::Failure;
}
}
catch
{
error("There was an unknown error communicating with the BarTender server. Please restart your computer and try again. If the issue continues please alert IT of this issue.");
//update progress bar
previewProgress.setText("Task: Finished");
previewProgress.setTotal(7);
previewProgress.hide();
return BarTenderStaus::Failure;
}
}
/// <summary>
/// Send print job btxml string to bartender and get a response back
/// </summary>
/// <param name="defaultXML">
/// the BTXML to send to bartender
/// </param>
/// <returns>
///BarTenderStaus if it was successfull or not
/// </returns>
public BarTenderStaus sendPrintJobTCP(str defaultXML)
{
str response;
XmlTextReader xmlTextReader;
boolean msgFound;
System.Text.Encoding encoding;
str errorId;
boolean errorsFound;
str message;
SysOperationProgress previewProgress;
System.Net.Sockets.TcpClient barTenderClient;
System.Net.Sockets.NetworkStream stream;
System.IO.StreamReader reader;
System.Byte[] send_bytes;
#avifiles
try
{
//setup progress bar so we can let the user know what we are doing
previewProgress = SysOperationProgress::newGeneral(#AviPublish2Web, 'Sending Print Job To BarTender', 7);
if(serverSettings.BarTenderServerName == "" || serverSettings.BarTenderServerPortNumber == 0)
{
throw error("No valid BarTender server has been defined. Please contact IT.");
}
//update progress bar
previewProgress.incCount();
previewProgress.setText("Task: Reading XML...");
message = defaultXML;
//check to see if we have something available to send to the server
if(message == "")
{
throw error("No items are available to print");
}
//update progress bar
previewProgress.incCount();
previewProgress.setText("Task: Connecting to BarTender Server...");
//make connection to bartender and open stream with UTF8 encoding
barTenderClient = new System.Net.Sockets.TcpClient(serverSettings.BarTenderServerName, serverSettings.BarTenderServerPortNumber);
stream = barTenderClient.GetStream();
reader = new System.IO.StreamReader(stream, System.Text.Encoding::get_UTF8());
//update progress bar
previewProgress.incCount();
previewProgress.setText("Task: Sending Label to BarTender...");
//define the stream encoding as UTF8
encoding = System.Text.Encoding::get_UTF8();
//convert the xml to bytes to send to bartender
send_bytes = encoding.GetBytes(message);
//send the xml bytes to bartender
stream.Write(send_bytes, 0, send_bytes.get_Length());
//update progress bar
previewProgress.incCount();
previewProgress.setText("Task: Reading Response From BarTender...");
//get the response bartender sends back
response = reader.ReadToEnd();
//close the bartender stream
stream.Close();
//update progress bar
previewProgress.incCount();
previewProgress.setText("Task: Analyzing XML Response from BarTender...");
//we need to parse the xml response string into xml nodes
xmlTextReader = XmlTextReader::newXml(response, true);
//loop through all of the xml nodes
while(xmlTextReader.read())
{
//check to see what type of xml node we are currently on
switch (xmlTextReader.NodeType())
{
case XmlNodeType::Element:
//check to see if we are on the message node
if(xmlTextReader.Name() == "Message")
{
//read the message attributes
while (xmlTextReader.MoveToNextAttribute())
{
//check to see if the attributes node is severity
if(xmlTextReader.Name() == "Severity")
{
//check to see if we are looking at an error
if(xmlTextReader.Value() == "Error")
{
//error has been found
msgFound = true;
errorsFound = true;
}
}
else if(xmlTextReader.Name() == "Id")
{
//define what the id attribute is incase it is an error
errorId = xmlTextReader.Value();
}
}
}
break;
case XmlNodeType::Text:
//check to see if the last node we were on was a message and if it was an error
if(msgFound)
{
//display error message to user in a friendly manner
setPrefix("BarTender Error " + errorId);
error(xmlTextReader.Value());
//reset message found flag
msgFound = false;
}
break;
case XmlNodeType::EndElement: //Display the end of the element.
break;
default:
break;
}
}
//update progress bar
previewProgress.setText("Task: Finished");
previewProgress.setTotal(7);
previewProgress.hide();
//check to see if any errors occured
if(!errorsFound)
{
return BarTenderStaus::Success;
}
else
{
return BarTenderStaus::Failure;
}
}
catch
{
error("There was an unknown error communicating with the BarTender server. Please restart your computer and try again. If the issue continues please alert IT of this issue.");
//update progress bar
previewProgress.setText("Task: Finished");
previewProgress.setTotal(7);
previewProgress.hide();
return BarTenderStaus::Failure;
}
}
Thursday, October 23, 2014
C# Accessing AX Session Information & Defining which AOS to connect to via code
So while working on the last post I ran into an issue where I couldn't change which aos the data was being pulled in from so I wrote the following function that gets server information so you can see basic information on what connection is being used. Along with defining which AOS the code pulls from by defining a server within code so I can switch back and forth between DEV & TEST
You can download the C# visual studio project here: download now!
Its good to note that around the web the following "logon" statement is posted
// Logon to Dynamics AX
Session axSession = new Session();
axSession.Logon(null, null, null, null);
However in order to define which AOS server to connect to via code we need to do the following
// Logon to Dynamics AX
Session axSession = new Session();
axSession.Logon(null, null, "AOSServerName", null);
The following code are just some ways to pull in basic server information
private void GetAOSInfo_Click(object sender, EventArgs e)
{
try
{
// Logon to Dynamics AX
Session axSession = new Session();
axSession.Logon(null, null, axServerName, null);
//get server information
string axInfoAOSInstance = axSession.CreateObject("XSession").Call("AOSName").ToString();
string axInfoClientName = axSession.CreateObject("XSession").Call("clientComputerName").ToString();
string axInfoLoginDateTime = axSession.CreateObject("XSession").Call("loginDateTime").ToString();
string axInfoMasterSessionId = axSession.CreateObject("XSession").Call("sessionId").ToString();
string axInfoUserId = axSession.CreateObject("XSession").Call("userId").ToString();
CustomerOutput.Clear();
CustomerOutput.AppendText(("AOS Server: " + axInfoAOSInstance));
CustomerOutput.AppendText((Environment.NewLine + "Client Computer Name: " + axInfoClientName));
CustomerOutput.AppendText((Environment.NewLine + "Session Id: " + axInfoMasterSessionId));
CustomerOutput.AppendText((Environment.NewLine + "Login DateTime: " + axInfoLoginDateTime));
CustomerOutput.AppendText((Environment.NewLine + "User Id: " + axInfoUserId));
//log off ax
axSession.Logoff();
}
catch (Exception ex)
{
CustomerOutput.Clear();
CustomerOutput.AppendText(ex.Message.ToString());
}
}
You can download the C# visual studio project here: download now!
Its good to note that around the web the following "logon" statement is posted
// Logon to Dynamics AX
Session axSession = new Session();
axSession.Logon(null, null, null, null);
However in order to define which AOS server to connect to via code we need to do the following
// Logon to Dynamics AX
Session axSession = new Session();
axSession.Logon(null, null, "AOSServerName", null);
The following code are just some ways to pull in basic server information
private void GetAOSInfo_Click(object sender, EventArgs e)
{
try
{
// Logon to Dynamics AX
Session axSession = new Session();
axSession.Logon(null, null, axServerName, null);
//get server information
string axInfoAOSInstance = axSession.CreateObject("XSession").Call("AOSName").ToString();
string axInfoClientName = axSession.CreateObject("XSession").Call("clientComputerName").ToString();
string axInfoLoginDateTime = axSession.CreateObject("XSession").Call("loginDateTime").ToString();
string axInfoMasterSessionId = axSession.CreateObject("XSession").Call("sessionId").ToString();
string axInfoUserId = axSession.CreateObject("XSession").Call("userId").ToString();
CustomerOutput.Clear();
CustomerOutput.AppendText(("AOS Server: " + axInfoAOSInstance));
CustomerOutput.AppendText((Environment.NewLine + "Client Computer Name: " + axInfoClientName));
CustomerOutput.AppendText((Environment.NewLine + "Session Id: " + axInfoMasterSessionId));
CustomerOutput.AppendText((Environment.NewLine + "Login DateTime: " + axInfoLoginDateTime));
CustomerOutput.AppendText((Environment.NewLine + "User Id: " + axInfoUserId));
//log off ax
axSession.Logoff();
}
catch (Exception ex)
{
CustomerOutput.Clear();
CustomerOutput.AppendText(ex.Message.ToString());
}
}
Accessing AX CustTable & DirPatyTable (Customer Info) via C# via Linq.
In order to support legacy applications sometimes you need to pull in data from AX into standalone applications. Below will show you how to pull in customer id's + names (CustTable + DirPartyTable)
The following examples will show you how to manually loop through that data or tie it to a combo box via Linq.
You can download the C# Visual Studio Project Here: download now!
Step 1. Start new project within visual studio that has access to an aos via the application explorer
Step 2. Adding the following references to the visual studio project
C:\Program Files (x86)\Microsoft Dynamics AX\6.0\Client\Bin\
Microsoft.Dynamics.AX.Framework.Linq.Data.dll
Microsoft.Dynamics.AX.Framework.Linq.Data.Interface.dll
Microsoft.Dynamics.AX.Framework.Linq.Data.ManagedInteropLayer.dll
Microsoft.Dynamics.AX.ManagedInterop.dll
Then on your form/class add the following using classes
using Microsoft.Dynamics.AX.ManagedInterop;
using Microsoft.Dynamics.AX.Framework.Linq.Data;
using System.Linq;
Step 3. Right click on project and add to AOT
Step 4. After step 3 you can start to add objects from the application explorer into the project. Add this time we should add the table CustTable & DirPartyTable
The following code block will show you how to connect to ax, query the tables and loop through the data or tie it to multiple combo boxes. Its good to note that my name space for this project was Win2AX.
The following examples will show you how to manually loop through that data or tie it to a combo box via Linq.
You can download the C# Visual Studio Project Here: download now!
Step 1. Start new project within visual studio that has access to an aos via the application explorer
Step 2. Adding the following references to the visual studio project
C:\Program Files (x86)\Microsoft Dynamics AX\6.0\Client\Bin\
Microsoft.Dynamics.AX.Framework.Linq.Data.dll
Microsoft.Dynamics.AX.Framework.Linq.Data.Interface.dll
Microsoft.Dynamics.AX.Framework.Linq.Data.ManagedInteropLayer.dll
Microsoft.Dynamics.AX.ManagedInterop.dll
Then on your form/class add the following using classes
using Microsoft.Dynamics.AX.ManagedInterop;
using Microsoft.Dynamics.AX.Framework.Linq.Data;
using System.Linq;
Step 3. Right click on project and add to AOT
Step 4. After step 3 you can start to add objects from the application explorer into the project. Add this time we should add the table CustTable & DirPartyTable
The following code block will show you how to connect to ax, query the tables and loop through the data or tie it to multiple combo boxes. Its good to note that my name space for this project was Win2AX.
public void loadCustomers(Boolean listInTextBox)
{
try
{
isCustomersLoaded = false;
// Logon to Dynamics AX (usering windows logon info)
Session axSession = new Session();
axSession.Logon(null, null, axServerName, null);
// Create a query provider needed by the Linq Provider
QueryProvider provider = new AXQueryProvider(null);
//Connect to the table proxy's for the CustTable and DirPartTable tables within AX.
QueryCollection<Win2AX.CustTable> customerCollection = new QueryCollection<Win2AX.CustTable>(provider);
QueryCollection<Win2AX.DirPartyTable> partyCollection = new QueryCollection<Win2AX.DirPartyTable>(provider);
//select the account num and dirparty name so we can provide an account num + name
//its good to note that when I didnt include a field list the app crashed. I think linq is limited to the amount of data that can be processed
var allCustomers = (from customer in customerCollection
join partyDesc in partyCollection on customer.Party equals partyDesc.RecId
orderby customer.AccountNum ascending
select new { customer.AccountNum, partyDesc.Name, Description = customer.AccountNum + " - " + partyDesc.Name }).ToList();
allCustomers.Insert(0, new { AccountNum = "<Select Customer>", Name = "<Select Customer>", Description = "<Select Customer>" });
if (listInTextBox)
{
CustomerOutput.Clear();
//go through all of the records
foreach (var custTable in allCustomers)
{
//output the current record
CustomerOutput.AppendText(Environment.NewLine + "Customer Account: " + custTable.AccountNum + " Description: " + custTable.Name);
}
}
else if (!listInTextBox)
{
//bind all combo boxes to our linq list
//combination (Customer Id - Name)
CustomerList.DataSource = allCustomers;
CustomerList.DisplayMember = "Description";
CustomerList.ValueMember = "AccountNum";
//Customer Id only
CustomerIdSelection.DataSource = allCustomers;
CustomerIdSelection.DisplayMember = "AccountNum";
CustomerIdSelection.ValueMember = "AccountNum";
//Name Selection / Account Num Value
CustomerNameSelection.DataSource = allCustomers;
CustomerNameSelection.DisplayMember = "Name";
CustomerNameSelection.ValueMember = "AccountNum";
//signal that all combo boxes are loaded so we can handle comboboxes selected index changes correctly
isCustomersLoaded = true;
}
//log off ax
axSession.Logoff();
}
catch (Exception ex)
{
CustomerOutput.Clear();
CustomerOutput.AppendText(ex.Message.ToString());
}
Friday, October 10, 2014
Failed to create a session; confirm that the user has the proper privileges to log on to Microsoft Dynamics
Currently we have a developer working/coding in an active environment where users are currently using the system (non-prod) and had an issue generating good incremental CIL. During this time some of the users started to see the following message
"Failed to create a session; confirm that the user has the proper privileges to log on to Microsoft Dynamics"
In order to resolve this issue try the following
File/Tools/Options/Development/ uncheck the option for "Execute business operations in CIL"
This ended up fixing our issue, but after reading multiple other blogs about AX if this doesn't work then the next step is to run a full CIL. If that doesn't work you should restart the AOS and run the full CIL again.
"Failed to create a session; confirm that the user has the proper privileges to log on to Microsoft Dynamics"
In order to resolve this issue try the following
File/Tools/Options/Development/ uncheck the option for "Execute business operations in CIL"
This ended up fixing our issue, but after reading multiple other blogs about AX if this doesn't work then the next step is to run a full CIL. If that doesn't work you should restart the AOS and run the full CIL again.
Wednesday, September 24, 2014
Custom barcode and MICR fonts on SSRS reports from AX 2012 display correctly but will not print or export
So with AX 2012 you may want to display a custom, barcode, or micr font on a report to print for the bank or factory floor. By default a lot of these fonts get installed but some do not. What I have found out is that it will display correctly within the report window but whenever you try to print it or export it does not export the font correctly. In order to resolve the issue the following needs to be done
If this does not work try reinstalling the font thru the control panel.
- Install font on AOS
- If you are running an AX Cluster be sure to install it on all AOS's
- Install font on SQL/SSRS box
- If you are running a SQL cluster be sure to install it on all AOS's
- When installing be sure to install the font thru the control panel>fonts and not C:\windows\fonts for some odd reason windows server 2012 R1+ does not always install the font correctly when you copy to the specific folder but it does if you use the control panel
- Reboot SQL boxes
- Reboot AX AOS boxes
If this does not work try reinstalling the font thru the control panel.
Thursday, September 11, 2014
Firming Production Orders Crashes AOS: Object Server 01: An error has occurred in the services framework. Method: AifMessageInspector::AfterReceiveRequest. Error: System.ServiceModel.FaultException: Failed to logon to Microsoft Dynamics AX.
The issue: When firming a production order sometimes it may cause for all
the AOS's in a cluster to crash and restart.
The setup: 2 AOS cluster with 1 Batch AOS (3 AOS's in total)
The research: Because firming the PO sometimes would not crash the AOS's I looked into the windows log whenever it did and found the following error:
Object Server 01: An error has occurred in the services framework. Method: AifMessageInspector::AfterReceiveRequest. Error: System.ServiceModel.FaultException: Failed to logon to Microsoft Dynamics AX.
Update:
Issue continues to be random even after all of this. After looking at a KB article from Microsoft we have also added the AX AOS Service & Bus Con accounts to the Active Directory groups
Windows Authorization Access group & Pre-Windows 2000 Compatibility Access group (within active directory)
But we still seem to have to have the same issue. I will keep this article updated with anything else we try.
Update 3/11/15: The issue continues and we started to work with Microsoft and they were able to track down the class & table that was causing the issue. It appears there is a KB fix for this specific issue.
Issue Location: \tables\ReqTrans & \class\ReqTransPoMarkFirm
KB2936744
The setup: 2 AOS cluster with 1 Batch AOS (3 AOS's in total)
The research: Because firming the PO sometimes would not crash the AOS's I looked into the windows log whenever it did and found the following error:
Object Server 01: An error has occurred in the services framework. Method: AifMessageInspector::AfterReceiveRequest. Error: System.ServiceModel.FaultException: Failed to logon to Microsoft Dynamics AX.
at
Microsoft.Dynamics.Ax.Services.AxServiceOperationContext.InitializeSession()
at
Microsoft.Dynamics.Ax.Services.AxServiceOperationContext.InitializeContext()
at
Microsoft.Dynamics.Ax.Services.AxServiceOperationContext.Attach(OperationContext
owner)
at System.ServiceModel.ExtensionCollection`1.InsertItem(Int32 index,
IExtension`1 item)
at System.Collections.Generic.SynchronizedCollection`1.Add(T
item)
at
Microsoft.Dynamics.Ax.Services.AifMessageInspector.AfterReceiveRequest(Message&
request, IClientChannel channel, InstanceContext instanceContext)
Because the begining of the message contains "Failed to logon to
Microsoft Dynamics" you know it is something dealing with creditials. Currently
we have an account for the service called domain\AX_AOS_Service and an account
for the .NET Business Connector called domain\AX_BusCon so I knew that it had to
deal with one of these.
Action/Solution (Here is what I did to fix the issue):
- Make sure an SSRS default config instance is available for every aos. Including the batch server
- Add the AOS service account to the users in AX. This account should be added to the groups "System User" and "System Administrator" (leave employee off)
- Changed the report servers within AX from looking at a single sql server to the sql cluster (individual server vs SQL cluster)
- Changed the "Batch Group" (under system administration > setup > batch group) so that only batch servers were listed in any of these and the empty batch group was changed to have no servers. Before it contained non batch servers listed as batch servers
- Restart all 3 AOS's (Microsoft service/via services.msc)
- After restarting the AOS it would still crash but not as often. I would also now start get the following message instead of the original one
- The description for Event ID 180 from source Microsoft
Dynamics AX cannot be found. Either the component that raises this event is not
installed on your local computer or the installation is corrupted. You can
install or repair the component on the local computer. If the event
originated on another computer, the display information had to be saved with the
event. The following information was included with the event:
Microsoft Dynamics AX Business Connector Session 9.
RPC exception 1722 in Ping occurred in session 19 ,process: Ax32.exe ,thread: 8456
- This message tells us that there is still an issue but no longer a specific one but generic. These type of messages are usually fixed by a system reboot.
- Restart all 3 AOS's boxes and not just the service (systems/windows)
Update:
Issue continues to be random even after all of this. After looking at a KB article from Microsoft we have also added the AX AOS Service & Bus Con accounts to the Active Directory groups
Windows Authorization Access group & Pre-Windows 2000 Compatibility Access group (within active directory)
But we still seem to have to have the same issue. I will keep this article updated with anything else we try.
Update 3/11/15: The issue continues and we started to work with Microsoft and they were able to track down the class & table that was causing the issue. It appears there is a KB fix for this specific issue.
Issue Location: \tables\ReqTrans & \class\ReqTransPoMarkFirm
KB2936744
PROBLEM
Update on ReqTransPoMarkFirm crashing Application Object Server (AOS).
DESCRIPTION OF CHANGE
The changes in the hotfix resolve this issue.
The table method ReqTrans.reqTransDirectlyDerived() is using a code pattern that’s not supported. As hightlighted below, the method is returning a table variable that’s in the JOIN clause and holds a where condition that references a local table variable (i.e. reqTransCov). This leads to invalid cursor when ::update is called upon the returned table variable.
Changing the X++ select in ReqTrans.reqTransDirectlyDerived() so that reqTrans is the main and reqTransCov is in the JOIN clause. Since ReqTransCov is never used, put it in exists join.
You may also need KB2629981 - Orders can be firmed more than once, which leads to duplicate planned orders.
With the issue of AifMessageInspector::AfterReceiveRequest. Error: System.ServiceModel.FaultException: Failed to logon to Microsoft Dynamics AX.
If you turn off debugging on the specific aos it will no longer appear.
You may also need KB2629981 - Orders can be firmed more than once, which leads to duplicate planned orders.
With the issue of AifMessageInspector::AfterReceiveRequest. Error: System.ServiceModel.FaultException: Failed to logon to Microsoft Dynamics AX.
If you turn off debugging on the specific aos it will no longer appear.
Friday, August 8, 2014
Opening specific form in AX from external application or windows shortcut
When working with the last ERP system I used (Infor Visual ERP) we always had the option to create a pretty generic .txt file and convert it to a shortcut so it would open the application, open a specific form and jump to a specific record.
So far in AX I have figured out how to open AX from an external source and jump to a specific form but I have not figured out how to make it jump to a specific record. Maybe that will be in a later post.
But thanks to http://msdn.microsoft.com/en-us/library/jj677292.aspx I can show you an provide examples on how to open a specific form in AX
Opening AX via a shortcut:
Download the following zip and inside you will find a .vbs file. Simply make a shortcut with the following properties
https://drive.google.com/file/d/0B7mPpWNLDR1Xd1ZxUlRHWHV1OHc/edit?usp=sharing
<location of vbs file>.vbs -c <company> -d "<menu item name>"
Example : C:\openAX.vbs -c TEST -d "InventQualityOrderTable"
Opening AX via a C# application:
https://drive.google.com/file/d/0B7mPpWNLDR1XRW1xVEpKTGN5MGs/edit?usp=sharing
The above link provide a basic application that will show you how to open AX the only requirement is that you will need to add a reference to the COM object Dynamics AX Client 1.0 Type Library
Then add
using AxClientLib;
private void button1_Click(object sender, EventArgs e)
{
AxClientLib.DynamicsAxApplication axComClient = new AxClientLib.DynamicsAxApplication();
try
{
//find running Ax32.exe
axComClient.OpenMenuItem("FWM", "BatchTraceStandAloneUIMenuItem", AxClientLib.AxMenuType.DisplayMenu);
}
catch
{
MessageBox.Show("failed");
}
}
So far in AX I have figured out how to open AX from an external source and jump to a specific form but I have not figured out how to make it jump to a specific record. Maybe that will be in a later post.
But thanks to http://msdn.microsoft.com/en-us/library/jj677292.aspx I can show you an provide examples on how to open a specific form in AX
Opening AX via a shortcut:
Download the following zip and inside you will find a .vbs file. Simply make a shortcut with the following properties
https://drive.google.com/file/d/0B7mPpWNLDR1Xd1ZxUlRHWHV1OHc/edit?usp=sharing
<location of vbs file>.vbs -c <company> -d "<menu item name>"
Example : C:\openAX.vbs -c TEST -d "InventQualityOrderTable"
Opening AX via a C# application:
https://drive.google.com/file/d/0B7mPpWNLDR1XRW1xVEpKTGN5MGs/edit?usp=sharing
The above link provide a basic application that will show you how to open AX the only requirement is that you will need to add a reference to the COM object Dynamics AX Client 1.0 Type Library
Then add
using AxClientLib;
private void button1_Click(object sender, EventArgs e)
{
AxClientLib.DynamicsAxApplication axComClient = new AxClientLib.DynamicsAxApplication();
try
{
//find running Ax32.exe
axComClient.OpenMenuItem("FWM", "BatchTraceStandAloneUIMenuItem", AxClientLib.AxMenuType.DisplayMenu);
}
catch
{
MessageBox.Show("failed");
}
}
Subscribe to:
Posts (Atom)