Windows 10, Share Target, ShareOperation.ReportStarted and 0x80070491 (‘There was no match for the specified key in the index’)

Hi, just a short post but something that I spent a good few hours banging my head against and which I thought I’d share.

If I make a brand new, blank Windows 10 UWP application on Windows 10 build 10240 and I make it a target for sharing by editing its manifest;

image

and then I override App.OnShareTargetActivated and do this;

 protected override void OnShareTargetActivated(ShareTargetActivatedEventArgs args)
    {
      Debug.WriteLine("Share target activated");

      Window.Current.Content = new Rectangle()
      {
        Fill = new SolidColorBrush(Colors.Red),
        HorizontalAlignment = HorizontalAlignment.Stretch,
        VerticalAlignment = VerticalAlignment.Stretch
      };
      Window.Current.Activate();

      try
      {
        args.ShareOperation.ReportStarted();
        Debug.WriteLine("Reported starting status correctly");
      }
      catch
      {
        Debug.WriteLine("Failed to report started status");
      }
    }

then I find that the call to ShareOperation.ReportStarted will throw a System.Exception with a message saying ‘There was no match for the specified key in the index’ and with an HRESULT of 0x80070491.

Now…I think the guidance around using the ShareOperation here is that you get your work off the thread that calls your override and do it on another thread and that certainly seems to be what the official sample does.

In my case, I hit this exception while doing some more work on my kwiQR application and that had already implemented the Share Target for Windows 8.0/8.1.

At the time that I’d written that code (3+ years ago) I’d added this comment into it;

// Bug: Moving this work from the ASTA thread that the hosted share activation

// gives us because to not do that means that ASTA thread will call back to

// the ASTA thread that's calling us and will deadlock.

and I’d moved most of the sharing work across to a separate thread.

However…I still had calls like ShareOperation.ReportStarted executing on whatever thread executed my OnShareTargetActivated override and I think that code worked for me (rightly or wrongly) on Windows 8.x whereas on Windows 10 it seems to cause an exception to be thrown.

At the time of writing, I’m not 100% sure what the right thing to do is here. I experiment and found that, firstly;

    protected override void OnShareTargetActivated(ShareTargetActivatedEventArgs args)
    {
      Debug.WriteLine("Share target activated");

      Window.Current.Content = new Rectangle()
      {
        Fill = new SolidColorBrush(Colors.Red),
        HorizontalAlignment = HorizontalAlignment.Stretch,
        VerticalAlignment = VerticalAlignment.Stretch
      };

      Task.Factory.StartNew(() =>
      {
        try
        {
          args.ShareOperation.ReportStarted();
          Debug.WriteLine("Reported starting status correctly");
        }
        catch
        {
          Debug.WriteLine("Failed to report started status");
        }
      });

      Window.Current.Activate();
    }

still causes the same problem. However, I found that this;

    protected override void OnShareTargetActivated(ShareTargetActivatedEventArgs args)
    {
      Debug.WriteLine("Share target activated");

      Window.Current.Content = new Rectangle()
      {
        Fill = new SolidColorBrush(Colors.Red),
        HorizontalAlignment = HorizontalAlignment.Stretch,
        VerticalAlignment = VerticalAlignment.Stretch
      };

      Task.Factory.StartNew(async () =>
      {
        try
        {
          await Task.Delay(100);
          args.ShareOperation.ReportStarted();
          Debug.WriteLine("Reported starting status correctly");
        }
        catch
        {
          Debug.WriteLine("Failed to report started status");
        }
      });

      Window.Current.Activate();
    }

works fine – adding a simple 10ms delay before the call to ShareOperation.ReportStarted made a difference but I’m not a big fan of ‘random delays’ and so I wondered ‘what happens in that 10ms that makes a difference?’ and I wondered whether the Window being activated made a difference or not – i.e.

    protected override void OnShareTargetActivated(ShareTargetActivatedEventArgs args)
    {
      Debug.WriteLine("Share target activated");

      Window.Current.Content = new Rectangle()
      {
        Fill = new SolidColorBrush(Colors.Red),
        HorizontalAlignment = HorizontalAlignment.Stretch,
        VerticalAlignment = VerticalAlignment.Stretch
      };
      Window.Current.Activated += (s, e) =>
      {
        try
        {
          args.ShareOperation.ReportStarted();
          Debug.WriteLine("Reported starting status correctly");
        }
        catch
        {
          Debug.WriteLine("Failed to report started status");
        }
      };
      Window.Current.Activate();
    }

but, no, that still fails and so I wondered whether the Window being visible might make a difference;

   protected override void OnShareTargetActivated(ShareTargetActivatedEventArgs args)
    {
      Debug.WriteLine("Share target activated");

      Window.Current.Content = new Rectangle()
      {
        Fill = new SolidColorBrush(Colors.Red),
        HorizontalAlignment = HorizontalAlignment.Stretch,
        VerticalAlignment = VerticalAlignment.Stretch
      };
      Window.Current.VisibilityChanged += (s, e) =>
      {
        if (e.Visible)
        {
          try
          {
            args.ShareOperation.ReportStarted();
            Debug.WriteLine("Reported starting status correctly");
          }
          catch
          {
            Debug.WriteLine("Failed to report started status");
          }
        }
      };
      Window.Current.Activate();
    }

but, no, that seemed to fail for me as well and so I wondered about starting a new task from within that context…

   protected override void OnShareTargetActivated(ShareTargetActivatedEventArgs args)
    {
      Debug.WriteLine("Share target activated");

      Window.Current.Content = new Rectangle()
      {
        Fill = new SolidColorBrush(Colors.Red),
        HorizontalAlignment = HorizontalAlignment.Stretch,
        VerticalAlignment = VerticalAlignment.Stretch
      };
      Window.Current.VisibilityChanged += (s, e) =>
      {
        if (e.Visible)
        {
          Task.Factory.StartNew(() =>
          {
            try
            {
              args.ShareOperation.ReportStarted();
              Debug.WriteLine("Reported starting status correctly");
            }
            catch
            {
              Debug.WriteLine("Failed to report started status");
            }
          });
        }
      };
      Window.Current.Activate();
    }

and, bizarrely, that seemed to work reliably.

Now…at the time of writing I’m still very unsure what I’m doing wrong here in terms of the timing of the call to ShareOperation.ReportStarted().

Feel very free to tell me and I’ll update the post but I thought I’d publish it in this state in case it turns up in a web search for someone hitting a similar problem and at least it seems to offer one or two possible paths towards getting things working if you happen to hit this exception.