[NEW] Media Center Addin x64: Microsoft.MediaCenter.GuideSubscribed
-
Wednesday, March 10, 2010 12:14 PMSorry, have to post this thread again, because the original thread isn't accessibly anymore.
Hi,
I'm working on a Media Center Addin with the following references:
Microsoft.MediaCenter.Store (mcstore.dll)
Microsoft.MediaCenter.Guide (mcepg.dll)
I can access the ObjectStore (mcepg2-0.db),the Lineup and ScheduleEntry with:
But this is working on x86 Windows only. If I run the project on an x64 machine ScheduleEntries are always return a NullRefrenceException. I had build the project as x86, x64 or Any. All code is working fine then, but ScheduleEntries are always return a NullRefrenceException on x64 machine.ScheduleEntry e = channel.Service.GetScheduleEntryAt(DateTime.Now);
channel and Service are != null, that's not the reason for the NullReferenceException
Any ideas?
Exception System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
Server stack trace:
bei MCC_MC_AddIn.Application.searchTVnow(String data)
bei MCC_MC_AddIn.Application.Start()
bei MCC_MC_AddIn.MyAddIn.Launch(AddInHost host)
bei MediaCenter.Extensibility.AddInEntryPointWrapper.Launch(AddInHost host)
bei System.Runtime.Remoting.Messaging.Message.Dispatch(Object target, Boolean fExecuteInContext)
bei System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)
Exception rethrown at [0]:
bei System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
bei System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
bei MediaCenter.Extensibility.AddInEntryPointWrapper.Launch(AddInHost host)
bei System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
bei System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)
Exception rethrown at [1]:
bei System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
bei System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
bei MediaCenter.Extensibility.ExtensibilityPlugInEntryPointInfo.ExtensibilityPlugInLaunchInfo.AddInModalLauncher.AddInLaunchDelegate.EndInvoke(IAsyncResult result)
bei MediaCenter.Extensibility.ExtensibilityPlugInEntryPointInfo.ExtensibilityPlugInLaunchInfo.AddInModalLauncher.LaunchComplete(IAsyncResult result)
All Replies
-
Thursday, March 11, 2010 9:16 AMModeratorHi,
Which OS and .NET Framework version are you using? it will be helpful if you could post a small repro here.
Sincerely,
Eric
MSDN Subscriber Support in Forum
If you have any feedback of our support, please contact msdnmg@microsoft.com.
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us. -
Thursday, March 11, 2010 12:52 PM
I'm using Windows 7 x86 & x64 (fully patched/hotfixed) with .NET Framework 3.5.
And this is the code I have written:
private void searchTVbyChannel(Channel c, DateTime startTime, DateTime endTime) { if (!isTVenabled) { return; } //writeLog("searching epg: " + c.CallSign + " | " + startTime.ToString() + " | " + endTime.ToString()); //writeLog("isDaylightSavingTime: " + isDaylightSavingTime().ToString()); if (!isDaylightSavingTime()) { startTime = startTime.Subtract(new TimeSpan(1, 0, 0)); endTime = endTime.Subtract(new TimeSpan(1, 0, 0)); } lastTVquery.Clear(); lastTVqueryHash = DateTime.Now.Ticks.ToString(); string result = string.Empty; try { ScheduleEntry[] entries = c.Service.GetScheduleEntriesBetween(startTime, endTime); // <<<< NullRefrenceException here on x64 only foreach (ScheduleEntry e in entries) { if (result != string.Empty) { result = result + cmdRowDelemiter; } DateTime eStartTime = e.StartTime; DateTime eEndTime = e.EndTime; if (!isDaylightSavingTime()) { eStartTime = eStartTime.AddHours(1); eEndTime = eEndTime.AddHours(1); } TV.Entry qe = new TV.Entry(); qe.Channel = c; qe.StartDateTime = eStartTime; qe.EndDateTime = eEndTime; qe.Duration = e.Duration; qe.Program = e.Program; lastTVquery.Add(qe); } } catch (NullReferenceException ex) { } if (result != string.Empty) { sendMsg(cmdSearchTV + lastTVqueryHash + cmdRowDelemiter + result); } else { sendMsg(cmdSearchTV + lastTVqueryHash + cmdRowDelemiter + "=E="); } //ShowLongMessage("TVsearch: found " + lastTVquery.Count.ToString() + " entries."); } void getChannels() { writeLog("getChannels"); TVChannels = new List<mChannel>(); if (TVlineup != null) { Channel[] channels = TVlineup.GetChannels(); foreach (Channel channel in channels) { if (!channel.IsBlocked) //kanal vom benutzer deaktiviert = IsBlocked { StoredObject so = (StoredObject)channel; mChannel mchannel = new mChannel(); mchannel.Index = TVChannels.Count; mchannel.Channel = channel; mchannel.StoredObjectID = so.Id; mchannel.CallSign = channel.CallSign; mchannel.ChannelNumber = channel.DisplayChannelNumber; TVChannels.Add(mchannel); } } //debug foreach (mChannel c in TVChannels) { writeLog(c.Channel.CallSign + " | " + c.Channel.DisplayChannelNumber); if (c.Channel.Service == null) { writeLog("no service"); } else { writeLog("service ok"); } } writeLog("Channels: " + TVChannels.Count.ToString()); writeLog("getChannels ok"); } else { writeLog("getChannels error: noLineup"); } } void getStore() { writeLog("getStore"); string basePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), @"Microsoft\eHome\"); if (Directory.Exists(basePath)) { DirectoryInfo dir = new DirectoryInfo(basePath); try { FileInfo dbfile = dir.GetFiles("*.db").OrderByDescending(f => f.LastWriteTime).First(); if (dbfile != null) { TVstore = Microsoft.MediaCenter.Store.ObjectStore.Open(dbfile.FullName); TVstore.StoredObjectAdded += new StoredObjectEventHandler(TVstore_StoredObjectAdded); TVstore.StoredObjectUpdated += new StoredObjectEventHandler(TVstore_StoredObjectUpdated); TVstore.StoredObjectLoaded += new StoredObjectEventHandler(TVstore_StoredObjectLoaded); writeLog("store ok"); } } catch (InvalidOperationException ex) { } } } void getLineup() { writeLog("getLineup"); if (TVstore != null) { MergedLineups mls = new MergedLineups(TVstore); List<MergedLineup> m = mls.ToList(); writeLog("lineups found: " + m.Count.ToString()); if (m.Count == 1) { TVlineup = mls.First; writeLog("linup ok"); } else if (m.Count > 1) { TVlineup = mls.First; writeLog("lineup ok, but found more than one lineup"); } else { writeLog("lineup error: no lineups"); } } } -
Monday, March 15, 2010 8:28 AMModerator
H i,
You mentioned in above code snippet that the NullReference exception is thrown from line:
ScheduleEntry[] entries = c.Service.GetScheduleEntriesBetween(startTime, endTime); // <<<< NullRefrenceException here on x64 only
If c and c.Service are not null, could you step into GetScheduleEntriesBetween method to see its inner implementation?
Sincerely,
Eric
MSDN Subscriber Support in Forum
If you have any feedback of our support, please contact msdnmg@microsoft.com.
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us. -
Wednesday, March 17, 2010 12:17 PMHi eryang,
GetScheduleEntriesBetween(startTime, endTime) is in namespace Microsoft.MediaCenter.Guide in windows\ehome\mcepg.dll.
I think it is not possible to the inner implementation.? -
Thursday, March 18, 2010 7:45 AMModerator
H i,
You may see the inner implementation of GetScheduleEntriesBetween method from Reflector .
If the exception make your application crash, you can follow the article http://support.microsoft.com/default.aspx/kb/286350 to capture the dump file of the crashing application. After you get the dump, please let me know your email address by sending a mail to v-eryang@microsoft.com . Then I will create a file transfer workspace where you can upload your dump file. The dump will be kept confidential.
Sincerely,
Eric
MSDN Subscriber Support in Forum
If you have any feedback of our support, please contact msdnmg@microsoft.com.
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us. -
Monday, March 22, 2010 4:34 PM
Thank you for this great help. Using the reflector I was able to figure out what is wrong.
If I look into a Channel, i can resolve the Service and see that this Service has a valid ScheduleEndTime:
+ ScheduleEndTime {29.03.2010 00:05:00} System.DateTime
The Service is filled with hundrets of ScheduleEntries, but they are all of the same content:
- [0] {01.01.0001 00:00:00 - 01.01.0001 00:00:00 on <null> -> } Microsoft.MediaCenter.Guide.ScheduleEntry
The referencing Service of these ScheduleEntries is always null. And this is the point where the NullReferenceException occures.
This is the decompiled source of GetScheduleEntriesBetween method:
public ScheduleEntry[] GetScheduleEntriesBetween(DateTime dtStart, DateTime dtEnd) { ServiceStartTimeKey key = new ServiceStartTimeKey(this, dtStart); ScheduleEntry item = null; List<ScheduleEntry> list = new List<ScheduleEntry>(); StoredObjectsEnumerator<ScheduleEntry> storedObjectsEnumerator = new Microsoft.MediaCenter.Guide.ScheduleEntries(base.ObjectStore).GetStoredObjectsEnumerator(); using (storedObjectsEnumerator) { ServiceStartTimeKey key2 = new ServiceStartTimeKey(this); if (storedObjectsEnumerator.Seek(key, SeekType.BeforeEQ) || storedObjectsEnumerator.Seek(key2, SeekType.BeforeEQ)) { item = storedObjectsEnumerator.Current; if ((item != null) && ((item.Service == null) || (item.Service.Id != base.Id))) { if (storedObjectsEnumerator.MoveNext()) { item = storedObjectsEnumerator.Current; } else { item = null; } } if ((item != null) && (item.EndTime <= dtStart)) { if (storedObjectsEnumerator.MoveNext()) { item = storedObjectsEnumerator.Current; } else { item = null; } } while (((item != null) && (item.StartTime < dtEnd)) && (item.Service.Id == base.Id)) // NullReferenceException here (item.Service ==null)
{
list.Add(item);
if (!storedObjectsEnumerator.MoveNext())
{
goto Label_00EC;
}
item = storedObjectsEnumerator.Current;
}
}
}
Label_00EC:
return list.ToArray();
}I have double checked my code and I'm sure that I get the Linup, Channels and Services correct. And the code is working well on x86.
Any ideas?
Thanks in advance for your support.
-
Wednesday, March 24, 2010 1:55 AMModerator
Hi,
API GetScheduleEntriesBetween (and other APIs in mcepg.dll) is not supposed to be used directly by our application, those APIs are not supported. As a suggested way, you may use Media Centers supported APIs , hope it can helps.
Sincerely,
Eric
MSDN Subscriber Support in Forum
If you have any feedback of our support, please contact msdnmg@microsoft.com.
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us. -
Wednesday, March 24, 2010 12:36 PM
That's bad. You are not able to get any EPG info out of the supported API's. How someone should write a improved EPG or something for the Media Center?
-
Friday, April 09, 2010 1:13 AM
Hi,
Nice work MGelhaar.
I too would like access to epg data.
It appears as though the problem is within the IntializeProvider function within objectStore which is called shortly after TVstore = Microsoft.MediaCenter.Store.ObjectStore.Open(dbfile.FullName);
when not supplying the neccesary credintials it fails out to:
Trace.WriteLine(TraceLevel.Info, TraceOptions.Callstack, "Opening without Admin permissions.")
It appears like all is working with your code, just not getting the permission for all the information???
Does this function the same when run on a x86 version?
Here is a copy of IntializeProvider:
Private Shared Function InitializeProvider(ByVal store As ObjectStore, ByVal providerName As String, ByVal password As String, ByVal callingAssembly As Assembly) As Boolean If String.IsNullOrEmpty(providerName) Then Throw New ArgumentNullException("providerName") End If Dim passwordHash As String = String.Empty If Not String.IsNullOrEmpty(password) Then Dim managed As New SHA256Managed Dim bytes As Byte() = Encoding.Unicode.GetBytes(password) passwordHash = Convert.ToBase64String(managed.ComputeHash(bytes)) End If Dim flag As Boolean = False Dim flag2 As Boolean = False Dim providers As New Providers(store) Dim provider As Provider = providers.Item(New NameKey(providerName)) If (provider Is Nothing) Then provider = New Provider(providerName, passwordHash) providers.Add(provider) flag = True Else flag = (String.Compare(provider.PasswordHash, passwordHash, StringComparison.Ordinal) = 0) End If If (String.Compare(providerName, "frodo", StringComparison.Ordinal) = 0) Then flag = (String.Compare(passwordHash, "lRHLqm8I3IFsTWT13vr9gbov5dHHBgRj0Ga0jriDD88=", StringComparison.Ordinal) = 0) If flag Then flag2 = True End If ElseIf (String.Compare(providerName, "Default", StringComparison.Ordinal) <> 0) Then Dim managed2 As New SHA256Managed Dim buffer As Byte() = Encoding.Unicode.GetBytes(providerName) If (String.Compare(Convert.ToBase64String(managed2.ComputeHash(buffer)), "yo4uz8lUdecm6bCiATRRIwcjyTi2WBNPg+MzOsE3e0E=", StringComparison.Ordinal) = 0) Then Dim clientId As String = ObjectStore.GetClientId(True) Dim buffer3 As Byte() = Encoding.Unicode.GetBytes(clientId) clientId = Convert.ToBase64String(managed2.ComputeHash(buffer3)) buffer3 = Encoding.Unicode.GetBytes(clientId) clientId = Convert.ToBase64String(managed2.ComputeHash(buffer3)) flag = (String.Compare(passwordHash, clientId, StringComparison.Ordinal) = 0) If flag Then flag2 = True End If End If End If If (((Not callingAssembly Is Nothing) AndAlso Not flag2) AndAlso ObjectStore.CheckCallingAssembly(callingAssembly)) Then Dim entryAssembly As Assembly = Assembly.GetEntryAssembly If (Not entryAssembly Is Nothing) Then If ObjectStore.CheckCallingAssembly(entryAssembly) Then flag2 = True End If Else Dim frames As StackFrame() = New StackTrace(1, False).GetFrames If (frames.Length > 0) Then Dim method As MethodBase = frames((frames.Length - 1)).GetMethod If (Not method Is Nothing) Then Dim declaringType As Type = method.DeclaringType If (Not declaringType Is Nothing) Then Dim assembly As Assembly = declaringType.Assembly If ((Not [assembly] Is Nothing) AndAlso ObjectStore.CheckCallingAssembly([assembly])) Then flag2 = True End If End If End If End If End If End If If flag2 Then flag = True If (String.Compare(providerName, "Default", StringComparison.Ordinal) = 0) Then provider = providers.Item(New NameKey("MediaCenterDefault")) If (provider Is Nothing) Then provider = New Provider("MediaCenterDefault", "Windows Media Center Default Provider") providers.Add(provider) End If End If End If If (((Not provider Is Nothing) AndAlso (String.Compare(provider.Name, "MediaCenterDefault", StringComparison.Ordinal) = 0)) AndAlso (String.Compare(provider.PasswordHash, "Windows Media Center Default Provider", StringComparison.Ordinal) <> 0)) Then flag = False End If If Not flag Then Return False End If If (provider Is Nothing) Then Throw New InvalidOperationException("Unable to establish a provider") End If store.provider = provider If flag2 Then provider.OngoingPermissionChecks = True Else Trace.WriteLine(TraceLevel.Info, TraceOptions.Callstack, "Opening without Admin permissions.") End If Dim dictionary As New Dictionary(Of Type, StoredTypeRestriction) Dim restriction As StoredTypeRestriction For Each restriction In provider.StoredTypeRestrictions If (Not restriction Is Nothing) Then Dim storedType As StoredType = restriction.StoredType If (Not storedType Is Nothing) Then Dim type As Type = storedType.Type If Not dictionary.ContainsKey(type) Then dictionary.Add(type, restriction) End If End If End If Next store.providerRestrictionsTable = dictionary Return True End Function -
Friday, April 09, 2010 1:20 AM
oh and i wonder if the password is Baggins for what appears to be an old testing provider.....
If (String.Compare(providerName, "frodo", StringComparison.Ordinal) = 0) Then flag = (String.Compare(passwordHash, "lRHLqm8I3IFsTWT13vr9gbov5dHHBgRj0Ga0jriDD88=", StringComparison.Ordinal) = 0)sadly the provider name does not allow frodo anymore.
I guess he's been banned from Microsoft Earth.
- Proposed As Answer by dark_me Tuesday, January 18, 2011 2:57 PM
-
Saturday, October 09, 2010 11:27 PM
H i,
You may see the inner implementation of GetScheduleEntriesBetween method from Reflector .
If the exception make your application crash, you can follow the article http://support.microsoft.com/default.aspx/kb/286350 to capture the dump file of the crashing application. After you get the dump, please let me know your email address by sending a mail to v-eryang@microsoft.com . Then I will create a file transfer workspace where you can upload your ump file. The dump will be kept confidential.
Sincerely,
Eric
MSDN Subscriber Support in Forum
If you have any feedback of our support, please contact msdnmg@microsoft.com.
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
Many thanks to your description! I got more deep understanding about this part. -
Tuesday, January 18, 2011 3:12 PM
I have the same problem. I need access to the ObjectStore to manually add channels. Using MergedLineups I can call AddUserChannel.
The code works fine on x86 but generates an exception on x64. I traced the problem to a difference in the CheckCallingAssembly from InitializeProvider in the Open store function call. On x86 GetExecutingAssembly() == GetCallingAssembly() but on x64 it is not. I am not sure if there is a bug in the x64 version or in the x86 version. So on x86 you can get administrator permisions even without a provider name and password, but on x64 you cannot.
This is a problem for me since ussing the AddUserChannel from Microsoft.MediaCenter.Guide.MergedLineups is the only way I found to add channels in Media Center.
-
Monday, January 24, 2011 5:19 PM
I have the same problem. I need access to the ObjectStore to manually add channels. Using MergedLineups I can call AddUserChannel.
The code works fine on x86 but generates an exception on x64. I traced the problem to a difference in the CheckCallingAssembly from InitializeProvider in the Open store function call. On x86 GetExecutingAssembly() == GetCallingAssembly() but on x64 it is not. I am not sure if there is a bug in the x64 version or in the x86 version. So on x86 you can get administrator permisions even without a provider name and password, but on x64 you cannot.
This is a problem for me since ussing the AddUserChannel from Microsoft.MediaCenter.Guide.MergedLineups is the only way I found to add channels in Media Center.
I found this code in the ObjectStore.cs file ussing reflector.
string s = "Unable upgrade recording state.";
byte[] bytes = Convert.FromBase64String("FAAODBUITwADRicSARc=");
byte[] buffer2 = Encoding.ASCII.GetBytes(s);
for (int i = 0; i != bytes.Length; i++)
{
bytes[i] = (byte)(bytes[i] ^ buffer2[i]);
}
string clientId = Microsoft.MediaCenter.Store.ObjectStore.GetClientId(true);
SHA256Managed managed = new SHA256Managed();
byte[] buffer = Encoding.Unicode.GetBytes(clientId);
clientId = Convert.ToBase64String(managed.ComputeHash(buffer));
string FriendlyName = Encoding.ASCII.GetString(bytes);
string DisplayName = clientId;
ObjectStore TVstore = Microsoft.MediaCenter.Store.ObjectStore.Open("", FriendlyName, DisplayName, true);
It gets admin access to the ObjectStore database. It is probably not the nicest way to do things but it worked for me.
-
Monday, August 22, 2011 10:35 AM
Is this really the last word on this?
Is media center dead already?
-
Tuesday, November 08, 2011 8:54 PMDoes anybody want to do some more work on this to understand the ObjectStore structure and how it is used?