WMI Remote Process Starting - c#

Scenario
I've written a WMI Wrapper that seems to be quite sufficient, however whenever I run the code to start a remote process on a server, I see the process name appear in the task manager but the process itself does not start like it should (as in, I don't see the command line log window of the process that prints out what it's doing etc.)
The process I am trying to start is just a C# application executable that I have written.
Below is my WMI Wrapper Code and the code I am using to start running the process.
Question
Is the process actually running? - Even if it is only displaying the process name in the task manager and not actually launching the application to the users window?
Code To Start The Process
IPHostEntry hostEntry = Dns.GetHostEntry("InsertServerName");
WMIWrapper wrapper = new WMIWrapper("Insert User Name", "Insert Password", hostEntry.HostName);
List<Process> processes = wrapper.GetProcesses();
foreach (Process process in processes)
{
if (process.Caption.Equals("MyAppName.exe"))
{
Console.WriteLine(process.Caption);
Console.WriteLine(process.CommandLine);
int processId;
wrapper.StartProcess("E:\\MyData\\Data\\MyAppName.exe", out processId);
Console.WriteLine(processId.ToString());
}
}
Console.ReadLine();
WMI Wrapper Code
using System;
using System.Collections.Generic;
using System.Management;
using System.Runtime.InteropServices;
using Common.WMI.Objects;
using System.Net;
namespace Common.WMIWrapper
{
public class WMIWrapper : IDisposable
{
#region Constructor
/// <summary>
/// Creates a new instance of the wrapper
/// </summary>
/// <param jobName="username"></param>
/// <param jobName="password"></param>
/// <param jobName="server"></param>
public WMIWrapper(string server)
{
Initialise(server);
}
/// <summary>
/// Creates a new instance of the wrapper
/// </summary>
/// <param jobName="username"></param>
/// <param jobName="password"></param>
/// <param jobName="server"></param>
public WMIWrapper(string username, string password, string server)
{
Initialise(username, password, server);
}
#endregion
#region Destructor
/// <summary>
/// Clean up unmanaged references
/// </summary>
~WMIWrapper()
{
Dispose(false);
}
#endregion
#region Initialise
/// <summary>
/// Initialise the WMI Connection (local machine)
/// </summary>
/// <param name="server"></param>
private void Initialise(string server)
{
m_server = server;
// set connection options
m_connectOptions = new ConnectionOptions();
IPHostEntry host = Dns.GetHostEntry(Environment.MachineName);
}
/// <summary>
/// Initialise the WMI connection
/// </summary>
/// <param jobName="username">Username to connect to server with</param>
/// <param jobName="password">Password to connect to server with</param>
/// <param jobName="server">Server to connect to</param>
private void Initialise(string username, string password, string server)
{
m_server = server;
// set connection options
m_connectOptions = new ConnectionOptions();
IPHostEntry host = Dns.GetHostEntry(Environment.MachineName);
if (host.HostName.Equals(server, StringComparison.OrdinalIgnoreCase))
return;
m_connectOptions.Username = username;
m_connectOptions.Password = password;
m_connectOptions.Impersonation = ImpersonationLevel.Impersonate;
m_connectOptions.EnablePrivileges = true;
}
#endregion
/// <summary>
/// Return a list of available wmi namespaces
/// </summary>
/// <returns></returns>
public List<String> GetWMINamespaces()
{
ManagementScope wmiScope = new ManagementScope(String.Format("\\\\{0}\\root", this.Server), this.ConnectionOptions);
List<String> wmiNamespaceList = new List<String>();
ManagementClass wmiNamespaces = new ManagementClass(wmiScope, new ManagementPath("__namespace"), null); ;
foreach (ManagementObject ns in wmiNamespaces.GetInstances())
wmiNamespaceList.Add(ns["Name"].ToString());
return wmiNamespaceList;
}
/// <summary>
/// Return a list of available classes in a namespace
/// </summary>
/// <param jobName="wmiNameSpace">Namespace to get wmi classes for</param>
/// <returns>List of classes in the requested namespace</returns>
public List<String> GetWMIClassList(string wmiNameSpace)
{
ManagementScope wmiScope = new ManagementScope(String.Format("\\\\{0}\\root\\{1}", this.Server, wmiNameSpace), this.ConnectionOptions);
List<String> wmiClasses = new List<String>();
ManagementObjectSearcher wmiSearcher = new ManagementObjectSearcher(wmiScope, new WqlObjectQuery("SELECT * FROM meta_Class"), null);
foreach (ManagementClass wmiClass in wmiSearcher.Get())
wmiClasses.Add(wmiClass["__CLASS"].ToString());
return wmiClasses;
}
/// <summary>
/// Get a list of wmi properties for the specified class
/// </summary>
/// <param jobName="wmiNameSpace">WMI Namespace</param>
/// <param jobName="wmiClass">WMI Class</param>
/// <returns>List of properties for the class</returns>
public List<String> GetWMIClassPropertyList(string wmiNameSpace, string wmiClass)
{
List<String> wmiClassProperties = new List<string>();
ManagementClass managementClass = GetWMIClass(wmiNameSpace, wmiClass);
foreach (PropertyData property in managementClass.Properties)
wmiClassProperties.Add(property.Name);
return wmiClassProperties;
}
/// <summary>
/// Returns a list of methods for the class
/// </summary>
/// <param jobName="wmiNameSpace"></param>
/// <param jobName="wmiClass"></param>
/// <returns></returns>
public List<String> GetWMIClassMethodList(string wmiNameSpace, string wmiClass)
{
List<String> wmiClassMethods = new List<string>();
ManagementClass managementClass = GetWMIClass(wmiNameSpace, wmiClass);
foreach (MethodData method in managementClass.Methods)
wmiClassMethods.Add(method.Name);
return wmiClassMethods;
}
/// <summary>
/// Retrieve the specified management class
/// </summary>
/// <param jobName="wmiNameSpace">Namespace of the class</param>
/// <param jobName="wmiClass">Type of the class</param>
/// <returns></returns>
public ManagementClass GetWMIClass(string wmiNameSpace, string wmiClass)
{
ManagementScope wmiScope = new ManagementScope(String.Format("\\\\{0}\\root\\{1}", this.Server, wmiNameSpace), this.ConnectionOptions);
ManagementClass managementClass = null;
ManagementObjectSearcher wmiSearcher = new ManagementObjectSearcher(wmiScope, new WqlObjectQuery(String.Format("SELECT * FROM meta_Class WHERE __CLASS = '{0}'", wmiClass)), null);
foreach (ManagementClass wmiObject in wmiSearcher.Get())
managementClass = wmiObject;
return managementClass;
}
/// <summary>
/// Get an instance of the specficied class
/// </summary>
/// <param jobName="wmiNameSpace">Namespace of the classes</param>
/// <param jobName="wmiClass">Type of the classes</param>
/// <returns>Array of management classes</returns>
public ManagementObject[] GetWMIClassObjects(string wmiNameSpace, string wmiClass)
{
ManagementScope wmiScope = new ManagementScope(String.Format("\\\\{0}\\root\\{1}", this.Server, wmiNameSpace), this.ConnectionOptions);
List<ManagementObject> wmiClasses = new List<ManagementObject>();
ManagementObjectSearcher wmiSearcher = new ManagementObjectSearcher(wmiScope, new WqlObjectQuery(String.Format("SELECT * FROM {0}", wmiClass)), null);
foreach (ManagementObject wmiObject in wmiSearcher.Get())
wmiClasses.Add(wmiObject);
return wmiClasses.ToArray();
}
/// <summary>
/// Get a full list of services
/// </summary>
/// <returns></returns>
public List<Service> GetServices()
{
return GetService(null);
}
/// <summary>
/// Get a list of services
/// </summary>
/// <returns></returns>
public List<Service> GetService(string name)
{
ManagementObject[] services = GetWMIClassObjects("CIMV2", "WIN32_Service");
List<Service> serviceList = new List<Service>();
for (int i = 0; i < services.Length; i++)
{
ManagementObject managementObject = services[i];
Service service = new Service(managementObject);
service.Status = (string)managementObject["Status"];
service.Name = (string)managementObject["Name"];
service.DisplayName = (string)managementObject["DisplayName"];
service.PathName = (string)managementObject["PathName"];
service.ProcessId = (uint)managementObject["ProcessId"];
service.Started = (bool)managementObject["Started"];
service.StartMode = (string)managementObject["StartMode"];
service.ServiceType = (string)managementObject["ServiceType"];
service.InstallDate = (string)managementObject["InstallDate"];
service.Description = (string)managementObject["Description"];
service.Caption = (string)managementObject["Caption"];
if (String.IsNullOrEmpty(name) || name.Equals(service.Name, StringComparison.OrdinalIgnoreCase))
serviceList.Add(service);
}
return serviceList;
}
/// <summary>
/// Get a list of processes
/// </summary>
/// <returns></returns>
public List<Process> GetProcesses()
{
return GetProcess(null);
}
/// <summary>
/// Get a list of processes
/// </summary>
/// <returns></returns>
public List<Process> GetProcess(uint? processId)
{
ManagementObject[] processes = GetWMIClassObjects("CIMV2", "WIN32_Process");
List<Process> processList = new List<Process>();
for (int i = 0; i < processes.Length; i++)
{
ManagementObject managementObject = processes[i];
Process process = new Process(managementObject);
process.Priority = (uint)managementObject["Priority"];
process.ProcessId = (uint)managementObject["ProcessId"];
process.Status = (string)managementObject["Status"];
DateTime createDate;
if (ConvertFromWmiDate((string)managementObject["CreationDate"], out createDate))
process.CreationDate = createDate.ToString("dd-MMM-yyyy HH:mm:ss");
process.Caption = (string)managementObject["Caption"];
process.CommandLine = (string)managementObject["CommandLine"];
process.Description = (string)managementObject["Description"];
process.ExecutablePath = (string)managementObject["ExecutablePath"];
process.ExecutionState = (string)managementObject["ExecutionState"];
process.MaximumWorkingSetSize = (UInt32?)managementObject ["MaximumWorkingSetSize"];
process.MinimumWorkingSetSize = (UInt32?)managementObject["MinimumWorkingSetSize"];
process.KernelModeTime = (UInt64)managementObject["KernelModeTime"];
process.ThreadCount = (UInt32)managementObject["ThreadCount"];
process.UserModeTime = (UInt64)managementObject["UserModeTime"];
process.VirtualSize = (UInt64)managementObject["VirtualSize"];
process.WorkingSetSize = (UInt64)managementObject["WorkingSetSize"];
if (processId == null || process.ProcessId == processId.Value)
processList.Add(process);
}
return processList;
}
/// <summary>
/// Start the specified process
/// </summary>
/// <param jobName="commandLine"></param>
/// <returns></returns>
public bool StartProcess(string command, out int processId)
{
processId = int.MaxValue;
ManagementClass processClass = GetWMIClass("CIMV2", "WIN32_Process");
object[] objectsIn = new object[4];
objectsIn[0] = command;
processClass.InvokeMethod("Create", objectsIn);
if (objectsIn[3] == null)
return false;
processId = int.Parse(objectsIn[3].ToString());
return true;
}
/// <summary>
/// Schedule a process on the remote machine
/// </summary>
/// <param name="command"></param>
/// <param name="scheduleTime"></param>
/// <param name="jobName"></param>
/// <returns></returns>
public bool ScheduleProcess(string command, DateTime scheduleTime, out string jobName)
{
jobName = String.Empty;
ManagementClass scheduleClass = GetWMIClass("CIMV2", "Win32_ScheduledJob");
object[] objectsIn = new object[7];
objectsIn[0] = command;
objectsIn[1] = String.Format("********{0:00}{1:00}{2:00}.000000+060", scheduleTime.Hour, scheduleTime.Minute, scheduleTime.Second);
objectsIn[5] = true;
scheduleClass.InvokeMethod("Create", objectsIn);
if (objectsIn[6] == null)
return false;
UInt32 scheduleid = (uint)objectsIn[6];
jobName = scheduleid.ToString();
return true;
}
/// <summary>
/// Returns the current time on the remote server
/// </summary>
/// <returns></returns>
public DateTime Now()
{
ManagementScope wmiScope = new ManagementScope(String.Format("\\\\{0}\\root\\{1}", this.Server, "CIMV2"), this.ConnectionOptions);
ManagementClass managementClass = null;
ManagementObjectSearcher wmiSearcher = new ManagementObjectSearcher(wmiScope, new WqlObjectQuery(String.Format("SELECT * FROM Win32_LocalTime")), null);
DateTime localTime = DateTime.MinValue;
foreach (ManagementObject time in wmiSearcher.Get())
{
UInt32 day = (UInt32)time["Day"];
UInt32 month = (UInt32)time["Month"];
UInt32 year = (UInt32)time["Year"];
UInt32 hour = (UInt32)time["Hour"];
UInt32 minute = (UInt32)time["Minute"];
UInt32 second = (UInt32)time["Second"];
localTime = new DateTime((int)year, (int)month, (int)day, (int)hour, (int)minute, (int)second);
};
return localTime;
}
/// <summary>
/// Converts a wmi date into a proper date
/// </summary>
/// <param jobName="wmiDate">Wmi formatted date</param>
/// <returns>Date time object</returns>
private static bool ConvertFromWmiDate(string wmiDate, out DateTime properDate)
{
properDate = DateTime.MinValue;
string properDateString;
// check if string is populated
if (String.IsNullOrEmpty(wmiDate))
return false;
wmiDate = wmiDate.Trim().ToLower().Replace("*", "0");
string[] months = new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
try
{
properDateString = String.Format("{0}-{1}-{2} {3}:{4}:{5}.{6}",
wmiDate.Substring(6, 2), months[int.Parse(wmiDate.Substring(4, 2)) - 1], wmiDate.Substring(0, 4), wmiDate.Substring(8, 2), wmiDate.Substring(10, 2), wmiDate.Substring(12, 2), wmiDate.Substring(15, 6));
}
catch (InvalidCastException)
{
return false;
}
catch (ArgumentOutOfRangeException)
{
return false;
}
// try and parse the new date
if (!DateTime.TryParse(properDateString, out properDate))
return false;
// true if conversion successful
return true;
}
private bool m_disposed;
#region IDisposable Members
/// <summary>
/// Managed dispose
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Dispose of managed and unmanaged objects
/// </summary>
/// <param jobName="disposing"></param>
public void Dispose(bool disposing)
{
if (disposing)
{
m_connectOptions = null;
}
}
#endregion
#region Properties
private ConnectionOptions m_connectOptions;
/// <summary>
/// Gets or sets the management scope
/// </summary>
private ConnectionOptions ConnectionOptions
{
get
{
return m_connectOptions;
}
set
{
m_connectOptions = value;
}
}
private String m_server;
/// <summary>
/// Gets or sets the server to connect to
/// </summary>
public String Server
{
get
{
return m_server;
}
set
{
m_server = value;
}
}
#endregion
}
}

It is running but it's not running interactive. If you're running a process remotely you can't be sure that someone is even logged in to that pc so you can't assume that it can have a GUI that a user can interact with.
I'd suggest, instead of writing progress to the console window, write it to a file or the Event log.

Related

Unable to assign to Hashtable item in C# class consumed from VBA

I have written a C# class (KvpHash) for consumption in VBA which provides additional useful functionality around a Hashtable. In my VBA code I have an extensive Rubberduck test suite for the KvpHash class that shows all functions of the class work as expected except for the fact that I cannot change the value of an item.
From VBA I get the error message
424 'Object required'
In the C# class the interface code is
dynamic this[dynamic Key] { get; set; }
and the implementation is
public dynamic this[dynamic Key]
{
get
{
return MyKvpHash[Key];
}
set
{
MyKvpHash[Key] = value;
}
}
where MyKvpHash is defined as
private Hashtable MyKvpHash = new Hashtable();
If I add the mscorelib reference to VBA I can create a Hashtable directly in VBA where it is fully possible to change the value of an item in the Hash Table.
I'd appreciate pointers as to what I am doing wrong in the C# code which causes the object required error.
Edited: to add example VBA code
Using a native HashTable
Public Sub TestHashtable()
' requires reference to mscorlib.dll
Dim myHt As Hashtable
Set myHt = New Hashtable
myHt.Add 5, "Hello5"
myHt.Add 10, "Hello10"
Debug.Print myHt.Item(10)
Debug.Print myHt.Item(5)
' the next line works as expected
myHt.Item(10) = "A new world"
Debug.Print myHt.Item(10)
End Sub
Gives the output
Hello10
Hello5
A new world
Using my KvpHash class ( a wrapper for HashTable)
Public Sub TestKvpHash()
Dim myHt As VBAExtensions.KvpHash
' KvpHash is a C# wrapper for a System.Collections.HashTable
Set myHt = New KvpHash
myHt.AddByKey 5, "Hello5"
myHt.AddByKey 10, "Hello10"
Debug.Print myHt.Item(10)
Debug.Print myHt.Item(5)
' The next line produces error 424
myHt.Item(10) = "A new world"
Debug.Print myHt.Item(10)
End Sub
Gives the output
Hello10
Hello5
and then stops with the 424 error.
Edited to add the full C# code as requested.
Seems there is no file hosting and I don't have another means of providing a link so I'v inserted the relevant code below. The code was originally based on a Dictionary but I updated it to Hashtable when I first found I couldn't assign to an item. That switch didn't change the behaviour of my code. Please be aware that I'm not a professional programmer and that the supplied code is essentially my first foray into C#. Typically I write Word VBA macros for my own consumption.
// VBAExtensions
//
// C# Library module for VBA
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Linq;
namespace VBAExtensions
{
/// <summary>
/// Enum for accessing the kvphash structure returned by Method Cohorts
/// </summary>
public enum CohortType
{
/// <summary>1 = the keys in A plus keys in B that are not shared</summary>
KeysInAAndOnlyB = 1,
/// <summary>2 = the Keys from B in A where B has a different value to A</summary>
KeysInAandBWithDifferentValues,
/// <summary>3 = the keys that are only in A and only in B</summary>
KeysNotInAandB,
/// <summary>4 = the keys that are inA and B </summary>
KeysInAandB,
/// <summary>5 = the keys in A only </summary>
KeysInAOnly,
/// <summary>6 = the keys in B only</summary>
KeysInBOnly
}
/// <summary>
/// KvpHash is a C# class for VBA which implements a Key/Value HashTable
/// The object is a morer flexible version of the Scripting.Dictionary
/// </summary>
[Guid("30F9294B-11B4-4D91-9D7C-7FF02ADB3F11")]
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IKvpHash
{
/// <summary>
/// Returns/Sets the "Value" specified by "Key" (i) of a Key/Value Pair
/// </summary>
/// <param name="Key"></param>
/// <returns>Type used in Set statement (C# dynamic)</returns>
dynamic this[dynamic Key] { get; set; }
/// <summary>
/// Adds "Value" to the KvpHash using an integer (VBA Long) Key.
/// The integer key is based on the first available integer greater than or
/// equal to the Count of the KvpHash
/// </summary>
/// <param name="Value"></param>
void AddByIndex(dynamic Value);
/// <summary>
/// Populates this KvpHash using AddByIndex for each character in the string
/// </summary>
/// <param name="this_string"></param>
void AddByIndexAsChars(string this_string);
/// <summary>
/// Pupulates this KvpHash using AddByIndex for each substring in this_string delineated by this_seperator
/// </summary>
/// <param name="this_string"></param>
/// <param name="this_seperator"></param>
void AddByIndexAsSubStr(string this_string, string this_seperator = ",");
/// <summary>
/// Pupulates a KvpHash using AddByIndex for each array item
/// </summary>
/// <param name="this_array"></param>
void AddByIndexFromArray(dynamic this_array);
/// <summary>
/// Adds "Value" to the KvpHash with a key pf "Key"
/// </summary>
/// <param name="Key"></param>
/// <param name="Value"></param>
void AddByKey(dynamic Key, dynamic Value);
/// <summary>
/// Groups the keys of the two KvpHash
/// </summary>
/// <param name="ArgKvpHash"></param>
/// <returns>An array of 6 KvpHash
/// keys in a {1,2,3,4,5,6}
/// keys in b {1,2,3,6,7,8}
/// 1 = the keys in A plus keys in B that are not shared {1,2,3( from A),4,5,6,7,8}
/// 2 = the Keys from B in A where B has a different value to A {3( from B) if value is different}
/// 3 = the keys that are only in A and only in B {4,5,7,8}
/// 4 = the keys that are in A and B {1,2,3,6}
/// 5 = the keys in A only {4,5}
/// 6 = the keys in B only {7,8}
/// </returns>
KvpHash Cohorts(KvpHash ArgKvpHash);
/// <summary>
/// The number of key/vaue pairs in the KvpHash
/// </summary>
/// <returns>Long</returns>
int Count();
///// <summary>
///// Return the IEnumerator interface for KvpHash
///// </summary>
///// <returns>IEnumerator</returns>
//IEnumerator GetEnumerator();
/// <summary>
/// Gets the "Key" for the first ocurrence of "Value" in the KvpHash.
/// </summary>
/// <param name="Value"></param>
/// <returns>Key</returns>
dynamic GetKey(dynamic Value);
/// <summary>
/// Returns a variant array of the Keys of the KvpHash
/// </summary>
/// /// <returns>Variant Array</returns>
dynamic[] GetKeys();
/// <summary>
/// Returns a variant array of the values of the KvpHash
/// </summary>
/// <returns>Variant Array</returns>
dynamic[] GetValues();
/// <summary>
/// True if the "Key" exists in the keys of the KvpHash
/// </summary>
/// <param name="Key"></param>
/// <returns>Boolean</returns>
bool HoldsKey(dynamic Key);
/// <summary>
/// True if the "Value" exists in the values of the KvpHash
/// </summary>
/// <param name="Value"></param>
/// <returns>Boolean</returns>
bool HoldsValue(dynamic Value);
/// <summary>
/// True if the KvpHash holds 0 key/value pairs
/// </summary>
/// <returns>Boolean</returns>
bool IsEmpty();
/// <summary>
/// True if the KvpHash holds one or more key/value pairs
/// </summary>
/// <returns>Boolean</returns>
bool IsNotEmpty();
/// <summary>
/// True is the "Key" is not found in the keys of the KvpHash
/// </summary>
/// <param name="Key"></param>
/// <returns>Boolean</returns>
bool LacksKey(dynamic Key);
/// <summary>
/// True if the "Value" is not found in the values of the KvpHash
/// </summary>
/// <param name="Value"></param>
/// <returns>Boolean</returns>
bool LacksValue(dynamic Value);
/// <summary>
/// Reverses the Key/Value pairs in a KvpHash
/// </summary>
/// <returns>New KvpHash where:
/// KvpHash.Value(1) = KvpHash Unique values as Value/Key pairs
/// KvpHash.Value(2) = KvpHash Non unique values as Key/Value pairs</returns>
KvpHash Mirror();
/// <summary>
/// Removes the Key/Value pair spacified by "Key" from the KvpHash
/// </summary>
/// <param name="Key"></param>
void Remove(dynamic Key);
/// <summary>
/// Removes all Key/Value pairs from the KvpHash
/// </summary>
void RemoveAll();
/// <summary>
/// Returns true if the Values in KvpHash are unique.
/// </summary>
/// <returns>Boolean</returns>
bool ValuesAreUnique();
/// <summary>
/// Returns true if the Values in KvpHash are not unique.
/// </summary>
/// <returns>Boolean</returns>
bool ValuesAreNotUnique();
}
[Guid("87E5A539-FDB3-40D0-9CCD-C817F9893C08")]
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class KvpHash : IKvpHash, IEnumerable
{
private Hashtable MyKvpHash = new Hashtable();
public dynamic this[dynamic Key]
{
get
{
return MyKvpHash[Key];
}
set
{
MyKvpHash[Key] = value;
}
}
public void AddByIndex(dynamic Value)
{
int my_index = MyKvpHash.Count + 1;
while (MyKvpHash.ContainsKey(my_index))
{
my_index++;
}
MyKvpHash.Add(my_index, Value);
}
public void AddByIndexAsChars(string this_string)
{
int my_index = MyKvpHash.Count + 1;
while (MyKvpHash.ContainsKey(my_index))
{
my_index++;
}
char[] MyArray = this_string.ToCharArray();
MyKvpHash.Clear();
for (int i = 0; i <= MyArray.GetUpperBound(0); i++)
{
//KvpHash uses ordinal indexes
MyKvpHash.Add(i + 1, MyArray[i].ToString());
}
}
public void AddByIndexAsSubStr(string this_string, string this_seperator = ",")
{
int my_index = MyKvpHash.Count + 1;
while (MyKvpHash.ContainsKey(my_index))
{
my_index++;
}
string[] MyArray = this_string.Split(this_seperator.ToArray());
for (int i = 0; i <= MyArray.GetUpperBound(0); i++)
{
//KvpHash uses ordinal indexes
MyKvpHash.Add(i + 1, MyArray[i]);
}
}
public void AddByIndexFromArray(dynamic this_array)
{
int my_index = MyKvpHash.Count + 1;
while (MyKvpHash.ContainsKey(my_index))
{
my_index++;
}
for (int i = 0; i <= this_array.GetUpperBound(0); i++)
{
//KvpHash uses ordinal indexes
MyKvpHash.Add(i + 1, this_array[i]);
}
}
public void AddByKey(dynamic Key, dynamic Value)
{
MyKvpHash.Add(Key, Value);
}
public KvpHash Cohorts(KvpHash ArgKvpHash)
{
KvpHash ResultKvpHash = new KvpHash();
// VBA reports object not set error if the resuly KvpHash are not newed
for (int i = 1; i < 7; i++)
{
ResultKvpHash.AddByKey(i, new KvpHash());
}
foreach (DictionaryEntry MyKvpHashPair in MyKvpHash)
{
// A plus unique in B
ResultKvpHash[1].AddByKey(MyKvpHashPair.Key, MyKvpHashPair.Value);
if (ArgKvpHash.LacksKey(MyKvpHashPair.Key)) // problem is here
{
// In A only or in B only
ResultKvpHash[3].AddByKey(MyKvpHashPair.Key, MyKvpHashPair.Value);
// In A only
ResultKvpHash[5].AddByKey(MyKvpHashPair.Key, MyKvpHashPair.Value);
}
else
{
// In A and In B
ResultKvpHash[4].AddByKey(MyKvpHashPair.Key, MyKvpHashPair.Value);
}
}
foreach (dynamic MyKey in ArgKvpHash.GetKeys())
{
// B in A with different value
if (ResultKvpHash[1].LacksKey(MyKey)) // Result 0 will contain all of A
{
ResultKvpHash[1].AddByKey(MyKey, ArgKvpHash[MyKey]);
ResultKvpHash[3].AddByKey(MyKey, ArgKvpHash[MyKey]);
ResultKvpHash[6].AddByKey(MyKey, ArgKvpHash[MyKey]);
}
else
{
if (ResultKvpHash[1][MyKey] != ArgKvpHash[MyKey])
{
ResultKvpHash[2].AddByKey(MyKey, ArgKvpHash[MyKey]);
}
}
}
return ResultKvpHash;
}
public Int32 Count()
{
return MyKvpHash.Count;
}
public bool IsEmpty()
{
return MyKvpHash.Count == 0;
}
public bool IsNotEmpty()
{
return !IsEmpty();
}
public IEnumerator GetEnumerator()
{
foreach (DictionaryEntry my_pair in MyKvpHash)
{
yield return my_pair.Value;
}
}
public dynamic GetKey(dynamic Value)
{
return this.Mirror()[1][Value];
}
public dynamic[] GetKeys()
{
return (dynamic[]) MyKvpHash.Keys;
}
public dynamic[] GetValues()
{
return (dynamic[]) MyKvpHash.Values;
}
public bool HoldsKey(dynamic Key)
{
return MyKvpHash.ContainsKey(Key);
}
public bool HoldsValue(dynamic Value)
{
return MyKvpHash.ContainsValue(Value);
}
public bool LacksKey(dynamic Key)
{
return !HoldsKey(Key);
}
public bool LacksValue(dynamic Value)
{
return !HoldsValue(Value);
}
public KvpHash Mirror()
{
KvpHash MyResult = new KvpHash();
MyResult.AddByIndex(new KvpHash());
MyResult.AddByIndex(new KvpHash());
foreach (DictionaryEntry my_pair in MyKvpHash)
{
if (MyResult[1].LacksKey(my_pair.Value))
{
MyResult[1].AddByKey(my_pair.Value, my_pair.Key);
}
else
{
MyResult[2].AddByKey(my_pair.Key, my_pair.Value);
}
}
return MyResult;
}
public void Remove(dynamic Key)
{
MyKvpHash.Remove(Key);
}
public void RemoveAll()
{
MyKvpHash.Clear();
}
public bool ValuesAreUnique()
{
return MyKvpHash.Count == ((dynamic[]) MyKvpHash.Values).Distinct().Count();
}
public bool ValuesAreNotUnique()
{
return !ValuesAreUnique();
}
}
}
#Freeflow if You change in Word Module the myHt definition it will by OK and will work fine.
Public Sub TestKvpHash()
Dim myHt As Object
' KvpHash is a C# wrapper for a System.Collections.HashTable
Set myHt = New VBAExtensions.KvpHash
' Rest of code

SharpMap WMTS / TMS Server implementation

Can anyone help me with the implementation of WMTS / TMS Server in SharpMap?
I've been trying out a lot from diff sources but I can't seem to come up with a working solution. Below is a handler I am using, it's just drawing the boxes instead of data from the database. I am using the same method I used for a WMS Server:
DatabaseUtil.SqlServer(ConnectionString(), Layers(), new Size(1, 1), bbox, "id");
to get data from SQL Server and it's working just fine for the WMS. The only difference is that the one below returns a specific layer instead of a list by using .FindAll(lyr => lyr.Table.Equals(layer)) query.
/// <summary>
/// Summary description for WMTS
/// </summary>
public class WMTS : IHttpHandler
{
/// <summary>
/// Defines the projection
/// </summary>
private readonly ICoordinateTransformation projection = ProjUtil.ToPseudoMercator();
/// <summary>
/// The ProcessRequest
/// wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=layer_id&STYLE=default&TILEMATRIXSET=matrix_id&TILEMATRIX=3&TILEROW=2&TILECOL=0&FORMAT=image%2Fjpeg
/// </summary>
/// <param name="context">The <see cref="HttpContext"/></param>
public void ProcessRequest(HttpContext context)
{
string layer = context.Request.Params["LAYER"];
int tilematrix = int.Parse(context.Request.Params["TILEMATRIX"]);
int tilerow = int.Parse(context.Request.Params["TILEROW"]);
int tilecol = int.Parse(context.Request.Params["TILECOL"]);
string service = context.Request.Params["SERVICE"];
string request = context.Request.Params["REQUEST"];
string version = context.Request.Params["VERSION"];
string style = context.Request.Params["STYLE"];
string tilematrixset = context.Request.Params["TILEMATRIXSET"];
string format = context.Request.Params["FORMAT"];
if (String.IsNullOrEmpty(layer))
throw new ArgumentNullException("layer");
Map map = Map(layer, tilecol, tilerow, tilematrix);
var map_image = map.GetMap();
//using (var memory_stream = new MemoryStream())
//{
// map_image.Save(memory_stream, ImageFormat.Png);
// var wms = memory_stream.ToArray();
// WriteResponseInChunks(wms, context);
//}
byte[] buffer;
using (var ms = new MemoryStream())
{
map_image.Save(ms, ImageFormat.Png);
map_image.Dispose();
buffer = ms.ToArray();
}
WriteResponseInChunks(buffer, context);
}
public static ImageCodecInfo GetEncoderInfo(String mimeType)
{
foreach (var encoder in ImageCodecInfo.GetImageEncoders())
if (encoder.MimeType == mimeType)
return encoder;
return null;
}
/// <summary>
/// The GetMap
/// </summary>
/// <returns>The <see cref="SharpMap.Map"/></returns>
protected Map Map(string layer, int x, int y, int z)
{
Envelope bbox = GetBoundingBoxInLatLngWithMargin(x, y, z);
return DatabaseUtil.SqlServer(ConnectionString(), Layers().FindAll(lyr => lyr.Table.Equals(layer)), new Size(1, 1), bbox, "id");
}
/// <summary>
/// The Layers
/// </summary>
/// <returns>The <see cref="List{VectorLayerModel}"/></returns>
private List<VectorLayerModel> Layers()
{
VectorLayerModel standsLayerModel = new VectorLayerModel()
{
Table = "cadastre",
Style = new VectorStyle { Line = new Pen(Color.DarkGray, 2) }
};
VectorLayerModel roadsLayerModel = new VectorLayerModel()
{
Table = "townships",
Style = new VectorStyle { Line = new Pen(Color.DarkRed, 2.5f) }
};
VectorLayerModel pipeLayerModel = new VectorLayerModel()
{
Table = "provinces",
Style = new VectorStyle { Line = new Pen(Color.DarkBlue, 1.5f) }
};
return new List<VectorLayerModel>() { standsLayerModel, roadsLayerModel, pipeLayerModel };
}
/// <summary>
/// The ConnectionString
/// </summary>
/// <returns>The <see cref="string"/></returns>
private string ConnectionString()
{
return "Data Source=******;Initial Catalog=GCCIGO_V2;Integrated Security=SSPI;";
}
/// <summary>
/// The GetBoundingBoxInLatLngWithMargin
/// </summary>
/// <param name="tileX">The <see cref="int"/></param>
/// <param name="tileY">The <see cref="int"/></param>
/// <param name="zoom">The <see cref="int"/></param>
/// <returns>The <see cref="Envelope"/></returns>
private Envelope GetBoundingBoxInLatLngWithMargin(int tileX, int tileY, int zoom)
{
Point px1 = new Point((tileX * 256), (tileY * 256));
Point px2 = new Point(((tileX + 1) * 256), ((tileY + 1) * 256));
PointF ll1 = TileSystemHelper.PixelXYToLatLong(px1, zoom);
PointF ll2 = TileSystemHelper.PixelXYToLatLong(px2, zoom);
double[] prj1 = projection.MathTransform.Transform(new double[] { ll1.X, ll1.Y });
double[] prj2 = projection.MathTransform.Transform(new double[] { ll2.X, ll2.Y });
Envelope bbox = new Envelope();
bbox.ExpandToInclude(prj1[0], prj1[1]);
bbox.ExpandToInclude(prj2[0], prj2[1]);
return bbox;
}
/// <summary>
/// The size of the chunks written to response.
/// </summary>
private const int ChunkSize = 2 * 8192;
/// <summary>
/// Method to write an array of bytes in chunks to a http response
/// </summary>
/// <remarks>
/// The code was adopted from http://support.microsoft.com/kb/812406/en-us
/// </remarks>
/// <param name="buffer">The array of bytes</param>
/// <param name="context">The response</param>
private static void WriteResponseInChunks(byte[] buffer, HttpContext context)
{
try
{
bool _continue;
context.Response.ClearContent();
context.Response.ContentType = "image/png";
using (var ms = new MemoryStream(buffer))
{
var dataToRead = buffer.Length;
while (dataToRead > 0)
{
if (context.Response.IsClientConnected)
{
{
var tmpBuffer = new byte[ChunkSize];
var length = ms.Read(tmpBuffer, 0, tmpBuffer.Length);
context.Response.OutputStream.Write(tmpBuffer, 0, length);
context.Response.Flush();
dataToRead -= length;
}
}
else
{
dataToRead = -1;
}
}
_continue = dataToRead > 0;
}
}
catch (Exception ex)
{
context.Response.ClearContent();
context.Response.ContentType = "text/plain";
context.Response.Write(string.Format("Error : {0}", ex.Message));
context.Response.Write(string.Format("Source : {0}", ex.Message));
context.Response.Write(string.Format("StackTrace: {0}", ex.StackTrace));
}
finally
{
context.Response.End();
}
}
/// <summary>
/// Gets a value indicating whether IsReusable
/// </summary>
public bool IsReusable
{
get
{
return true;
}
}
}
Maybe it will help if i just put up the code for creating the SharpMap.Map:
public static Map SqlServer(string conn, List<VectorLayerModel> layers, Size map_size, Envelope bbox, string id_column = "ID")
{
Map map = new Map(map_size);
foreach (var layer in layers)
{
VectorLayer lyr = CreateSqlServerLayer(conn, layer.Table, layer.Style, id_column);
lyr.IsQueryEnabled = true;
lyr.Enabled = true;
if (bbox != null)
{
var geometries = lyr.DataSource.GetGeometriesInView(bbox);
lyr.DataSource = new GeometryFeatureProvider(geometries);
}
map.Layers.Add(lyr);
}
return map;
}
After some debugging i found out that my
GetBoundingBoxInLatLngWithMargin(int tileX, int tileY, int zoom)
was returning bounds that was way out of my data bounds. I realized i was applying a coordinate transformation to my bbox giving me a bbox in pseudo mercator yet my layer is in wgs84. I changed the GetBoundingBoxInLatLngWithMargin to:
//code omited
Envelope bbox = new Envelope();
bbox.ExpandToInclude(ll1.X, ll1.Y );
bbox.ExpandToInclude(ll2.X, ll2.Y);
return bbox;
Please find the full conversation on GitHub

How to get the My Documents folder paths from all users of a machine

I am looking for a way to get the paths of the My Documents folders from all users (each user) of a local machine.
I found several articles, but they show how to do this for the current user.
I tested the code below, using SHGetKnownFolderPath, but it works only for the logged user. In the class ctor that receives a WindowsIdentity object, I create it with tokens of other users, but the paths returned were of the logged-in user.
Does anyone know how I could get the folders paths?
Thanks.
using Syroot.Windows.IO;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace ConsoleApplication2
{
class Program
{
private static Dictionary<KnownFolderType, KnownFolder> _knownFolderInstances;
static void Main(string[] args)
{
KnownFolderType type = KnownFolderType.Documents;
KnownFolder knownFolder = new KnownFolder(type);
//Ctor with WindowsIdentity parameter
//public KnownFolder(KnownFolderType type, WindowsIdentity identity)
//{
// Type = type;
// Identity = identity;
//}
// Write down the current and default path.
Console.WriteLine(knownFolder.Type.ToString());
try
{
Console.Write("Current Path: ");
Console.WriteLine(knownFolder.Path);
Console.Write("Default Path: ");
Console.WriteLine(knownFolder.DefaultPath);
}
catch (ExternalException ex)
{
// While uncommon with personal folders, other KnownFolders don't exist on every system, and trying
// to query those returns an error which we catch here.
Console.WriteLine("<Exception> " + ex.ErrorCode);
}
Console.ReadLine();
}
private static KnownFolder GetInstance(KnownFolderType type)
{
// Check if the caching directory exists yet.
if (_knownFolderInstances == null)
{
_knownFolderInstances = new Dictionary<KnownFolderType, KnownFolder>();
}
// Get a KnownFolder instance out of the cache dictionary or create it when not cached yet.
KnownFolder knownFolder;
if (!_knownFolderInstances.TryGetValue(type, out knownFolder))
{
knownFolder = new KnownFolder(type);
_knownFolderInstances.Add(type, knownFolder);
}
return knownFolder;
}
/// <summary>
/// The per-user Documents folder.
/// Defaults to "%USERPROFILE%\Documents".
/// </summary>
public static KnownFolder Documents
{
get { return GetInstance(KnownFolderType.Documents); }
}
}
}
KnownFolder.cs
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
namespace Syroot.Windows.IO
{
/// <summary>
/// Represents a special Windows directory and provides methods to retrieve information about it.
/// </summary>
public sealed class KnownFolder
{
// ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
/// <summary>
/// Initializes a new instance of the <see cref="KnownFolder"/> class for the folder of the given type. It
/// provides the values for the current user.
/// </summary>
/// <param name="type">The <see cref="KnownFolderType"/> of the known folder to represent.</param>
public KnownFolder(KnownFolderType type)
: this(type, WindowsIdentity.GetCurrent())
{
}
/// <summary>
/// Initializes a new instance of the <see cref="KnownFolder"/> class for the folder of the given type. It
/// provides the values for the given impersonated user.
/// </summary>
/// <param name="type">The <see cref="KnownFolderType"/> of the known folder to represent.</param>
/// <param name="identity">The <see cref="WindowsIdentity"/> of the impersonated user which values will be
/// provided.</param>
public KnownFolder(KnownFolderType type, WindowsIdentity identity)
{
Type = type;
Identity = identity;
}
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
/// <summary>
/// Gets the type of the known folder which is represented.
/// </summary>
public KnownFolderType Type
{
get;
private set;
}
/// <summary>
/// Gets the <see cref="WindowsIdentity"/> of the user whose folder values are provided.
/// </summary>
public WindowsIdentity Identity
{
get;
private set;
}
/// <summary>
/// Gets or sets the default path of the folder.
/// This does not require the folder to be existent.
/// </summary>
/// <exception cref="ExternalException">The known folder could not be retrieved.</exception>
public string DefaultPath
{
get
{
return GetPath(KnownFolderFlags.DontVerify | KnownFolderFlags.DefaultPath);
}
set
{
}
}
/// <summary>
/// Gets or sets the path as currently configured.
/// This does not require the folder to be existent.
/// </summary>
/// <exception cref="ExternalException">The known folder could not be retrieved.</exception>
public string Path
{
get
{
return GetPath(KnownFolderFlags.DontVerify);
}
set
{
SetPath(KnownFolderFlags.None, value);
}
}
/// <summary>
/// Gets or sets the path as currently configured, with all environment variables expanded.
/// This does not require the folder to be existent.
/// </summary>
/// <exception cref="ExternalException">The known folder could not be retrieved.</exception>
public string ExpandedPath
{
get
{
return GetPath(KnownFolderFlags.DontVerify | KnownFolderFlags.NoAlias);
}
set
{
SetPath(KnownFolderFlags.DontUnexpand, value);
}
}
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
/// <summary>
/// Creates the folder using its Desktop.ini settings.
/// </summary>
/// <exception cref="ExternalException">The known folder could not be retrieved.</exception>
public void Create()
{
GetPath(KnownFolderFlags.Init | KnownFolderFlags.Create);
}
// ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
private string GetPath(KnownFolderFlags flags)
{
IntPtr outPath;
int result = SHGetKnownFolderPath(Type.GetGuid(), (uint)flags, Identity.Token, out outPath);
if (result >= 0)
{
return Marshal.PtrToStringUni(outPath);
}
else
{
throw new ExternalException("Cannot get the known folder path. It may not be available on this system.",
result);
}
}
private void SetPath(KnownFolderFlags flags, string path)
{
int result = SHSetKnownFolderPath(Type.GetGuid(), (uint)flags, Identity.Token, path);
if (result < 0)
{
throw new ExternalException("Cannot set the known folder path. It may not be available on this system.",
result);
}
}
/// <summary>
/// Retrieves the full path of a known folder identified by the folder's known folder ID.
/// </summary>
/// <param name="rfid">A known folder ID that identifies the folder.</param>
/// <param name="dwFlags">Flags that specify special retrieval options. This value can be 0; otherwise, one or
/// more of the <see cref="KnownFolderFlags"/> values.</param>
/// <param name="hToken">An access token that represents a particular user. If this parameter is NULL, which is
/// the most common usage, the function requests the known folder for the current user. Assigning a value of -1
/// indicates the Default User. The default user profile is duplicated when any new user account is created.
/// Note that access to the Default User folders requires administrator privileges.</param>
/// <param name="ppszPath">When this method returns, contains the address of a string that specifies the path of
/// the known folder. The returned path does not include a trailing backslash.</param>
/// <returns>Returns S_OK if successful, or an error value otherwise.</returns>
/// <msdn-id>bb762188</msdn-id>
[DllImport("Shell32.dll")]
private static extern int SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)]Guid rfid, uint dwFlags,
IntPtr hToken, out IntPtr ppszPath);
/// <summary>
/// Redirects a known folder to a new location.
/// </summary>
/// <param name="rfid">A <see cref="Guid"/> that identifies the known folder.</param>
/// <param name="dwFlags">Either 0 or <see cref="KnownFolderFlags.DontUnexpand"/>.</param>
/// <param name="hToken"></param>
/// <param name="pszPath"></param>
/// <returns></returns>
/// <msdn-id>bb762249</msdn-id>
[DllImport("Shell32.dll")]
private static extern int SHSetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)]Guid rfid, uint dwFlags,
IntPtr hToken, [MarshalAs(UnmanagedType.LPWStr)]string pszPath);
// ---- ENUMERATIONS -------------------------------------------------------------------------------------------
/// <summary>
/// Represents the retrieval options for known folders.
/// </summary>
/// <msdn-id>dd378447</msdn-id>
[Flags]
private enum KnownFolderFlags : uint
{
None = 0x00000000,
SimpleIDList = 0x00000100,
NotParentRelative = 0x00000200,
DefaultPath = 0x00000400,
Init = 0x00000800,
NoAlias = 0x00001000,
DontUnexpand = 0x00002000,
DontVerify = 0x00004000,
Create = 0x00008000,
NoAppcontainerRedirection = 0x00010000,
AliasOnly = 0x80000000
}
}
}
I figured it out.
I got all SIDs from the system and then searched the Windows registry for each SID by the "Personal" key in the following format: "HKEY_USERS" + "SID" + "\ Software \ Microsoft \ Windows \ CurrentVersion \ Explorer \ Shell Folders \ Personal ".
The "Personal" key retains the current path of each user's "My Documents" folder.
Get SIDs:
public static List<string> GetMachineSids()
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_UserProfile");
var regs = searcher.Get();
string sid;
List<string> sids = new List<string>();
foreach (ManagementObject os in regs)
{
if (os["SID"] != null)
{
sid = os["SID"].ToString();
sids.Add(sid);
}
}
searcher.Dispose();
return sids.Count > 0 ? sids : null;
}
Get MyDocuments Path:
public static List<string> GetMyDocumentsPathAllUsers()
{
const string parcialSubkey = #"\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders";
string subkey = string.Empty;
const string keyName = "Personal";
//get sids
List<string> sids = GetMachineSids();
List<string> myDocumentsPaths = new List<string>();
if (sids != null)
{
foreach (var sid in sids)
{
//get paths
subkey = sid + parcialSubkey;
using (RegistryKey key = Registry.Users.OpenSubKey(subkey))
{
if (key != null)
{
Object o = key.GetValue(keyName);
if (o != null)
{
myDocumentsPaths.Add(o.ToString());
}
}
}
}
}
return myDocumentsPaths.Count > 0 ? myDocumentsPaths : null;
}

Understanding Serialization

Context
I'm trying to understand how to use Serialization, never used it previously.
Right now I have a populate method in my singleton object (Main class) that basically adds a few member objects to a list of members using my addMember methods
I want to serialize this Members List Once I can serialize and deserialize the list I can delete my populate method.
Questions
HOW do I serialize this list so that the members list is deserialized upon startup?
WHERE do I serialize specifically? Do I serialize when I'm creating a new member, or do I just serialize the list at shutdown and deserialize at startup.
Since member information can be edited, how do I serialize the updates and overwrite the previously held data?
Code Listings
I'm kinda new to Serialization, but here's my code, I'm using a method for this because I I think it's cleaner this way, using ISerializable in my main class. Here's a few snippets from my main class, keep in mind I have tons of comments in my code, that's kinda why I didn't post this previously:
namespace HillRacingGraded
{
[Serializable]
public class HillRacing : ISerializable
{
/// <summary>
/// Singleton object hillracing
/// </summary>
private static HillRacing hillracing;
GUIUtility gui = new GUIUtility();
/// <summary>
/// Instance property returns the singleton instance
/// </summary>
public static HillRacing Instance
{
get
{
if (hillracing == null)
hillracing = new HillRacing();
return hillracing;
}
}
/// <summary>
/// public Property that returns races list, can be accessed by other classes.
/// </summary>
public List<BaseRace> Races
{
get
{
return races;
}
set
{
races = value;
}
}
/// <summary>
/// public Property that returns members list, can be accessed by other classes.
/// </summary>
public List<BaseMember> Members
{
get
{
return members;
}
set
{
members = value;
}
}
/// <summary>
/// instantiate the list of members
/// </summary>
private List<BaseMember> members; //I WANT TO SERIALIZE THIS
/// <summary>
/// instantiate the list of races
/// </summary>
private List<BaseRace> races; //I WANT TO SERIALIZE THIS
/// <summary>
/// Default constructor for hillracing.
/// </summary>
public HillRacing()
{
//members is a new list of the BaseMember objects.
//races is a new list of the BaseRace objects.
members = new List<BaseMember>();
races = new List<BaseRace>();
//call the populate method on launch, mostly for testing purposes.
Populate();
}
/// <summary>
/// Hillracing constructor for serialization
/// </summary>
/// <param name="info"></param>
/// <param name="ctxt"></param>
public HillRacing(SerializationInfo info, StreamingContext ctxt)
{
this.members = (List<BaseMember>)info.GetValue("Members", typeof(List<BaseMember>));
this.races = (List<BaseRace>)info.GetValue("Races", typeof(List<BaseRace>));
}
/// <summary>
/// get object data
/// </summary>
/// <param name="info"></param>
/// <param name="ctxt"></param>
public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
{
info.AddValue("Members", this.members);
}
/// <summary>
/// Adds a new junior member to the list of all members.
/// </summary>
/// <param name="stringfirstname">first name of the member</param>
/// <param name="stringlastname">last name of the member</param>
/// <param name="stringmiddlename">middle name of the member</param>
/// <param name="stringtitle">title of the member</param>
/// <param name="strst">street of the member</param>
/// <param name="strtwn">Town of the member</param>
/// <param name="strpc">Postcode of the member</param>
/// <param name="strEmail">email of the member</param>
/// <param name="intMobile">Mobile of the member</param>
/// <param name="intHome">Home phone of the member</param>
/// <param name="shrnumber">ID number of the member</param>
/// <param name="memtype">Type of the member</param>
/// <param name="username">username of the member</param>
/// <param name="noracesrun">number of races that the member has run</param>
/// <param name="perraceswon">percentage of races that the member has won</param>
/// <param name="mempic">image of the member</param>
/// <param name="memclub">the club the member is part of</param>
/// <param name="gender">the gender of the member</param>
/// <param name="memexp">the experience level the member has</param>
/// <param name="yearofbirth">the year of birth the member was born in</param>
/// <param name="monthofbirth">the month of birth the member was born in</param>
/// <param name="dayofbirth">the day of birth the member was born on</param>
public void addJunior(string stringfirstname, string stringlastname, string stringmiddlename, string stringtitle, string strst, string strtwn, string strpc, string strEmail, int intMobile, int intHome,
string shrnumber, string memtype, string username, string password, int noracesrun, float perraceswon, string mempic, string memclub, string gender, int memexp, int yearofbirth, int monthofbirth, int dayofbirth, string nextofkin, string docName, string docTel, string healthIssues, string parentalConsent)
{
// create a new member with the entered parameters to add to the list.
JuniorMember newMember = new JuniorMember(stringfirstname, stringlastname, stringmiddlename, stringtitle, strst, strtwn, strpc, strEmail, intMobile, intHome, shrnumber, memtype, username, password, noracesrun, perraceswon, mempic, memclub, gender, memexp, yearofbirth, monthofbirth, dayofbirth,nextofkin,docName,docTel,healthIssues,parentalConsent);
//use add functionality of list to add to the list.
members.Add(newMember);
}
/// <summary>
///
/// </summary>
/// <param name="stringfirstname">first name of the member</param>
/// <param name="stringlastname">last name of the member</param>
/// <param name="stringmiddlename">middle name of the member</param>
/// <param name="stringtitle">title of the member</param>
/// <param name="strst">street of the member</param>
/// <param name="strtwn">Town of the member</param>
/// <param name="strpc">Postcode of the member</param>
/// <param name="strEmail">email of the member</param>
/// <param name="intMobile">Mobile of the member</param>
/// <param name="intHome">Home phone of the member</param>
/// <param name="shrnumber">ID number of the member</param>
/// <param name="memtype">Type of the member</param>
/// <param name="username">username of the member</param>
/// <param name="noracesrun">number of races that the member has run</param>
/// <param name="perraceswon">percentage of races that the member has won</param>
/// <param name="mempic">image of the member</param>
/// <param name="memclub">the club the member is part of</param>
/// <param name="gender">the gender of the member</param>
/// <param name="memexp">the experience level the member has</param>
/// <param name="yearofbirth">the year of birth the member was born in</param>
/// <param name="monthofbirth">the month of birth the member was born in</param>
/// <param name="dayofbirth">the day of birth the member was born on</param>
/// <param name="nextofkin">The next family member contact</param>
/// <param name="docName">The name of the members doctor</param>
/// <param name="docTel">A telephone number for the doctor</param>
/// <param name="healthIssues">the health issues this member has.</param>
public void addSenior(string stringfirstname, string stringlastname, string stringmiddlename, string stringtitle, string strst, string strtwn, string strpc, string strEmail, int intMobile, int intHome,
string shrnumber, string memtype, string username, string password, int noracesrun, float perraceswon, string mempic, string memclub, string gender, int memexp, int yearofbirth, int monthofbirth, int dayofbirth, string nextofkin, string docName, string docTel, string healthIssues)
{
//create a new member with the entered parameters to add to the list.
SeniorMember newMember = new SeniorMember(stringfirstname, stringlastname, stringmiddlename, stringtitle, strst, strtwn, strpc, strEmail, intMobile, intHome, shrnumber, memtype, username, password, noracesrun, perraceswon, mempic, memclub, gender, memexp, yearofbirth, monthofbirth, dayofbirth,docName,docTel,healthIssues);
//use standard list functionality of list to add this new member to the list.
members.Add(newMember);
}
Here is my Serialization method in the Serializer class:
public void SerializeObject(string filename, object objectToSerialize)
{
Stream stream = File.Open(filename + ".bin", FileMode.Create);
BinaryFormatter bFormatter = new BinaryFormatter();
bFormatter.Serialize(stream, objectToSerialize);
stream.Close();
}
Problem is, I don't know how to actually use this.
Also have a deserializer:
public HillRacing DeSerializeObject(string filename)
{
HillRacing hillracing;
Stream stream = File.Open(filename + ".bin", FileMode.Open);
BinaryFormatter bFormatter = new BinaryFormatter();
hillracing = (HillRacing)bFormatter.Deserialize(stream);
stream.Close();
return hillracing;
}
Although you have done most of the part i suggest a little generics make it multiuse as
public static class StreamUtilities
{
public static T GetObject<T>(Byte[] rawimage) where T : class
{
try
{
MemoryStream memStream = new MemoryStream();
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(rawimage, 0, rawimage.Length);
memStream.Seek(0, SeekOrigin.Begin);
return binForm.Deserialize(memStream) as T;
}
catch (Exception ex)
{
return null;
}
}
public static Byte[] Serialize<T>(this T obj) where T:class
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
return ms.ToArray();
}
}
then in your main class or whereever you want it to use include to namespace where the above extention method is then use
Object1 a=new Object1();// any serializable object
serializedbytes=a.Serialize<Object1>();
//deserialize
Object b=StreamUtilities.GetObject<Object1>(serializedbytes);
The above extention method will allow to seriailize/Deserialize any serializable Object.

Get all Shapes with Charts from a Slide

I am working with a Powerpoint slide and try to extract the names of all shapes with charts from the slide. I can find out if the Slide has charts at all, but I am stuck as to how to find the correspondending Slide.
code:
// suppose that a presentation is correctly loaded
private List<PPChart> GetChartsfromSlide(SlidePart slidepart)
{
var chartList = new List<PPChart>();
if (slidepart.ChartParts.Any())
{
foreach (var chart in slidepart.ChartParts)
{
// how to get the ID of the Chart and get the corespondending slide?
}
}
return chartList;
}
I found a solution, but the Solution is rather involved:
Hopefully, it helps somebody in the future...
/// <summary>
/// Gets a List of all Charts on this Slide
/// </summary>
/// <param name="slidepart">The SlidePart.</param>
/// <returns>A List of all Charts on this Slide</returns>
private List<PPChart> GetChartsfromSlide(SlidePart slidepart)
{
var chartList = new List<PPChart>();
if (slidepart.ChartParts.Any())
{
foreach (var chart in slidepart.ChartParts)
{
//// get the ID of the Chart-Part
var id = slidepart.GetIdOfPart(chart);
//// Get a list of all Shapes(Graphicframes) which contain Charts
var gshapes = from shapeDesc in slidepart.Slide.Descendants<GraphicFrame>() select shapeDesc;
var tempgshapes = gshapes.ToList();
//// Select all possible Shapes which have Graphics
var thisShape = from Gshape in tempgshapes where this.HasThisChart(id, Gshape) select Gshape;
var result = thisShape.ToList();
this.logger.Debug("Found Chart with ID:{0} Name:{1}", result[0].NonVisualGraphicFrameProperties.NonVisualDrawingProperties.Id, result[0].NonVisualGraphicFrameProperties.NonVisualDrawingProperties.Name);
var ppchart = new PPChart(result[0].NonVisualGraphicFrameProperties.NonVisualDrawingProperties.Id);
ppchart.ShapeName = result[0].NonVisualGraphicFrameProperties.NonVisualDrawingProperties.Name;
chartList.Add(ppchart);
}
}
return chartList;
}
/// <summary>
/// Determines whether the Slider has this Chart or not.
/// </summary>
/// <param name="id">The id.</param>
/// <param name="gframe">The gframe.</param>
/// <returns>
/// <c>true</c> if the Slide has the chart; otherwise, <c>false</c>.
/// </returns>
private bool HasThisChart(string id, GraphicFrame gframe)
{
var returnValue = false;
if (!(gframe == null) && this.HasGraphic(gframe))
{
if (!(gframe.Graphic.GraphicData == null))
{
var graphicData = gframe.Graphic.GraphicData;
var drawChartsRef = graphicData.Descendants<DrawCharts.ChartReference>();
if (!(drawChartsRef == null))
{
foreach (var drawChart in drawChartsRef)
{
if (drawChart.Id == id)
{
returnValue = true;
}
}
}
}
}
return returnValue;
}
/// <summary>
/// Determines whether the specified GraphicFrame has a graphic (A graphic is a chart!).
/// </summary>
/// <param name="gframe">The gframe.</param>
/// <returns>
/// <c>true</c> if the specified gframe has a graphic; otherwise, <c>false</c>.
/// </returns>
private bool HasGraphic(GraphicFrame gframe)
{
var returnValue = false;
if (!(gframe == null))
{
var graphicDescendants = gframe.Descendants<Draw.Graphic>();
if (graphicDescendants.Count() > 0)
{
returnValue = true;
}
}
return returnValue;
}

Categories

Resources