SAZClipboard

The goal of this *incomplete* example is to show how you can build an extension which accepts drag/drop of Fiddler Sessions.

SAZClipboardFactory.cs

// The SAZClipboardFactory extension creates SAZClipboardForms. These allow the user to manage collections of
// session items. This is useful, for instance, when testing webservices by replaying traffic using the Composer.
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Fiddler;
 
namespace SAZClipboard
{
    public class SAZClipboardFactory : IFiddlerExtension
    {
        List<SAZClipboardForm> oSAZClipboards = new List<SAZClipboardForm>();
        public void OnLoad()
        {
            MenuItem oMI = new MenuItem("New Session Clip&board...");
            oMI.Click += new EventHandler(oMI_Click);
            FiddlerApplication.UI.mnuTools.MenuItems.Add(oMI);
        }
 
        void oMI_Click(object sender, EventArgs e)
        {
            SAZClipboardForm oNew = new SAZClipboardForm();
            oNew.Left = FiddlerApplication.UI.Left + 50;
            oNew.Top = FiddlerApplication.UI.Top + 50;
            oSAZClipboards.Add(oNew);
            oNew.Show();
        }
 
        public void OnBeforeUnload()
        {
            foreach (SAZClipboardForm oEach in oSAZClipboards){
                oEach.Close();
            }
            oSAZClipboards = null;
        }
    }
}

SAZClipboardForm.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Fiddler;
using System.Diagnostics;
using System.IO;
 
namespace SAZClipboard
{
    public partial class SAZClipboardForm : Form
    {
        public SAZClipboardForm()
        {
            InitializeComponent();
        }
 
        /// <summary>
        /// Allow drag drop of sessions or SAZ files
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lvSessionClip_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = (e.Data.GetDataPresent("Fiddler.Session[]") || e.Data.GetDataPresent(DataFormats.FileDrop)) ? 
                DragDropEffects.Copy : e.Effect = DragDropEffects.None;
        }
 
        private void lvSessionClip_DragDrop(object sender, DragEventArgs e)
        {
            Session[] oSessions = (Session[])e.Data.GetData("Fiddler.Session[]");
            if ((oSessions == null) || (oSessions.Length < 1)) { Debug.Assert(false, "Unexpected drop type."); return; }
            AddSessionsToUI(oSessions);
        }
 
        /// <summary>
        /// Adds one or more Sessions to the SAZClipboard UI
        /// </summary>
        /// <param name="oSessions"></param>
        private void AddSessionsToUI(Session[] oSessions)
        {
            foreach (Session oSession in oSessions)
            {
                ListViewItem oLVI = new ListViewItem(new[] {
                                                            oSession.RequestMethod,
                                                            oSession.oRequest.headers.UriScheme,
                                                            oSession.host,
                                                            oSession.oRequest.headers.RequestPath,
                                                            oSession.GetRequestBodyAsString(),
                                                            oSession.oFlags["ui-comments"]});
                oLVI.Tag = oSession;
                lvSessionClip.Items.Add(oLVI);
            }
        }
 
        private void lvSessionClip_ItemDrag(object sender, ItemDragEventArgs e)
        {
            Session[] toDrag = GetSelectedSessions();
            if (toDrag.Length > 0)
            {
                lvSessionClip.DoDragDrop(toDrag, DragDropEffects.Copy);
            }
        }
 
        private void lvSessionClip_DoubleClick(object sender, EventArgs e)
        {
            Session[] arrSess = GetSelectedSessions();
            if (arrSess.Length > 0)
            {
                arrSess[0].actInspectInNewWindow();
            }
        }
 
        private void lvSessionClip_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.X:
                    if (e.Control)
                    {
                        lvSessionClip.Items.Clear();
                        this.Text = "Session Clipboard";
                        e.Handled = e.SuppressKeyPress = true;
                    }
                    return;
 
                case Keys.C:
                    {
                        Session[] arrSess = GetSelectedSessions();
                        if (arrSess.Length > 0)
                        {
                            FiddlerApplication.DoComposeByCloning(arrSess[0]);
                            e.Handled = e.SuppressKeyPress = true;
                        }
                        return;
                    }
 
                case Keys.R:
                    FiddlerApplication.UI.actReissueSessions(GetSelectedSessions(), false);
                    e.Handled = e.SuppressKeyPress = true;
                    return;
 
                case Keys.Enter:
                    {
                        Session[] arrSess = GetSelectedSessions();
                        if (arrSess.Length > 0)
                        {
                            arrSess[0].actInspectInNewWindow();
                        }
                        e.Handled = e.SuppressKeyPress = true;
                        return;
                    }
 
                case Keys.Delete:
                    if (lvSessionClip.SelectedItems.Count < 1) return;
                    ListView.SelectedListViewItemCollection lvisToRemove = lvSessionClip.SelectedItems;
 
                    lvSessionClip.BeginUpdate();
                    foreach (ListViewItem lviToRemove in lvisToRemove)
                    {
                        lviToRemove.Remove();
                    }
                    lvSessionClip.EndUpdate();
 
                    if (lvSessionClip.FocusedItem != null)
                    {
                        lvSessionClip.FocusedItem.Selected = true;
                    }
                    e.Handled = e.SuppressKeyPress = true;
                    return;
            }
        }
 
        [CodeDescription("Returns a Session[] array containing all sessions. Note: returns an empty non-null array if no sessions selected")]
        public Session[] GetAllSessions()
        {
            Session[] oResults = new Session[lvSessionClip.Items.Count];
            for (int x = 0; x < oResults.Length; x++)
            {
                oResults[x] = lvSessionClip.Items[x].Tag as Session;        // Should never be null, but...
            }
            return oResults;
        }
 
        public Session[] GetSelectedSessions()
        {
            ListView.SelectedListViewItemCollection lvSI = lvSessionClip.SelectedItems;
            Session[] oResults = new Session[lvSI.Count];
            int x = 0;
 
            // Using Foreach here makes this loop 200x faster than using indexes due to how the Framework works internally.
            foreach (ListViewItem oLVI in lvSI)
            {
                oResults[x] = oLVI.Tag as Session;
                x++;
            }
 
            return oResults;
        }
 
        private void tsbSaveSAZ_Click(object sender, EventArgs e)
        {
            if (lvSessionClip.Items.Count < 1)
            {
                MessageBox.Show("The Clipboard is empty. There is nothing to save.", "Nothing to do...");
                return;
            }
 
            try
            {
                this.UseWaitCursor = true;
                Application.DoEvents();
                FiddlerApplication.UI.actSaveSessionArchive(this, GetAllSessions(), null);
            }
            finally
            {
                this.UseWaitCursor = false;
            }
        }
 
        private void tsbLoadSAZ_Click(object sender, EventArgs e)
        {
            if (dlgOpenSAZ.ShowDialog(this) == DialogResult.OK)
            {
                try
                {
                    this.UseWaitCursor = true;
                    Application.DoEvents();
 
                    Session[] oSessions = Utilities.ReadSessionArchive(dlgOpenSAZ.FileName, true);
                    if (null == oSessions) return;
 
                    // Update form caption with name of loaded file
                    this.Text = String.Format("{0} [{1}]", this.Text, Path.GetFileNameWithoutExtension(dlgOpenSAZ.FileName));
 
                    AddSessionsToUI(oSessions);
                }
                finally
                {
                    this.UseWaitCursor = false;
                }
            }
        }
 
        private void tsbPin_CheckedChanged(object sender, EventArgs e)
        {
            this.TopMost = tsbPin.Checked;
        }
 
    }
}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License