Export Edge Favorites

Note: This utility has been "deprecated", please look at Manage Edge Favorites

The new Edge browser was released with Windows 10 in July of 2015. It had a rudimentary import feature for transferring favorites from Internet Explorer. However, it did not have any export capability at all. Instead, you'd just have to dig through a byzantine directory structure and copy the folder contents.

However, all that changed with the "November update" to Windows 10. The Windows 10 version 1511 changed how Edge stores favorites. They no longer are stored in a folder structure... and are now stored in an Extensible Storage Engine (ESE) database. So, that means you can no longer just copy the folder contents in order to export your favorites.

The location of this database file is buried 15 folders deep... it's at:
C:\User\YourName\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\AC\
MicrosoftEdge\User\Default\DataStore\Data\nouser1\120712-0049\DBStore\spartan.edb

The demonstration project below can be used to extract favorites from the ESE database and export them to a standards-based "bookmark.htm" file. You can then use this export file to import your Edge favorites to other browsers (IE, Chrome, etc). Note: This demonstration project does not have any import capability

ESE Database

There is an entire article on how to read from an ESE database that can be found here: Extensible Storage Engine

The Example Code

We use the ESE database "library" for all of the heavy lifting, so I won't repeat that here. This section of code extracts and converts the raw favorites data from the ESE database.

Try
    ' pull the Favorites table from the ESE database
    dt = ese.GetTable(path, My.Settings.FavTable, True)

    ' do a LINQ query to convert/eliminate columns
    Dim query =
       From entry In dt.AsEnumerable()
       Where entry.Field(Of Boolean)("IsDeleted") = False
       Select New Favorite With
          {
             .isFolder = entry.Field(Of Boolean)("IsFolder"),
             .ItemID = New Guid(entry.Field(Of Byte())("Itemid")).ToString("B"),
             .ParentID = New Guid(entry.Field(Of Byte())("Parentid")).ToString("B"),
             .DateUpdated = Date.FromFileTime(entry.Field(Of Long)("DateUpdated")).ToLocalTime,
             .Title = entry.Field(Of String)("Title"),
             .URL = entry.Field(Of String)("URL")
          }

    ' do another run just to find the root element.  I'm assuming that all
    ' favorites have a "_Favorites_Bar_" item?
    Dim FindRoot =
        From entry In dt.AsEnumerable()
        Where entry.Field(Of String)("Title") = My.Settings.FavBar
        Select New Favorite With
            {
                .isFolder = entry.Field(Of Boolean)("IsFolder"),
                .ItemID = New Guid(entry.Field(Of Byte())("Itemid")).ToString("B"),
                .ParentID = New Guid(entry.Field(Of Byte())("Parentid")).ToString("B"),
                .DateUpdated = Date.FromFileTime(entry.Field(Of Long)("DateUpdated")).ToLocalTime,
                .Title = entry.Field(Of String)("Title"),
                .URL = entry.Field(Of String)("URL")
            }
    Dim root As Favorite = FindRoot.First

    ' Open the file
    sw = New StreamWriter(tbOutput.Text)

    ' start the file (I cringe at the formating... or lack thereof)
    sw.WriteLine("<!DOCTYPE NETSCAPE-Bookmark-file-1>")
    sw.WriteLine("<!-- This is an automatically generated file.")
    sw.WriteLine("It will be read and overwritten.")
    sw.WriteLine("Do Not Edit! -->")
    sw.WriteLine("<TITLE>Bookmarks</TITLE>")
    sw.WriteLine("<H1>Bookmarks</H1>")
    sw.WriteLine("<DL><p>")

    ' Here we go!
    Traverse(query, root)

    ' close out the file
    sw.WriteLine("</DL><p>")
    sw.Close()
    MessageBox.Show("Done!", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information)
Catch ex As Exception
    MsgBox(ex.Message)
End Try

This routine is used like a directory traversal example. It will detect if the entry is a folder or a favorite. If a folder, it recursively calls itself to build the entire nested folder structure in the export file

' Descend the folder structure
Private Sub Traverse(favorites As EnumerableRowCollection(Of Favorite), id As String)
   For Each fav In favorites
      If fav.ParentID = id Then
         If fav.isFolder Then
            ' create a folder
            sw.WriteLine("<DT><H3 FOLDED>" & fav.Title & "</H3></DT>")
            sw.WriteLine("<DL><p>")

            ' recursively call this routine
            Traverse(favorites, fav.ItemID)
            sw.WriteLine("</DL><p>")
         Else
            ' create the items
            sw.WriteLine("<DT><A HREF="" " & fav.URL & "" " LAST_MODIFIED="" " & DateToEpoch(fav.DateUpdated) & "" ">" & fav.Title & "</A>" )
         End If
      End If
   Next
End Sub

Release Notes

Version 1.2 - 14 Feb 2016

Version 1.1 - 27 Jan 2016

Public Domain

This application and its source code are placed in the "public domain". That means it completely free, with no restrictions on its use. There is no license, so you can do anything you want with it, to include making money from it. You are also free to tinker with it, modify it, add new features, etc.

Other Related Projects

Take a look at these related projects:

Downloads/Links

Download the windows installer file: SetupEdgeExport.exe
Download the VB.Net Source code example used in this article: EdgeExportSrc.zip