AX 2012 - Get Instance Name not Server Name in X++ - axapta

Is it possible to get the Instance Name instead of the Server Name in X++?
The attached image shows the field I am looking for:
When I use xSession.AOSName(); it returns the Server Name and when I use sysServerSessions..Instance_Name; an empty string is returned. The Instance_Name field only has "01" in the database so it would still be incorrect if it did return a value.

The Instance name (optional), I believe is just the folder name and the service display name. So when you create multiple instances, it creates a folder C:\Program Files\Microsoft Dynamics AX\60\Server\[InstanceName]\, and then an AOS service with that instance display name.
If you really want it, you could enumerate the folder and parse it using a regular expression or any number of other methods. To enumerate the folder, create this server static method somewhere and call it:
static server FilenameOpen pathServer()
{
return xInfo::directory(DirectoryType::Bin);
}
There is also a ServerId, which I don't think is the same as the Instance Name, but it's in the SysServerConfig table:
while select sysServerConfig
{
info(strFmt("%1", sysServerConfig.ServerId));
}
And the ServerId is a derived value from the AOSId and name, etc. You can see how it's derived in this method:
\Data Dictionary\Tables\SysServerConfig\Methods\delete

Below is the added logic to Alex's answer to get the Instance Name.
static server str getAOSInstanceName()
{
str serverPath;
str instanceName;
int fullPathLen;
int serverNameEnd;
int instanceNameStart;
//Get the full path of the AOS Server install.
serverPath = xInfo::directory(DirectoryType::Bin);
fullPathLen = strLen(serverPath);
//Get the location of where the Instance Names Ends. "-5" represents "\bin\" in the full path.
serverNameEnd = fullPathLen - 5;
//Get the location where the Instance Name Starts - 1.
instanceNameStart = strFind(serverPath, #"\", serverNameEnd, - fullPathLen);
//Get the Instance Name.
instanceName = subStr(serverPath, instanceNameStart + 1, serverNameEnd - serverNameStart);
return instanceName;
}

Related

save image on file system instead of DB

I m developping an application where user can provide text informations and images. I want to save images on file system and in DB, I will add a link of each user to its images So I need to add the user ID to the image name to not get images with same name. I m using SPRING MVC.
in my Controller :
#RequestMapping(value="/save",method=RequestMethod.POST)
public String add ( #RequestParam("prix") Long prix,
RequestParam("adresse") String ville,
#RequestParam("categorie") String categorie,
#RequestParam("photos") MultipartFile file,
) throws FileNotFoundException
{
String chemin=null;
if (!file.isEmpty())
{
try {
String orgName = file.getOriginalFilename();
// this line to retreive just file name
String
name=orgName.substring(orgName.lastIndexOf("\\")+1,orgName.length());
chemin="e:\\images\\"+name; //here I want to add id (auto generated)
File file1=new File(chemin);
file.transferTo(file1);
} catch (IOException e) {
e.printStackTrace();
}
}
annonce.setImage(chemin);
annonce.setTitre(prix);
annonce.setCorps(ville);
annonce.setPrix(cetegorie)
annoncedao.save(annonce);
return "SuccessAddAnnonce";
}
but I can not get the ID witch is auto generated so I can not get it throw #RequestParam like adress or categorie because it is auto generated and I still don t have it until we call save method witch is last .
Any suggestions are welcome .
I got the Id using query with Select max (id)
#Query("SELECT MAX(id) FROM Annonce")
Long findAutoincrementAnnonce();
I wish help someone.
You can generate a random ID for each user and assign it to a particular user, and thus its image name also (what you intend to do here I guess).
I will illustrate it simply.
// Get a random ID coressponding to the user address or whatever, here i will just use address
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] hash = digest.digest(ville.getBytes("UTF-8"));
String randomId = DatatypeConverter.printHexBinary(hash);
// Here you have a uniqueID for an address.
// You could have just used ville.hashCode() also but it might give you collisions with some different Strings.
if Input: "64th Street, Downtown, StackOverFlow" then
randomId = 8AB126F8EBC0F7B5CCBBEB3E21582ADF

Changing dataset connection string in web config at runtime

I have a c# generated dataset.
How can I change the connection string so I can use the dataset with another (identically structured yet differently populated) database?
This has to occur at runtime as I do not know the server or database name at compile time. I am using c# 3.5.
I think there is no simple way and you cannot change the Connection-String programmatically for the entire DataSet since it's defined for every TableAdapter.
You need to create the partial class of the TableAdapter to change the connection-string since the Connection property is internal (if your DAL is in a different assembly). Don't change the designer.cs file since it will be recreated automatically after the next change on the designer. To create it just right-click the DataSet and chose "show code".
For example (assuming the TableAdapter is named ProductTableAdapter):
namespace WindowsFormsApplication1.DataSet1TableAdapters
{
public partial class ProductTableAdapter
{
public string ConnectionString {
get { return Connection.ConnectionString; }
set { Connection.ConnectionString = value; }
}
}
}
Now you can change it easily:
var productTableAdapter = new DataSet1TableAdapters.ProductTableAdapter();
productTableAdapter.ConnectionString = someOtherConnectionString;
Here's a screenshot of my sample DataSet and the created file DataSet1.cs:
ide mvs 2008
in your settings.designer.cs verifier or edit this
public string NamOfappConnectionString{
get {
return ((string)(this["NamOfappConnectionString"]));
}
//add this line
set {
this["NamOfappConnectionString"]=value;
}
}
//atr untime use this
string myconnexion = "Data Source=" + txt_data_source.Text + ";Initial Catalog=" + txt_initial_catalog.Text + ";Persist Security Info=True;";
ConfigurationManager.AppSettings.Set("NamOfappConnectionString", myconnexion);
//save into setting
Properties.Settings.Default.NamOfappConnectionString= myconnexion;
Application.Restart();

Resolve path of IVersionableHandle in RTC

How to get path of file which isn't in newest version but is a part of previous changelist in RTC scm.
All I could achieve so far is this:
IFileItemHandle fileItemHandle = (IFileItemHandle) IFileItem.ITEM_TYPE.createItemHandle(change.afterState().getItemId(), change.afterState().getStateId());
file = versionableManager.fetchCompleteState(fileItemHandle, monitor);
if (file instanceof IFolder) {
IFolder folder = (IFolder) file;
relativePath = getFilePath(file, workspaceConnection.configuration(changeSet.getComponent()), monitor);
fileName = folder.getName();
} else {
relativePath = getFilePath(file, workspaceConnection.configuration(changeSet.getComponent()), monitor);
fileName = ((FileItem) file).getName();
}
Where getFilePath is:
private String getFilePath(IVersionableHandle folder, IConfiguration config, IProgressMonitor monitor, Boolean searchInHistory) throws TeamRepositoryException {
List lst = new ArrayList<IVersionableHandle>(), ancestors;
lst.add(folder);
if (searchInHistory) {
ancestors = config.determineAncestorsInHistory(lst, monitor);
} else {
ancestors = config.locateAncestors(lst, monitor);
}
return getFullPath(ancestors);
}
private String getFullPath(List ancestor) throws TeamRepositoryException {
String directoryPath = "";
for (Object ancestorObj : ancestor) {
IAncestorReport ancestorImpl = (IAncestorReport) ancestorObj;
for (Object nameItemPairObj : ancestorImpl.getNameItemPairs()) {
INameItemPair nameItemPair = (INameItemPair) nameItemPairObj;
String pathName = nameItemPair.getName();
if (pathName != null && !pathName.equals("")) {
directoryPath = directoryPath + "\\" + pathName;
}
}
}
return directoryPath;
}
Unfortunately it doesn't work perfectly. If filename is changed in following changelists like on this example:
Changelist 1:
add file: src/newFile.java
Changelist 2:
modify file: src/newFile.java
Changelist 3:
rename file: src/newFile.java -> src/newFile_rename.java
The relative path resolved in first changelist would be:
src/newFile_rename.java
instead of
src/newFile.java
How to make it works good?
While the javadoc for IConfiguration.determineAncestorsInHistory doesn't specify, the server side equivalent IScmService.configurationDetermineAncestorsInHistory (which is what ends up being called) says this in the javadoc:
* #param versionableItemHandles
* a list of versionable items; only the item ids are needed;
* must not be <code>null</code>
Basically, the determineAncestorsInHistory is not looking at the state id on the file handles, it only looks at the item id.
The particular state of the file that will be considered is determined by the configuration. This is mostly because while the state of the file in the changeset will tell you the name of that file, it does not tell you the name of the parent folder. That will depend on the state of the folder that is present in the workspace at a particular time and could be different for different workspaces
You basically need to get an IConfiguration that represents your workspace at the time the change set was accepted/created.
The way I see to do this is to get the IWorkspaceConnection.changeHistory(component) (this is actually defined on IFlowNodeConnection). You will need to walk back through the histories by calling IChangeHistory.previousHistory(monitor) until you find one that contains your changeset in IChangeHistory.recent(monitor).
Once you find the appropriate IChangeHistory use IChangeHistory.configuration() for the determineAncestorsInHistory call.
Note that this configuration represents the state of the workspace at the end of that particular IChangeHistory, so to be completely accurate you would need to inspect the changesets that occur after your change in the IChangeHistory.recent to see if any of them modified your file name (or also any of the containing folders' file names).
(Another alternative is to use the history configuration 1 previous to the history that contains your changeset, and then look at the effects of the changes that happen before your change)

Images are getting published with TCM id appended with the image name

Mode of publishing - static
I'm trying to publish images, but the issue is whenever I publish those images, their TCM URI is appended to their name (i.e if image name is example and its TCM URI is like tcm:1-115, image filename becomes example_tcm1-115).
I have written the following code:
public void Transform(Engine engine, Package package)
{
Filter MMCompFilter = new Filter();
MMCompFilter.Conditions["ItemType"] = Tridion.ContentManager.ItemType.Component;
Folder folder = engine.GetObject("tcm:1-1-2") as Folder;
foreach (Component MMcomp in folder.GetItems(MMCompFilter))
{
Binary binary = engine.PublishingContext.RenderedItem.AddBinary(MMcomp);
String binaryurl = binary.Url;
char[] array = binaryurl.ToCharArray();
Array.Reverse(array);
string obj = new string(array);
string final = newImagepath(obj);
char[] array2 = final.ToCharArray();
Array.Reverse(array2);
string obj2 = new string(array2);
package.PushItem("Image", package.CreateHtmlItem(obj2));
}
public string newImagepath(string filePath)
{
int formatIndex =filePath.IndexOf(".");
string format= filePath.Substring(0,formatIndex);
int finalPath=filePath.IndexOf("_");
string newPath=filePath.Substring((finalPath+1));
return (format+"."+newPath);
}
}
I want to publish images without the TCM URI appended to it. Plz suggest how can it be done.
Chris Summers wrote a very nice article on this very topic http://www.urbancherry.net/blogengine/post/2010/02/09/Unique-binary-filenames-for-SDL-Tridion-Multimedia-Components.aspx
It is basically a very simple thing to fix, but can have huge consequences which you should be aware of!
You can only publish a binary with a certain file-name in a single location once (and a binary can only be published to a single location on the presentation server, unless you publish it as a variant). However, in the CMS it is very easy to create Multimedia Components with the same binary file-name in different folders, which if they get published to the same location will be in conflict. That is why by default SDL Tridion appends the TCM URI to the filename to make it unique.
Simplest is always best.
In your TBB, just push the individual images to the package:
package.PushItem(package.CreateMultimediaItem(component.Id));
Then use the "PublishBinariesInPackage" TBB to publish these images to your presentation server.
You can use the RenderedItem.AddBinary method for this goal. Some of the overloaded versions of the method allows to publish an image as a stream, and pass any file name. For example:
public Binary AddBinary(
Stream content,
string filename,
string variantId,
string mimeType
)

Is there a way to get ALL the MIME types instead of wrinting a huge case statement?

I want to populate
Response.ContentType = "text/plain";
From somewhere in the server/web/dictionary ALL possible MIME types according to file extension:
public string GetMimeType(string extension)
{
//This is what I am looking for.
}
Also, I have to rename the file (at least if going to be downloaded, so I have to know in advance if it's going to be opened or not.
You can store the mimetype when the file is uploaded ( FileUpload.PostedFile.ContentType ) and send that when the file is requested.
Umm... why? You're not going to be returning content of every possible type, are you?
Here's a list of common types: http://www.webmaster-toolkit.com/mime-types.shtml. There is no list that would include "ALL" types simply because any application vendor can create a custom one and associate it with a custom extension.
It's going to depend on your platform. Here's one for C# and IIS: http://blog.crowe.co.nz/archive/2006/06/02/647.aspx
In Powershell it's a one-liner:
([adsi]"IIS://localhost/MimeMap").MimeMap
The code in the link posted by Richard:
// Maintain a sorted list to contain the MIME Types
SortedList sl = new SortedList();
Console.WriteLine("IIS Mime Map - c#");
Console.WriteLine();
// Serve to connect to...
string ServerName = "LocalHost";
// Define the path to the metabase
string MetabasePath = "IIS://" + ServerName + "/MimeMap";
// Note: This could also be something like
// string MetabasePath = "IIS://" + ServerName + "/w3svc/1/root";
try
{
// Talk to the IIS Metabase to read the MimeMap Metabase key
DirectoryEntry MimeMap = new DirectoryEntry(MetabasePath);
// Get the Mime Types as a collection
PropertyValueCollection pvc = MimeMap.Properties["MimeMap"];
// Add each Mime Type so we can display it sorted later
foreach (object Value in pvc)
{
// Convert to an IISOle.MimeMap - Requires a connection to IISOle
// IISOle can be added to the references section in VS.NET by selecting
// Add Reference, selecting the COM Tab, and then finding the
// Active DS Namespace provider
IISOle.MimeMap mimetypeObj = (IISOle.MimeMap)Value;
// Add the mime extension and type to our sorted list.
sl.Add(mimetypeObj.Extension, mimetypeObj.MimeType);
}
// Render the sorted MIME entries
if (sl.Count == 0)
Console.WriteLine("No MimeMap entries are defined at {0}!", MetabasePath);
else
foreach (string Key in sl.Keys)
Console.WriteLine("{0} : {1}", Key.PadRight(20), sl[Key]);
}
catch (Exception ex)
{
if ("HRESULT 0x80005006" == ex.Message)
Console.WriteLine(" Property MimeMap does not exist at {0}", MetabasePath);
else
Console.WriteLine("An exception has occurred: \n{0}", ex.Message);
}
// Convert to an IISOle.MimeMap - Requires a connection to IISOle
// IISOle can be added to the references section in VS.NET by selecting
// Add Reference, selecting the COM Tab, and then finding the
// Active DS Namespace provider
According to my googling: (lost the links, sorry)
The "Active DS IIS Namespace Provider" is part of the IIS installation.
After you install IIS you will see that in the list of options.
If you don't see it should be located at C:\windows\system32\inetsrv\adsiss.dll.
To install IIS:
click Start, Settings, Control Panel, Add or Remove Programs, Add or Remove Windows Components, select Internet Informatoin Services (IIS).
Most of the code I've seen uses some combination of these:
using System.IO;
using System.DirectoryServices; // Right-click on References, and add it from .NET
using System.Reflection;
using System.Runtime.InteropServices;
using System.Collections;
using IISOle;
using System.Collections.Specialized;
The Active DS Namespace might be under the COM tab when adding the reference.
I've written a small class based on the webmaster-toolkit.com list. This is to avoid using COM and the IIS route or any IIS references.
It uses an XML serialized list which contains about 400 mimetypes, so is usually more than enough unless you have really obscure mimetypes. In that case you can just add to the XML file.
The full solution can be found here. Here's a sample:
class Program
{
static void Main(string[] args)
{
var list = MimeType.Load();
MimeType mimetype = list.FirstOrDefault(m => m.Extension == "jpg");
}
}

Resources