Eldert Grootenboer
maandag 25 juni 2012
vrijdag 8 juni 2012
BizTalk360 and DTC
vrijdag 1 juni 2012
BizTalk Powershell Provider on Windows Server 2008 R2
Today I ran into a problem while trying to use the
BizTalk PowerShell Provider on a Windows Server R2 installation.
I allready knew I would have to
use the 32 bit version when working with the provider,
however on starting up the console I received the following message:
Add-PSSnapin : Cannot load
Windows PowerShell snap-in BizTalkFactory.Powershell.Extensions
because of the following err or: Could not load file or assembly
'file:///C:\Program Files (x86)\BizTalkFactory
PowerShell Provider\BizTalkFactory.P
owerShell.Extensions.dll' or one of its dependencies. This assembly is built by
a runtime newer than the currently load ed
runtime and cannot be loaded. At
C:\Users\Administrator\Documents\WindowsPowerShell\profile.ps1:5 char:13 + Add-PSSnapin
<<<< BizTalkFactory.Powershell.Extensions
+ CategoryInfo : InvalidArgument:
(BizTalkFactory.Powershell.Extensions:String) [Add-PSSnapin], PSSnapInE xception + FullyQualifiedErrorId
: AddPSSnapInRead,Microsoft.PowerShell.Commands.AddPSSnapinCommand
In the documentation for the provider it states it
targets .NET 2.0, and that the configuration files should be changed to the
following:
<configuration>
<startup>
<supportedRuntime version="v4.0.30319" />
</startup>
</configuration>
This did however not solve my problem.
After further investigation I found out you actually need
following in the configuration file:
<configuration>
<startup
useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0.30319" />
<supportedRuntime version="v2.0.50727" />
</startup>
</configuration>
woensdag 9 mei 2012
Automated BizTalk Deployment
Introduction
Place root element in filename
/// <summary> /// IComponent.Execute method is used to initiate the processing of the message in /// this pipeline component. /// </summary> /// <param name="pc">Pipeline context.</param> /// <param name="inmsg">Input message.</param> /// <returns>Original input message.</returns> public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(IPipelineContext pc, IBaseMessage pInMsg) { // Create a new XML document XmlDocument xmlDocument = new XmlDocument(); // Get the XML data from the message xmlDocument.Load(pInMsg.BodyPart.Data); // Set the filename, starting with the root element, and adding a GUID to make // sure the filename is unique string filename = String.Format("{0}-{1}.xml", xmlDocument.DocumentElement.LocalName, Guid.NewGuid()).ToUpperInvariant(); // To be able to use the filename in the BizTalk file adapter properties, we // promote ReceivedFileName // This gives us the %SourceFileName% parameter we can use as the filename for // the file adapter pInMsg.Context.Promote("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties", navisionFilename); // Go back to the start of the message pInMsg.BodyPart.Data.Position = 0; // Continue processing the message return pInMsg; }
Add Namespaces
using System; using System.ComponentModel; using System.IO; using System.Reflection; using System.Xml; using Microsoft.BizTalk.Component.Interop; using Microsoft.BizTalk.Message.Interop; namespace Company.BizTalk.PipelineComponents { /// <summary> /// Custom component for adding a default namespace to a document. /// It is possible to define a namespace for an explicit root element by defining /// the root element and the namespace like this: /// RootElement1 = Navision_SOC /// Namespace1 = http://www.business.com/BizTalk/Common/v100 /// Adds namespace http://www.business.com/BizTalk/Common/v100 to an XmL document /// with rootelement Navision_SOC. /// RootElement1 and RootElement2 in combination with Namespace1 and Namespace2 /// work simular. /// It is also possible to define a default namespace. /// If a rootelement isn't defined to by one of the above rootelements, then the /// default namespace is used. /// </summary> [ComponentCategory(CategoryTypes.CATID_PipelineComponent)] [System.Runtime.InteropServices.Guid("6BC4F961-EF65-4190-BC6D-F57AA063D938")] [ComponentCategory(CategoryTypes.CATID_Decoder)] public class NamespaceAdderComponent : Microsoft.BizTalk.Component.Interop.IComponent, IBaseComponent, IPersistPropertyBag, IComponentUI { #region Properties /// <summary> /// First root element to look for. /// </summary> private string _RootElement1; /// <summary> /// First root element to look for. /// </summary> public string RootElement1 { get { return _RootElement1; } set { _RootElement1 = value; } } /// <summary> /// Namespace to be used for the first defined root element. /// </summary> private string _Namespace1; /// <summary> /// Namespace to be used for the first defined root element. /// </summary> public string Namespace1 { get { return _Namespace1; } set { _Namespace1 = value; } } /// <summary> /// Second root element to look for. /// </summary> private string _RootElement2; /// <summary> /// Second root element to look for. /// </summary> public string RootElement2 { get { return _RootElement2; } set { _RootElement2 = value; } } /// <summary> /// Namespace to be used for the second defined root element. /// </summary> private string _Namespace2; /// <summary> /// Namespace to be used for the second defined root element. /// </summary> public string Namespace2 { get { return _Namespace2; } set { _Namespace2 = value; } } /// <summary> /// Namespace to be used if root element does not match any of the previous /// root elements. /// </summary> private string _DefaultNamespace; /// <summary> /// Namespace to be used if root element does not match any of the previous /// root elements. /// </summary> public string DefaultNamespace { get { return _DefaultNamespace; } set { _DefaultNamespace = value; } } #endregion #region IBaseComponent members /// <summary> /// Name of the component /// </summary> [Browsable(false)] public string Name { get { return "NamespaceAdderComponent"; } } /// <summary> /// Version of the component /// </summary> [Browsable(false)] public string Version { get { return "1.0.0.0"; } } /// <summary> /// Description of the component /// </summary> [Browsable(false)] public string Description { get { return "Adds a namespace to the root element, using the root element" + "to decide what namespace to add"; } } #endregion #region IPersistPropertyBag members /// <summary> /// Gets class ID of component for usage from unmanaged code. /// </summary> /// <param name="classid">Class ID of the component.</param> public void GetClassID(out System.Guid classid) { classid = new System.Guid("6BC4F961-EF65-4190-BC6D-F57AA063D938"); } /// <summary> /// Not implemented. /// </summary> public void InitNew() { } /// <summary> /// Loads configuration properties for the component. /// </summary> /// <param name="pb">Configuration property bag.</param> /// <param name="errlog">Error status.</param> public virtual void Load(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, int errlog) { object val = null; // Read the first root element from the property bag val = this.ReadPropertyBag(pb, "RootElement1"); if (val != null) { this._RootElement1 = ((string)(val)); } // Read the first namespace from the property bag val = this.ReadPropertyBag(pb, "Namespace1"); if (val != null) { this._Namespace1 = ((string)(val)); } // Read the second root element from the property bag val = this.ReadPropertyBag(pb, "RootElement2"); if (val != null) { this._RootElement2 = ((string)(val)); } // Read the second namespace from the property bag val = this.ReadPropertyBag(pb, "Namespace2"); if (val != null) { this._Namespace2 = ((string)(val)); } // Read the default root element from the property bag val = this.ReadPropertyBag(pb, "DefaultNamespace"); if (val != null) { this.DefaultNamespace = ((string)(val)); } } /// <summary> /// Saves the current component configuration into the property bag. /// </summary> /// <param name="pb">Configuration property bag.</param> /// <param name="fClearDirty">Not used.</param> /// <param name="fSaveAllProperties">Not used.</param> public virtual void Save(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, bool fClearDirty, bool fSaveAllProperties) { // Save the first root element this.WritePropertyBag(pb, "RootElement1", this.RootElement1); // Save the first namespace this.WritePropertyBag(pb, "Namespace1", this.Namespace1); // Save the second root element this.WritePropertyBag(pb, "RootElement2", this.RootElement2); // Save the second namespace this.WritePropertyBag(pb, "Namespace2", this.Namespace2); // Save the default root element this.WritePropertyBag(pb, "DefaultNamespace", this.Namespace2); } #region utility functionality /// <summary> /// Reads property value from property bag. /// </summary> /// <param name="pb">Property bag.</param> /// <param name="propName">Name of property.</param> /// <returns>Value of the property.</returns> private object ReadPropertyBag( Microsoft.BizTalk.Component.Interop.IPropertyBag pb, string propName) { object val = null; try { pb.Read(propName, out val, 0); } catch (System.ArgumentException) { return val; } catch (System.Exception e) { throw new System.ApplicationException(e.Message); } return val; } /// <summary> /// Writes property values into a property bag. /// </summary> /// <param name="pb">Property bag.</param> /// <param name="propName">Name of property.</param> /// <param name="val">Value of property.</param> private void WritePropertyBag( Microsoft.BizTalk.Component.Interop.IPropertyBag pb, string propName, object val) { try { pb.Write(propName, ref val); } catch (System.Exception e) { throw new System.ApplicationException(e.Message); } } #endregion #endregion #region IComponentUI members /// <summary> /// Component icon to use in BizTalk Editor. /// </summary> [Browsable(false)] public IntPtr Icon { get { return IntPtr.Zero; } } /// <summary> /// The Validate method is called by the BizTalk Editor during the build /// of a BizTalk project. /// </summary> /// <param name="obj">An Object containing the configuration properties. /// </param> /// <returns>The IEnumerator enables the caller to enumerate through a /// collection of strings containing error messages. These error messages /// appear as compiler error messages. To report successful property /// validation, the method should return an empty enumerator.</returns> public System.Collections.IEnumerator Validate(object obj) { return null; } #endregion #region IComponent members /// <summary> /// IComponent.Execute method is used to initiate /// the processing of the message in this pipeline component. /// </summary> /// <param name="pc">Pipeline context.</param> /// <param name="inmsg">Input message.</param> /// <returns>Original input message.</returns> public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute( Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg) { // Create the message that will be sent out when processing is done IBaseMessage pOutMessage = null; // Create an empty XML document XmlDocument xmlDocument = new XmlDocument(); // Boolean indicating if the namespace has been set bool isNamespaceSet = false; try { // Get the data of the XML message xmlDocument.Load(inmsg.BodyPart.Data); } catch (Exception e) { throw new Exception("Error converting message to xml", e); } // Check if we specified the first root element // If we did, check if it is this document's root element if (!string.IsNullOrEmpty(_RootElement1) && xmlDocument.DocumentElement.Name == _RootElement1 ) { // Set the namespace for this message pOutMessage = SetNamespace(inmsg, xmlDocument, _Namespace1); // The namespace has been set isNamespaceSet = true; } // Check if the namespace was allready set earlier // If not, check if we specified a second root element // If we did, check if it is this document's root element if (!isNamespaceSet && !string.IsNullOrEmpty(_RootElement2) && xmlDocument.DocumentElement.Name == _RootElement2) { // Set the namespace for this message pOutMessage = SetNamespace(inmsg, xmlDocument, _Namespace2); // The namespace has been set isNamespaceSet = true; } // Check if the namespace was allready set earlier if (!isNamespaceSet) { // Set the namespace for this message pOutMessage = SetNamespace(inmsg,_DefaultNamespace, xmlDocument); } // Check if setting the namespace went ok if (pOutMessage == null) { // If not, set the output message to be the same as the input message pOutMessage = inmsg; } // Go to the start of the output message pOutMessage.BodyPart.Data.Position = 0; // Return the message for further processing in the pipeline return pOutMessage; } /// <summary> /// Set the namespace of a XML message. /// </summary> /// <param name="pInMessage">The message in which we want to set the /// namespace.</param> /// <param name="defaultNamespace">The namespace we want to set.</param> /// <param name="XmlDocument">The data of the xml message.</param> /// <returns>Original input message.</returns> private IBaseMessage SetNamespace(IBaseMessage pInMessage, string defaultNamespace,XmlDocument xmlDocument) { // Check if a namespace was provided if (!string.IsNullOrEmpty(defaultNamespace)) { // Used to set the namespace string systemPropertiesNamespace = "http://schemas.microsoft.com/BizTalk/2003/system-properties"; // Promotion of the messagetype string messageType = defaultNamespace + "#" + xmlDocument.DocumentElement.Name; pInMessage.Context.Promote("MessageType", systemPropertiesNamespace, messageType); // Used to set the xmlns namespace string xmlnsNS = "http://www.w3.org/2000/xmlns/"; // Add the namespace to the xml document XmlAttribute attributeNode = xmlDocument.CreateAttribute("xmlns", xmlnsNS); attributeNode.Value = defaultNamespace; xmlDocument.DocumentElement.SetAttributeNode(attributeNode); // We will write the new XML into the message pInMessage.BodyPart.Data = new MemoryStream(); // Save the XML into the message xmlDocument.Save(pInMessage.BodyPart.Data); // Go to the start of the message pInMessage.BodyPart.Data.Position = 0; } // Return the message return pInMessage; } #endregion } } |