.NET Framework Developer Center > .NET Framework Forums > .NET Platform Architecture Development Discussions > [NEW] Media Center Addin x64: Microsoft.MediaCenter.GuideSubscribed

Proposed Answer [NEW] Media Center Addin x64: Microsoft.MediaCenter.GuideSubscribed

  • Wednesday, March 10, 2010 12:14 PM
     
     
    Sorry, 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:
    ScheduleEntry e = channel.Service.GetScheduleEntryAt(DateTime.Now);

    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.

    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 AM
    Moderator
     
     
    Hi,
    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
     
      Has Code
    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 AM
    Moderator
     
     

    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 PM
     
     
    Hi 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 AM
    Moderator
     
     

    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
     
      Has Code

    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 AM
    Moderator
     
     

    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
     
      Has Code

    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
     
     Proposed Answer Has Code

    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 PM
     
     
    Does anybody want to do some more work on this to understand the ObjectStore structure and how it is used?