Last week I blogged about a problem I came across when beta testing a new WP7 application. My problem was related to the ID_CAP_MEDIALIB capability. Today I noticed somebody on twitter having similar issues.
Fortunately there is a way to force detection of every capability. The key is knowing what reference to use to force the detection. In this post I will show how to implement a simple workaround to ensure detection. Please note that all of this is just temporary. Microsoft’s engineering teams are working on fixing these detection issues, so these tricks should not be required anymore in the future.
Detection process
First of all it is important to realize that the Ingestion Tool does not scan the actual C# and XAML (that’s not included in the XAP package anyway). The actual scanning happens on the Intermediate Language (IL) that is generated by the compiler. This is important to keep in mind when implementing this workaround.
Detection rules
Essentially both the Marketplace Test Kit and the App Hub itself use the same set of rules to determine what capabilities are required. Fortunately those rules are supplied with the Test Kit in understandable XML format. To find out what class you need to reference to force detection it is sufficient to check this list of rules. The rules.xml can be found in “C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v7.1\Tools\Marketplace” For example here’s the part on the ID_CAP_MICROPHONE capability.
<Capability ID=”ID_CAP_MICROPHONE” Type=”Security”>
<Assembly Name=”Microsoft.Xna.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553″>
<Namespace Name=”Microsoft.Xna.Framework.Audio”>
<Class Name=”Microphone” />
</Namespace>
</Assembly>
<Assembly Name=”Microsoft.Phone.Media.Extended, Version=7.0.0.0, Culture=neutral, PublicKeyToken=24eec0d8c86cda1e”>
<Namespace Name=”Microsoft.Phone”>
<Class Name=”Camera” />
<Class Name=”PhotoCamera” />
<Class Name=”VideoCamera” />
</Namespace>
</Assembly>
</Capability>
Forcing detection
The rules.xml file basically tells you what classes to reference to force the detection (I highlighted them). In any case you can just add a dummy file (either xaml or just cs) and make a reference to just one of these classes. In case of the Microphone
@lancewmccarthy suggests this line:
Microphone microphone = Microphone.Default;
This is a Microphone-specific solution. Another option is to just add this line:
Microsoft.Xna.Framework.Audio.Microphone temp = null;
This is where you need to remember the code gets compiled before scanning. The compiler implements a lot of optimization which in this case would lead to discarding a variable that is never accessed. Adding another line that references the variable solves this. This can be pretty much anything, for example:
MessageBox.Show(temp.ToString());
If you would actually run this code it will always throw a NullReferenceException, but since this is a dummy file that will never happen. Although the code is unreachable the ingestion tool notices it. You can use the Marketplace Test Kit to verify this.
Conclusion
By combining the information in the rules.xml with a simple dummy file you should be able to force detection of any capability. The other way around rules.xml can also help you identify why a certain capability gets detected. Do you come across any problems when using this method? Feel free to leave a comment or send me a
tweet.