Sortowanie Favorites (Ulubionych) w Edge

Jak wiadomo w Edge posortować Ulubionych (dalej zwanymi dla uproszczenia Favorites) się nie da. Taka cecha…

Nie przeszkadzało mi to, bo przed importem z IE były posortowane, a zmian w Edge wiele nie było.

Ale przyszła chwila instalacji Windows Phone 10 na smartfonie… Po instalacji urządzenia się zsynchronizowały – no i zrobił się problem:

  • jeżeli miałem w Favorites folder A z zawartością 5 linków,
  • to teraz miałem dwa foldery A, odległe od siebie, jeden zawierający 2 linki, a drugi 3.

Rozmnożyło się tak większość folderów, i korzystanie z Favorites stało się mordęgą.

 

Więc trzeba było poszukać. W win10-edge-favorites-folder-location była informacja o konfiguracji.

W katalogu C:\Users\%UserName%\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\RoamingState znajdują się pliki o nazwach takich jak: {00516beb-9ef3-4a06-8a1c-a7760fcb37e8}.json

 Nazwa, jak widać to Guid, a sam plik to zserializowana klasa.

Odtworzona klasa wygląda tak:


 

[DataContract]
public class Favorite
{
 [DataMember]
 public int Collection;
 [DataMember]
 public int SchemaVersion;
 [DataMember]
 public string ItemId;
 [DataMember]
 public string ParentId;
 [DataMember]
 public Int64 OrderNumber;
 [DataMember]
 public bool IsFolder;
 [DataMember]
 public string Title;
 [DataMember]
 public string URL;
 [DataMember]
 public UInt32 DateUpdatedLow;
 [DataMember]
 public UInt32 DateUpdatedHigh;
 [DataMember]
 public string FaviconFileContent;
 //
 public string OrderNumberAsText
 {
 get
 {
 return DateTime.FromFileTime(OrderNumber).ToString("yyy.MM.dd HH:mm:ss");
 }
 }
 //
 public Int64 DateUpdated
 {
 get
 {
 UInt64 u = DateUpdatedHigh;
 u <<= 32;
 u |= DateUpdatedLow;
 //
 return (Int64)u;
 }
 set
 {
 UInt64 uH = (UInt64)value;
 UInt64 uL = uH & 0xFFFFFFFF;
 uH >>= 32;
 //
 DateUpdatedLow = (UInt32)uL;
 DateUpdatedHigh = (UInt32)uH;
 }
 }
 public string DateUpdatedAsText
 {
 get
 {
 return DateTime.FromFileTime(DateUpdated).ToString("yyy.MM.dd HH:mm:ss");
 }
 }
 //
 public override string ToString()
 {
 string s = "";
 //
 s += string.Format("Collection:{0}{1}", Collection, Environment.NewLine);
 s += string.Format("SchemaVersion:{0}{1}", SchemaVersion, Environment.NewLine);
 s += string.Format("ItemId:{0}{1}", ItemId, Environment.NewLine);
 s += string.Format("ParentId:{0}{1}", ParentId, Environment.NewLine);
 s += string.Format("OrderNumber:{0}{1}", OrderNumberAsText, Environment.NewLine);
 s += string.Format("IsFolder:{0}{1}", IsFolder, Environment.NewLine);
 s += string.Format("Title:{0}{1}", Title, Environment.NewLine);
 s += string.Format("URL:{0}{1}", URL, Environment.NewLine);
 s += string.Format("FaviconFileContent:{0}\n", FaviconFileContent);
 s += string.Format("DateUpdated:{0}{1}", DateUpdatedAsText, Environment.NewLine);
 //
 return s;
 }
}

Zostało to, na wszelki wypadek opakowane:

 public class FileFavorite
 {
 public string FName;
 public Favorite F;
 }

 

ItemId i ParentId to Guidy, jeżeli ParentId jest równy „{fddf6d73-3ca3-456b-946a-96b379ad4a44}” to element znajduje się w głównym katalogu. ItemId zawsze był taki sam, jak w nazwie pliku.

OrderNumber, wbrew pozorom, to data w formacie FileTime. Określa ona kolejność wyświetlania elementów w Edge.

DateUpdatedLow, DateUpdatedHigh to połówki daty w formacie FileTime.

I tylko te elementy klasy zmieniałem, pozostawiając resztę.


Przy okazji zrobiłem formalne sprawdzenie poprawności danych: sieroty i duble. Sierot nie było, ale okazało się że prawie połowa wpisów to duble… Co ciekawe, nie były one widoczne.

Wczytana lista Guidów nie będącym plikami i których przodkiem był root, była grupowana po Title. W tych grupach, gdzie było > 1 elementów, wszystkie elementy poza pierwszym były usuwane, a w ParentId elementów będących ich potomkami wpisywany był ParentId pierwszego.

Zadziałało, chociaż by Edge zauważył zmianę trzeba było wejść i wyjść z jakiegoś katalogu Favorites.


A tutaj przykład posortowania Favorites:

static string rootId = „{fddf6d73-3ca3-456b-946a-96b379ad4a44}”;// na innym PC był taki sam

List<FileFavorite> lf = new List<FileFavorite>();// wszystkie Fav.

long ct = DateTime.Now.ToFileTime();
//
var AllFav = (from x in lf orderby x.F.Title orderby !x.F.IsFolder where (x.F.ParentId == rootId) select x).ToList();
//
DateTime ord = DateTime.Now;
TimeSpan m1 = new TimeSpan(0, 1, 0);
ord = ord.Subtract(new TimeSpan(0, AllFav.Count() * 3, 0));
//
for (int j = 0; j < AllFav.Count(); j++)
{
 AllFav[j].F.DateUpdated = ct;
 AllFav[j].F.OrderNumber = ord.ToFileTime();
 //
 Console.WriteLine(AllFav[j].F.Title);
 WriteFavorite(dstFav, AllFav[j]);
 //
 ord = ord.Add(m1);
}
//

Funkcje użytkowe:

  • deserializacja
  • serializacja

(ciekawostką jest to, że Edge używa innego serializera, bo DataContractJsonSerializer zamienia `/’ na `\/’, a tego w danych nie było. Ale to bez znaczenia, obydwie postacie są prawidłowe.)


 

public static FileFavorite ReadFavorite(string f)
{
 Byte[] bb = File.ReadAllBytes(f);
 MemoryStream ms = new MemoryStream(bb);
 ms.Position = 0;
 Favorite fv = (Favorite)ser.ReadObject(ms);
 //
 FileFavorite ffv = new FileFavorite()
 {
 FName = Path.GetFileNameWithoutExtension(f),
 F = fv
 };
 //
 if (ffv.FName != ffv.F.ItemId)
 {
 throw new Exception("ffv.Id != ffv.F.ItemId");
 }
 return ffv;
}

 

public static void WriteFavorite(string path, FileFavorite ffv)
{
 MemoryStream ms = new MemoryStream();
 ser.WriteObject(ms, ffv.F);
 ms.Seek(0, SeekOrigin.Begin);
 byte[] bb = ms.ToArray();
 string filename = Path.Combine(path, ffv.FName + ".json");
 File.WriteAllBytes(filename, bb);
}

Aktualizacja 2017

Teraz to nie pliki są używane, tylko baza danych i dane znajdujące się w:

%LOCALAPPDATA%\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\AC\MicrosoftEdge\User\Default\DataStore\Data\nouser1\120712-0049

a konkretnie to ta baza danych:

 DBStore\spartan.edb

Do edycji bazy polecam program:

http://www.emmet-gray.com/Articles/EdgeManage.html

Ćwiczyłem to, gdy po aktualizacji zniknęła mi połowa favorities. Szczęśliwie, na innej maszynie pozostały właściwe dane

Reklamy
Ten wpis został opublikowany w kategorii c#, Komputery i Internet i oznaczony tagami , , . Dodaj zakładkę do bezpośredniego odnośnika.

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Wyloguj / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Wyloguj / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Wyloguj / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Wyloguj / Zmień )

Connecting to %s