sirbow2 Posted August 20, 2011 Share Posted August 20, 2011 hi im making a C# program that can read the shared memory from Everest. i read the stuff from the help faq ADIA64 shared memory but it doesnt have anything about the structlayout for C#. the program will be similair to C# shared memory speedfan thanks Quote Link to comment Share on other sites More sharing options...
Fiery Posted August 20, 2011 Share Posted August 20, 2011 There's no struct involved at all, since AIDA64 publishes sensor readings in shared memory as a single long string (set of characters), using XML format. You can simply read the full shared memory into a character variable, and display it or post-process it. Regards, Fiery Quote Link to comment Share on other sites More sharing options...
sirbow2 Posted August 21, 2011 Author Share Posted August 21, 2011 There's no struct involved at all, since AIDA64 publishes sensor readings in shared memory as a single long string (set of characters), using XML format. You can simply read the full shared memory into a character variable, and display it or post-process it. Regards, Fiery thanks for the info, ive managed to get the speed fan code up and running. so now all i need to do is change the shared memory address in the C# program, remove the speedfan structLayout, how would i interpret this data into simple integers? XMLReader? 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("SpeedFan64_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; } } } Quote Link to comment Share on other sites More sharing options...
Fiery Posted August 21, 2011 Share Posted August 21, 2011 Either you implement a XML parser, or simply process the long string, to convert it to a format that you need. It's not a real, complex XML string, just a dumb XML-like format Quote Link to comment Share on other sites More sharing options...
sirbow2 Posted August 21, 2011 Author Share Posted August 21, 2011 Either you implement a XML parser, or simply process the long string, to convert it to a format that you need. It's not a real, complex XML string, just a dumb XML-like format could you help me with that code? no one else seems to understand what im trying to do, either method i dont care, i jsut need the values as int and floats etc. Quote Link to comment Share on other sites More sharing options...
sirbow2 Posted August 22, 2011 Author Share Posted August 22, 2011 could you help me with that code? no one else seems to understand what im trying to do, either method i dont care, i jsut need the values as int and floats etc. well i managed to get some code to work that gets the memory and writes to a file, but that file is all little "ㄱ⼼慶畬㹥⼼祳㹳猼ç¹ã°¾æ‘©åŒ¾ä¥”ä•â¼¼æ‘©"s. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Runtime.InteropServices; namespace SharedMemSaveToFile { class SharedMemSaver { public class Data { static void Main(string[] args) { SharedMemSaver sf = new SharedMemSaver(); sf.OpenView(); String d = sf.GetData(); System.IO.StreamWriter file = new System.IO.StreamWriter("C:\\files.txt"); file.WriteLine(d); } } #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; ~SharedMemSaver() { CloseView(); } public bool OpenView() { if (!fileOpen) { StringBuilder sharedMemFile = new StringBuilder("AIDA64_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, 0); 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 String GetData() { if (fileOpen) { String data = (String)Marshal.PtrToStringAuto(map); return data; } else { return null; } } } } Quote Link to comment Share on other sites More sharing options...
sirbow2 Posted August 26, 2011 Author Share Posted August 26, 2011 new question: what encoding does the xml use? ASCI UTF8? etc? Quote Link to comment Share on other sites More sharing options...
Fiery Posted August 27, 2011 Share Posted August 27, 2011 new question: what encoding does the xml use? ASCI UTF8? etc? Plain old ASCII Quote Link to comment Share on other sites More sharing options...
sirbow2 Posted August 28, 2011 Author Share Posted August 28, 2011 Plain old ASCII cool but then why do i have this: NUL NUL NUL NUL at the end of the string when i print it to a text file and open with notepad++? this is causing issues with my code. what do you recommend? can you fix this? Quote Link to comment Share on other sites More sharing options...
Fiery Posted August 28, 2011 Share Posted August 28, 2011 NUL character is used to indicate the end of the string. Quote Link to comment Share on other sites More sharing options...
sirbow2 Posted August 28, 2011 Author Share Posted August 28, 2011 ahh well i got it to work, i set the length to 300 for ex then the CPU mulitplier would change to 11 from 6 thus adding a character and messing up the length. so since i was never going to use all the data given by aida i just selected a few options for shared memory that dont change in length. Quote Link to comment Share on other sites More sharing options...
Fiery Posted August 28, 2011 Share Posted August 28, 2011 Please note that the shared memory content doesn't have a fixed length, so the number of characters is dynamically changed depending on the shared memory content. We indicate the end of string by the NUL character. If you use a char* or PChar sort of variable, then it should be easy to handle a zero-terminated string. Quote Link to comment Share on other sites More sharing options...
Foyn Posted November 4, 2011 Share Posted November 4, 2011 @sirbow2 I tried the code myself, but i couldn´t solve the problem with the ㄱ⼼慶畬㹥⼼祳㹳猼ç¹ã°¾æ‘©åŒ¾ä¥”ä•â¼¼æ‘©" Code in the .txt-File, I didn´t understand where you defined the length to 300, could you tell me what exactly you have done to solve the problem? Quote Link to comment Share on other sites More sharing options...
schkube Posted June 10, 2012 Share Posted June 10, 2012 Simples, to solve the ㄱ⼼慶畬㹥⼼祳㹳猼ç¹ã°¾æ‘©åŒ¾ä¥”ä•â¼¼æ‘©" problem, just change: String data = (String)Marshal.PtrToStringAuto(map); To... String data = (String)Marshal.PtrToStringAnsi(map); You can then parse the XML using whatever method floats your boat. Google is your friend. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.