I started with this excellent working unzip pipeline component here (by Rui Machado).

I made the following changes to that code:
1) Put it in MyCompany.Common.etc… namespace and project (not shown here)
2) Added a Property Bag Item called FileMask (and a one for future use called “ParmReserved1” (this is standard coding, so I didn’t include here).
3) Added the FitsMask function from StackOverflow
4) Added the functionality to set the %SourceFileName% (aka ReceivedFileName, based on the files inside the zip instead of the zip file dropped).

public void Disassemble(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg)
{
  IBaseMessage Temp = inmsg;
  // uses Ionic.Zip 
  using (ZipFile zip = ZipFile.Read(inmsg.BodyPart.GetOriginalDataStream()))
  {
    foreach (ZipEntry e in zip)
    {
      string strCheckFileName = System.IO.Path.GetFileName(e.FileName);

      if (FitsMask(strCheckFileName, FileMask))
      {
         var ms = new MemoryStream();
         IBaseMessage outMsg;
         outMsg = pc.GetMessageFactory().CreateMessage();
         outMsg.AddPart("Body", pc.GetMessageFactory().CreateMessagePart(), true);
         outMsg.Context = inmsg.Context;

        // Neal Walters - 05/08/2017 - added promoted field with the filename - 
        // This allows us to use the %sourcefilenam% macro in the SendPort to name the file. 
        outMsg.Context.Write("ReceivedFileName",
             "http://schemas.microsoft.com/BizTalk/2003/file-properties", 
             strCheckFileName);

        e.Extract(ms);
        string XMLMessage = Encoding.UTF8.GetString(ms.ToArray());

        MemoryStream mstemp = new System.IO.MemoryStream(
        System.Text.Encoding.UTF8.GetBytes(XMLMessage));

        outMsg.GetPart("Body").Data = mstemp;

       _msgs.Enqueue(outMsg);
      }
   }
 }
}

        private static bool FitsMask(string fileName, string fileMask)
        {
            string pattern =
                 '^' +
                 Regex.Escape(fileMask.Replace(".", "__DOT__")
                                 .Replace("*", "__STAR__")
                                 .Replace("?", "__QM__"))
                     .Replace("__DOT__", "[.]")
                     .Replace("__STAR__", ".*")
                     .Replace("__QM__", ".")
                 + '$';
            return new Regex(pattern, RegexOptions.IgnoreCase).IsMatch(fileName);
        }

The screen shot below show how the FileMask can be specified in the RecieveLocation (via use of the standard Property Bag interface):

(Sorry, don't have SnagIt yet at this client, so have to use the poor man's Snipping Tool).

Filed under: Pipelines