0 Replies - 686 Views - Last Post: 21 August 2011 - 11:41 PM Rate Topic: -----

#1 sirbow2   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 21-August 11

get XML data from shared memory/Memory mapped file.

Posted 21 August 2011 - 11:41 PM

my situation:
i have a program called AIDA64 which is a system monitoring tool. it has the option to store some of its data in shared memory that other programs can use it. i have set the app to use shared memory now all i need to do is write a program. in my case i want to access temperature data provided by the application and send that data over serial port. when its sen over serial port i want it to be just numbers, no identifiers(ill explain later). i found a C# program similar to what im looking to for SpeedFan. SpeedFan is another temperature app which with this app writes systems stats to CMD, see code below. I am using AIDA instead of SpeedFan because speedfan lacks alot of features that AIDA has for sensors. but their are a few differences between that make it incompatible sort of with AIDA64.
-struct layout/WriteLine, the speedfan uses structlayout to get the data from memory, AIDA puts the data as simple XML file in memory. SpeedFan C# app writes to CMD via WriteLine incompatible with AIDA because of XML format. see:
<temp><id>TGPU1</id><label>GPU</label><value>67</value></temp>
<temp><id>THDD1</id><label>ST3320620AS</label><value>34</value></temp>

-Memory name is different, but i know that AIDA uses AIDA64_SensorValues as its memory name. i can change the memory name to AIDA it will run but it doesn't do anything as trying to use the sped fan structlayout etc with AIDA XML.


but i have found some help from people, i think this is what i need to do:
-copy the memory into a managed structure. Use one of the Marshal.PtrToString variants (probably Ptr.ToStringAuto), this will give you a String object that contains the XML.
-use XMLReader.Create() on the string to get an XMLReader object
-after i use XML reader and just the numbers are put into another string or variable etc, i can send them over serial. but that's for later.

for the Ptr.ToStringAuto i figured that "public Data GetData()" part from the code needed to be:
public String GetData()
        {
            if (fileOpen)
            {
                String data = (String)Marshal.Ptr.ToStringAuto(map);

                return data;
            }
            else
                return null;
        }

and "SpeedFan.Data d = sf.GetData();" as "String d = sf.GetData();"

but now is where i need your help. im confused on the XML stuff, what code from the SpeedFan "write to CMD" do i get rid of? "static void printHeader(SpeedFan.Data d)" and "static void printData(SpeedFan.Data d)" for sure right? modify the try/catch, try/final places

also sine i have so far put the data from memory into a string, and the string is just a XML file can i output the string to file and see whats in it?

Thanks!! ill gladly answer any questions, confusion.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;

namespace SpeedFanReader
{
    class SpeedFan
    {

        static void printHeader(SpeedFan.Data d)
        {
            String header = "";
            for (int i = 0; i < d.numFans; i++)
            {
                header += "Fan " + i + ",";
            }
            for (int i = 0; i < d.numTemps; i++)
            {
                header += "Temp " + i + ",";
            }
            for (int i = 0; i < d.numVolts; i++)
            {
                header += "Volt " + i + ",";
            }
            header += "Flags";
            Console.WriteLine(header);
        }

        static void printData(SpeedFan.Data d)
        {
            if (d != null)
            {
                String output = "";
                for (int i = 0; i < d.numFans; i++)
                {
                    output += d.fans[i] + ",";
                }
                for (int i = 0; i < d.numTemps; i++)
                {
                    output += d.temps[i] + ",";
                }
                for (int i = 0; i < d.numVolts; i++)
                {
                    output += d.volts[i] + ",";
                }
                output += d.flags;

                Console.WriteLine(output);
            }
        }

        static void Main(string[] args)
        {
            SpeedFan sf = new SpeedFan();

            sf.OpenView();
            bool done = false;
            StreamWriter writer = null;
            if (args.Length > 0)
            {
                try
                {
                    writer = new StreamWriter(args[0]);
                    writer.AutoFlush = true;
                    Console.SetOut(writer); // redirect stdout to the file
                }
                catch (IOException e)
                {
                    Console.WriteLine("Failed to open file: " + args[0] + " : " + e.Message);
                    return;
                }
            }
            try
            {
                bool first = true;
                while (!done)
                {
                    SpeedFan.Data d = sf.GetData();

                    if (first)
                    {
                        printHeader(d);
                        first = false;
                    }
                    printData(d);

                    if (writer != null)
                        writer.Flush(); 

                    // Sleep for a second
                    System.Threading.Thread.Sleep(1000);
                }
            }
            finally
            {
                if (writer != null)
                {
                    Console.SetOut(new StreamWriter(Console.OpenStandardOutput()));
                    writer.Flush();
                    writer.Close();
                }
                Console.WriteLine("Done!");
            }
        }

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public class Data
        {
            public ushort version;
            public ushort flags;
            public Int32 size;
            public Int32 handle;
            public ushort numTemps;
            public ushort numFans;
            public ushort numVolts;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
            public Int32[] temps;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
            public Int32[] fans;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
            public Int32[] volts;

            public Data()
            {
                temps = new Int32[32];
                fans = new Int32[32];
                volts = new Int32[32];
            }
        }

        #region Win32 API stuff
        public const int FILE_MAP_READ = 0x0004;

        [DllImport("Kernel32", CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern IntPtr OpenFileMapping(int dwDesiredAccess,
            bool bInheritHandle, StringBuilder lpName);

        [DllImport("Kernel32", CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern IntPtr MapViewOfFile(IntPtr hFileMapping,
            int dwDesiredAccess, int dwFileOffsetHigh, int dwFileOffsetLow,
            int dwNumberOfBytesToMap);

        [DllImport("Kernel32.dll")]
        internal static extern bool UnmapViewOfFile(IntPtr map);

        [DllImport("kernel32.dll")]
        internal static extern bool CloseHandle(IntPtr hObject);
        #endregion

        private bool fileOpen = false;
        private IntPtr map;
        private IntPtr handle;

        ~SpeedFan()
        {
            CloseView();
        }

        public bool OpenView()
        {
            if (!fileOpen)
            {
                StringBuilder sharedMemFile = new StringBuilder("SpeedFan_SensorValues");
                handle = OpenFileMapping(FILE_MAP_READ, false, sharedMemFile);
                if (handle == IntPtr.Zero)
                {
                    throw new Exception("Unable to open file mapping.");
                }
                map = MapViewOfFile(handle, FILE_MAP_READ, 0, 0, Marshal.SizeOf((Type)typeof(Data)));
                if (map == IntPtr.Zero)
                {
                    throw new Exception("Unable to read shared memory.");
                }
                fileOpen = true;
            }
            return fileOpen;
        }

        public void CloseView()
        {
            if (fileOpen)
            {
                UnmapViewOfFile(map);
                CloseHandle(handle);
            }
        }

        public Data GetData()
        {
            if (fileOpen)
            {
                Data data = (Data)Marshal.PtrToStructure(map, typeof(Data));

                return data;
            }
            else
                return null;
        }
    }
}


Is This A Good Question/Topic? 0
  • +

Page 1 of 1