Create Windows Service that will just write to log In Visual Studio 2010, create new project, Windows group, Windows service
in Service1.cs, OnStart(string[] args) {...} add an action that the service will start. The method has to return in 30 seconds.

Debug.Listeners.Add(new TextWriterTraceListener(System.IO.File.Create(@"c:\_delete\trace.txt")));
Trace.AutoFlush = true;
Trace.WriteLine("starting");



Similar way implement OnStop(), OnShutdown)(), OnPause(), OnContinue()

Add installer:
 in Solution explorer, Doubleclick on Service1.cs
 in Service1 designer, right click and select "Add Installer"
 doubleclick on ProjectInstaller.cs
 Right click on serviceInstaller1, select Properties, set Service Name = "MyService", Start Type="Automatic" if you want to service to start automatically
 Right click on serviceProcessInstaller1, select Properties, set Account = "LocalSystem" in order to avoid entering user name and password

Install:
 InstallUtil.exe WindowsServiceBasics.exe

Start:
 in start menu type "services.msc", find MyService, right click Start

Note: you do not have to install the service again when you recompile the binary.

Unistall:
InstallUtil.exe /u WindowsServiceBasics.exe
Note: You need to close the management console window (service is marked for deletion)

Debugging:
Start the service (see above)
From Visual Studio (running as Administrator), menu Debug, Attach to process
Click "Show processes from all users"
Select process that belongs to the service, click Attach

More info and samples on: www.devarchweb.net

How to specify credentials for Windows service 1. Programatically:
Right click on serviceProcessInstaller1, select Properties, set Account = "myAccount"

// ProjectInstaller.Designer.cs
private void InitializeComponents() {
 ...
 this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
 this.serviceProcessInstaller1.Password = null;
 this.serviceProcessInstaller1.Username = null;
 ...
}



2. Configuration
services.msc
right click on the service
tab LogOn, enter user and password

More info and samples on: www.devarchweb.net

Write a code that populates common members of PersonLite and Person (inherits from PersonLite) classes using generics

private class PersonLite
{
  internal int Id;
  internal string Name;
}

private class Person : PersonLite
{
  internal DateTime BirthDay;
}

internal static void ShowBasics()
{
  PersonLite personLite = new PersonLite();
  Populate(personLite);

  Person person = new Person();
  Populate(person);
  person.BirthDay = DateTime.Parse("1969-01-01");
}

private static void Populate<T>(T p) where T : PersonLite
{
  // read data from external source, e.g. DB
  p.Id = 1;
  p.Name = "John";
}


More info and samples on: www.devarchweb.net

Create a generic method that returns new object of type T

private class PersonLite
{
  internal int Id;
  internal string Name;
}

private class Person : PersonLite
{
  internal DateTime BirthDay;
}

internal static void DemoCreateNewObject()
{
  PersonLite personLite = CreateNew<PersonLite>();
  Person person = CreateNew<Person>();
}

private static T CreateNew<T>() where T : PersonLite, new()
{
  T result = new T();
  result.Name = "new";
  return result;
}


More info and samples on: www.devarchweb.net

Create list based on generic type (Person or PersonLite) passed in

private class PersonLite
{
  internal int Id;
  internal string Name;
}

private class Person : PersonLite
{
  internal DateTime BirthDay;
}

internal static void DemoLoadDataBasedOnType()
{
  List<PersonLite> list = CreateList<PersonLite>();
  List<Person> list2 = CreateList<Person>();
}

private static List<T> CreateList<T>() where T : PersonLite, new() // new() is needed New<T>()
{
  List<T> result = new List<T>();
  Type t = typeof(T);

  int count = 1;
  switch (t.Name)
  {
    // this can be used to generate a SQL query
    case "PersonLite": count = 2; break;
    case "Person": count = 3; break;
  }

  for (int i = 0; i < count; i++)
  {
    T item = new T();
    item.Name = "new";
    result.Add(item);
  }
  return result;
}


More info and samples on: www.devarchweb.net

Explain dynamic If an object is defined as dynammic, it bypasses static type checks at compile time

DateTime date = new DateTime();
// date.AddCentury(1); fails at compile time

dynamic dateDynamic = new DateTime();
dateDynamic.AddCentury(1); // fails at runtime

var obj = date as dynamic;
obj.AddCentury(); // fails at runtime


More info and samples on: www.devarchweb.net

Convert Enum to string and back

public enum Department
{
 IT,
 Finance
}

string text = Enum.GetName(IT.GetType(), IT);

Department d = (Department) Enum.Parse(typeof(Department), "IT");


More info and samples on: www.devarchweb.net

What are immutable classes, what is the problem, how could it be prevented? http://tipsandtricks.runicsoft.com/CSharp/Immutables.html

Immutable types are reference types with value type semantics.
Problem: when a class is passed as an argument to a method, it content can be unexpectedly modified.
How to prevent that: Classes can be ensured to be immutable by using readonly keyword for their members.

More info and samples on: www.devarchweb.net

How to identify assembly architecture corflags myassembly.exe

Any CPU: PE = PE32 and 32BIT = 0
x86:   PE = PE32 and 32BIT = 1
64-bit: PE = PE32+ and 32BIT = 0

More info and samples on: www.devarchweb.net

What is mixed mode assembly Source MSDN: Mixed assemblies are capable of containing both unmanaged machine instructions and MSIL instructions. This allows them to call and be called by .NET components, while retaining compatibility with components that are entirely unmanaged. Using mixed assemblies, developers can author applications using a mixture of managed and unmanaged functionality. This makes mixed assemblies ideal for migrating existing Visual C++ applications to the .NET Platform.

An existing application consisting entirely of unmanaged functions can be brought to the .NET platform by recompiling just one module with the /clr compiler switch

More info and samples on: www.devarchweb.net

How list and array get placed in LOH List is implented using an array and when new item is added, a new and larger array is allocated
and the old one is released. List reaches 85k with about 20.000 items.

Arrays with 10,000 or more end up on LOH.

More info and samples on: www.devarchweb.net

Type of GC roots Local variables: are kept alive as long as the method is on call stack (in Release build, JIT can unmark it before the method exits)

Static variables: always considered GC roots

Managed object passed to COM+ through interop: Ends when COM reference counter is set to 0.

Object with finalizer: If it is no longer live, it becomes special kind of GC root until .net called the finalizer (placed in finalizer queue).
Require more than one collection GC. Object with finalizers cause delay to be released from memory, use Dispose() whenever possible and GC.SuppressFinalize().

More info and samples on: www.devarchweb.net

Type of memory leaks and how to solve them Holding references to managed objects (e.g. event handlers):
Solution:
- use local rather than global variable
- call Dispose() or use "using(...){ }" concept
- set variable to null when it not needed anymore

Failing to release unmanaged resources
- practises of deallocating unmanaged code apply

Failing to dispose Drawing objects
e.g Bitmaps, brushes, fonts - these are managed objects, but they hold references to unmanaged objects.
These resources are cleaned up when the objects are disposed

Solving LOH fragmentation:
- Split list or arrays into smaller objects that remain below 85kB
- allocate the largest and longest-living objects first
- let GC compact the LOH (.net > 4.5.1). If GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce
the LOH is compacted during the next full blocking garbage collection, and the property value is reset to default.
- restart program

Generally: do no rely on finalization. 1. It happens unpredictably and may take long time,
2. Finalizer of certain object may not call Dispose() (if it has a bug)

More info and samples on: www.devarchweb.net

Available memory resources per 32 and 64 bit systems On 32 bit system a program can use up to 1.5G memory
64 system can page out memory, which decreases performance, and event run out disk space.

More info and samples on: www.devarchweb.net

GC modes Concurent (desktop apps): GC will not stop the app, the app will just slow.
Server (ASP.net apps): NET will suspend the running application while the garbage collector is running.

More info and samples on: www.devarchweb.net

Impact of using GC.Collect() Using GC.Collect() will cause newly created objects released later (moved to Gen 2) which increases the likelihood of another expensive full collection in the near future.

More info and samples on: www.devarchweb.net

Example of extension method that adds a method with new name and extends method with the same name

sealed class SealedClass
{
  internal void DoSomething()
  {
    Console.WriteLine("SealedClass.DoSomething()");
  }

  // cannot be called from extension method
  protected void DoSomethingProtected()
  {
    Console.WriteLine("SealedClass.DoSomethingProtected()");
  }

  internal static void DoSomethingStatic()
  {
    Console.WriteLine("SealedClass.DoSomethingStatic()");
  }
}

static class ExtensionClass
{
  internal static void DoSomething(this SealedClass sealedClass)
  {
    Console.WriteLine("Gets never called");
  }

  internal static void DoSomething(this SealedClass sealedClass, int i)
  {
    sealedClass.DoSomething(); // class method can be called

    // sealedClass.DoSomethingProtected(); not available
    Console.WriteLine("ExtensionClass.DoSomething(int i)");
  }

  internal static void DoSomethingElse(this SealedClass sealedClass)
  {
    Console.WriteLine("ExtensionClass.DoSomethingElse()");
  }

  internal static void DoSomethingStatic(this SealedClass sealedClass)
  {
    Console.WriteLine("Gets never called");
  }
}

class ExtensionMethodsDemo
{
  internal static void DemoExtensionMethods()
  {
    SealedClass sealedClass = new SealedClass();

    sealedClass.DoSomething(); // calls SealedClass
    sealedClass.DoSomething(1); // calls ExtensionClass
    sealedClass.DoSomethingElse(); // calls ExtensionClass
    SealedClass.DoSomethingStatic(); // calls SealedClass
  }
}


More info and samples on: www.devarchweb.net

Write tracing information to log file, console and event log

// trace to a text file
TextWriterTraceListener textWriterTraceListener = new TextWriterTraceListener(LOG_FILE_NAME);
textWriterTraceListener.TraceOutputOptions = TraceOptions.DateTime | TraceOptions.ProcessId | TraceOptions.ThreadId;
Trace.Listeners.Add(textWriterTraceListener);

// trace to the console
Trace.Listeners.Add(new ConsoleTraceListener());

// trace to event log
// !! this code must be executed als administrator when the source Basics.exe does not exist

ventLogTraceListener eventLogTraceListener = new EventLogTraceListener("Basics.exe");

Trace.WriteLine("Written by Trace.WriteLine()");
Trace.Flush();

Trace.AutoFlush = true;
Trace.TraceInformation("Written by Trace.TraceInformation");  // writes datetime + process id + thread id
Trace.TraceWarning("Written by Trace.TraceWarning");
Trace.TraceError("Written by Trace.TraceError");


More info and samples on: www.devarchweb.net

Create TextWriterTraceListener in app.config

<configuration>
 <system.diagnostics>
  <trace autoflush="true">
   <listeners>
    <remove name="Default"/>
    <add name="textWriterTraceListenerConfig"
      type="System.Diagnostics.TextWriterTraceListener"
      traceOutputOptions="DateTime,Timestamp,Callstack,LogicalOperationStack,ProcessId,ThreadId"
      initializeData="MyLogFromConfig.log">
    </add>
   </listeners>
  </trace>
 </system.diagnostics>
</configuration>


More info and samples on: www.devarchweb.net

Create a trace listener with filter

TextWriterTraceListener textWriterTraceListener = new TextWriterTraceListener(LOG_FILE_NAME);

EventTypeFilter e = new EventTypeFilter(SourceLevels.Error); // .Error: Verbose, Information, Warning are ignored
textWriterTraceListener.Filter = e;

Trace.Listeners.Add(textWriterTraceListener);
Trace.TraceWarning("DemoEventTraceWithFilter - Trace warning"); // will be ignored (by filter)
Trace.TraceError("DemoEventTraceWithFilter - Trace error");   // will be written


This can be also done in app.config

<add name="textWriterTraceListenerConfig"
  type="System.Diagnostics.TextWriterTraceListener"
  initializeData="MyLogFromConfig.log">
 <filter type="System.Diagnostics.EventTypeFilter" initializeData="Warning"/>
</add>


More info and samples on: www.devarchweb.net

TraceSwitch to filter messages

TraceSwitch traceSwitch = new TraceSwitch("textWriterTraceListener", "description" );
traceSwitch.Level = TraceLevel.Warning;

// Off 0, Error 1, Warning 2 default, Info 3, Verbose 4

TextWriterTraceListener textWriterTraceListener = new TextWriterTraceListener(LOG_FILE_NAME);
Trace.Listeners.Add(textWriterTraceListener);

Trace.WriteLine("switch controlled - no IF");
Trace.WriteLineIf(traceSwitch.TraceVerbose, "switch controlled verbose"); // will be ignored
Trace.WriteLineIf(traceSwitch.TraceError, "switch controlled error");
Trace.Flush();


or in app.config

 <system.diagnostics>
  <switches>
   <add name="textWriterTraceListener" value="3"/>
  </switches>
  ...


More info and samples on: www.devarchweb.net

Write to Event Log

string myAppName = "Basics3.exe"; // event source name must be unique accross all logs

// Write to application log

EventLog eventLog = new EventLog("Application", Environment.MachineName, myAppName);
EventLog.WriteEntry(myAppName, "Demo error", EventLogEntryType.Error); // !! this code must be executed als administrator when the source does not exist

// Write to custom log
EventLog customEventLog = new EventLog("ZbynekDemo1", Environment.MachineName, myAppName + "Custom");
customEventLog.WriteEntry("Demo error", EventLogEntryType.Error); // first time you have to close and open Event Viewer to see the new custom event log


More info and samples on: www.devarchweb.net

How to enable and create and configure console logger in Log4net Install log4net NuGet package (log4net.dll will be added to project references)

using log4net;
using log4net.Config;

namespace Log4NetBasics
{
  class Program
  {
    private static readonly ILog _logger = LogManager.GetLogger("MyLogger");

    static void Main(string[] args)
    {
      XmlConfigurator.Configure(); // read the configuration from app.config
      // BasicConfigurator.Configure(); // ! does not read configuration for File or Debug appenders

      _logger.Info("Info message");
      _logger.Warn("Warning message");
      _logger.Error("Error message");

      Console.ReadLine();
    }
  }
}



<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 <configSections>
  <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
 </configSections>

 <log4net>
  <appender name="Console" type="log4net.Appender.ColoredConsoleAppender">
   <layout type="log4net.Layout.PatternLayout">
   </layout>
  </appender>

  <root>
   <level value="ALL"/>
   <appender-ref ref="Console"/>
  </root>
 </log4net>

</configuration>


More info and samples on: www.devarchweb.net

How to format message for log4net and include own property

<log4net>
<appender name="Console" type="log4net.Appender.ColoredConsoleAppender">
 <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%thread] %-5level %logger %property{myData} (%file:%line): %message %newline"/>
 </layout>
</appender>

...

</log4net>



will produce:

2016-05-22 11:00:05,887 [10] ERROR MyLogger Abc (c:\Log4NetBasics\Program.cs:18): Error message


%property{myData} will pint out content set as below

GlobalContext.Properties["myData"] = "abc";


More info and samples on: www.devarchweb.net

How to define color for messages for og4net

<log4net>
<appender name="Console" type="log4net.Appender.ColoredConsoleAppender">
<mapping>
<level value="ERROR"/>
<foreColor value="Red"/>
</mapping>
...
</appender>
...
</log4net>


More info and samples on: www.devarchweb.net

Using file and debug appenders in Log4net Adding another listeners, called appenders, can be done the same way in app.config

<log4net>
  <appender name="File" type="log4net.Appender.RollingFileAppender">
   <param name="File" value="c:\\temp\\log4netBasics.log"/>
   <param name="AppendToFile" value="true"/>
   <maximumFileSize value="100KB" />
   <maxSizeRollBackups value="2" />

   <layout type="log4net.Layout.PatternLayout"></layout>
  </appender>

  <appender name="DebuggerAppender" type="log4net.Appender.DebugAppender">
   <layout type="log4net.Layout.PatternLayout">
   </layout>
  </appender>

...

</log4net>


More info and samples on: www.devarchweb.net

How to output current class and method (for logging)

private static void Log(string message)
{
var frame = new StackFrame(skipFrames: 1); // 1 will get the frame of the caller of the Log method
System.Reflection.MethodBase callingMethod = frame.GetMethod();
Console.WriteLine("Class: {0} Method: {1}", callingMethod.DeclaringType.Name, callingMethod);
}


More info and samples on: www.devarchweb.net

Configure value in default app config and read it in code app.config file contains key-vaulue pair

<configuration>
 <appSettings>
  <add key="key1" value="value1" />
 </appSettings>
</configuration>


the values can be retrieved as

string settingValue = System.Configuration.ConfigurationManager.AppSettings["key1"];


More info and samples on: www.devarchweb.net

Get and set values in default config file Configuration values in default app.config cannot be modified, because the is no setter defined

try
{
  System.Configuration.ConfigurationManager.AppSettings.Add("added", "added value");
}
catch (ConfigurationErrorsException ex)
{
  Console.WriteLine(ex);
  // "The configuration is write protected" exception. When executed from VS or Basics.exe.
}


but you can open the default app.config as a specific file and then you can modify the values.

More info and samples on: www.devarchweb.net

Get value from specific config

ExeConfigurationFileMap map = new System.Configuration.ExeConfigurationFileMap();
map.ExeConfigFilename = "app1.config"; // this can be used for Basics.exe.config or Basics.vshost.exe.config as well
Configuration mappedConfiguration = ConfigurationManager.OpenMappedExeConfiguration(map, System.Configuration.ConfigurationUserLevel.None);
AppSettingsSection appSettingsSection = (AppSettingsSection)mappedConfiguration.GetSection("appSettings");

// Get
string settings = appSettingsSection.Settings["key2"].Value;

// Add
appSettingsSection.Settings.Add("addedKey", "addedValue");
mappedConfiguration.Save();

// Remove
appSettingsSection.Settings.Remove("addedKey");
mappedConfiguration.Save();


More info and samples on: www.devarchweb.net

How to use properties for configuration Another way how to store configuration data is to use Properties.Settings class.
- The settings are stored in app.config either in userSettings or applicationSettings sections.

<configuration>
 <configSections>
  <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
   <section name="Basics.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
  </sectionGroup>
  <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
   <section name="Basics.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </sectionGroup>
 </configSections>
 <userSettings>
  <Basics.Properties.Settings>
   <setting name="MySettingForUser" serializeAs="String">
    <value>user</value>
   </setting>
  </Basics.Properties.Settings>
 </userSettings>
 <applicationSettings>
  <Basics.Properties.Settings>
   <setting name="MySettingForApp" serializeAs="String">
    <value>app</value>
   </setting>
  </Basics.Properties.Settings>
 </applicationSettings>
</configuration>



- The settings need to be created in the Settings tab in Project properties.
After the creation the Properties\Settings.settings file will be modified.

internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
 [global::System.Configuration.UserScopedSettingAttribute()]
 public string MySettingForUser {
   get {
     return ((string)(this["MySettingForUser"]));
   }
   set {
     this["MySettingForUser"] = value;
   }
 }
}


The settings can be accessed with the code below:

// get application scope setting value
string value = Properties.Settings.Default.MySettingForApp;
// Properties.Settings.Default.SettingApp = value + "x";  does not compile, SettingApp has no setter

// get and set user scope setting value
string userValue = Properties.Settings.Default.MySettingForUser;
Properties.Settings.Default.MySettingForUser = userValue + "+";
Properties.Settings.Default.Save();


More info and samples on: www.devarchweb.net

Create simple custom section in config Define class representing the section

class ConfigurationElementSimple : System.Configuration.ConfigurationSection
{
  [System.Configuration.ConfigurationProperty("myValue", IsRequired = true)]
  public string MyValue
  {
    get { return (string)base["myValue"]; }
    set { base["myValue"] = value; }
  }

  [System.Configuration.ConfigurationProperty("myNumber", IsRequired = false)]
  public int MyNumber
  {
    get { return (int)base["myNumber"]; }
    set { base["myNumber"] = value; }
  }
}


Define the section and populate its values in app.config.
configSections must be the first section in the app.config.
The same section type can be used multiple times.

<configuration>
 <configSections>
  <section name="simpleCustomSection" type="Basics.ConfigurationElementSimple, Basics"/>
  <section name="simpleCustomSection2" type="Basics.ConfigurationElementSimple, Basics"/>
 </configSections>

 <simpleCustomSection myValue="abc" myNumber="1" />
<configuration>


Read content of the section in code.

ConfigurationElementSimple config = (ConfigurationElementSimple)System.Configuration.ConfigurationManager.GetSection("simpleCustomSection");
config = (ConfigurationElementSimple)System.Configuration.ConfigurationManager.GetSection("simpleCustomSection2");


More info and samples on: www.devarchweb.net

Create complex custom section with list in config Define class representing the section including the collection with its items.
Each item in collection must be identified with unique value.

public class ConfigurationCollectionItem : ConfigurationElement
{
  [ConfigurationProperty("name", IsRequired = true, IsKey = true)]
  public string Name
  {
    get { return (string)base["name"]; }
  }

  [ConfigurationProperty("detail", IsRequired = false, IsKey = true)]
  public string Detail
  {
    get { return (string)base["detail"]; }
  }

  public string UniqueName
  {
    get { return string.Format("{0}{1}", Name, Detail); }
  }
}

public class MyConfigurationCollection : ConfigurationElementCollection
{
  public ConfigurationCollection() { }

  protected override ConfigurationElement CreateNewElement()
  {
    return new ConfigurationCollectionItem();
  }

  protected override Object GetElementKey(ConfigurationElement element)
  {
    return ((ConfigurationCollectionItem)element).UniqueName;
  }
}

public class ConfigurationElementComplex : ConfigurationSection
{
  [ConfigurationProperty("id", IsDefaultCollection = false, IsRequired = true)]
  public string Id
  {
    get { return (string)base["id"]; }
  }

  [ConfigurationProperty("myList", IsDefaultCollection = false, IsRequired = true)]
  public MyConfigurationCollection MyList
  {
    get { return (MyConfigurationCollection)base["myList"]; }
  }
}


Define the section and populate its values in app.config.
configSections must be the first section in the app.config.

<configuration>
 <configSections>
  <section name="complexCustomSection" type="Basics.ConfigurationElementComplex, Basics"/>
 </configSections>

 <complexCustomSection id="1">
  <myList>
   <add name="John" detail="abc" />
   <add name="Paul" detail="def" />
  </myList>
 </complexCustomSection>
<configuration>


Read content of the section in code

ConfigurationElementComplex config1 = (ConfigurationElementComplex)System.Configuration.ConfigurationManager.GetSection("complexCustomSection");

// string s = ((ConfigurationCollectionItem)config1.MyList[0]).Name; // access not allowed (config1.MyList[0])
foreach(var item in config1.MyList)
{
  string name = ((ConfigurationCollectionItem)item).Name;
}


More info and samples on: www.devarchweb.net

Write a value, Read a value(2 ways) in registry, Test if values exists and delete it

// create or overwrite registry value
Registry.SetValue(Registry.CurrentUser.Name + @"\Software\Zbynek Cernin\Basics", "TestValue", "abc");

// read registry value
string value = (string)Registry.GetValue(Registry.CurrentUser.Name + @"\Software\Zbynek Cernin\Basics", "TestValue", string.Empty);

// read registry value - using RegistryKey
RegistryKey basicsKey = Registry.CurrentUser.OpenSubKey(@"Software\Zbynek Cernin\Basics");
if (basicsKey != null)
{
  value = (string)basicsKey.GetValue("TestValue");
  value = (string)basicsKey.GetValue("TestValue1"); // does not exists - returns null
}

// test if values exists and delete it

basicsKey = Registry.CurrentUser.OpenSubKey(@"Software\Zbynek Cernin\Basics", writable: true);
if (basicsKey != null)
{
  if (basicsKey.GetValueNames().Where(s => s == "TestValue").Count() > 0)
  {
    basicsKey.DeleteValue("TestValue");
  }
}


More info and samples on: www.devarchweb.net

Create message queue

// this code has to run as Admin

System.Messages.MessageQueue.Create(@".\Private$\MyQueue");


More info and samples on: www.devarchweb.net

Read messages synchronously

if (MessageQueue.Exists(@".\Private$\MyQueue"))
{
  MessageQueue mq = new MessageQueue(@".\Private$\MyQueue");

  // send
  mq.Send("Hello " + DateTime.Now.ToString(), "Title");

  // receive
  Message msg = mq.Receive();
};


More info and samples on: www.devarchweb.net

Read messages asynchronously

static void WriteAndReadMessageAsynchronously()
{
  MessageQueue mq = new MessageQueue(@".\Private$\MyQueue");

  mq.Send("Hello " + DateTime.Now.ToString(), "Title");

  mq.ReceiveCompleted += new ReceiveCompletedEventHandler(MessageReceived);
  mq.BeginReceive();
}

public static void MessageReceived(object source, ReceiveCompletedEventArgs args)
{
  MessageQueue mq = (MessageQueue)source;
  Message msg = mq.EndReceive(args.AsyncResult);
  string body = (string)msg.Body;
}


More info and samples on: www.devarchweb.net

Create class instance from its name

internal class Person
{
  internal int ID;
  internal string Name;
}

// arguments: assembly name, full class name with namespace
Person p = new Person() { ID = 1 };
object p1 = Activator.CreateInstance("Basics", "Basics.Person").Unwrap();
p = (Person)p1;


More info and samples on: www.devarchweb.net

Can you compare secure strings

System.Security.SecureString NewPassword;
System.Security.SecureString NewPassword2;

NewPassword.Clear();
NewPassword.AppendChar('a');

NewPassword2.Clear();
NewPassword2.AppendChar('a');

bool b = NewPassword2.Equals(NewPassword);
// b is FALSE

b = NewPassword.GetHashCode() == NewPassword.GetHashCode();
// b is FALSE


More info and samples on: www.devarchweb.net

Convert SecureString to string

IntPtr sPtr = IntPtr.Zero;
try
{
  sPtr = Marshal.SecureStringToBSTR(securePassword);

  String s1 = Marshal.PtrToStringBSTR(sPtr);

  StringBuilder sb = new StringBuilder();
  for (int i = 0; i < s1.Length; i++)
  {
    sb.Append(s1[i]);
  }
  return sb.ToString();
}
finally
{
  if (ss_bstr1_ptr != IntPtr.Zero)
  {
    Marshal.ZeroFreeBSTR(ss_bstr1_ptr);
  }
}


More info and samples on: www.devarchweb.net

Publish and subscribe string and int events with Caliburn

// add reference to Caliburn.micro.dll
using Caliburn.Micro; // this is needed in order to see PublishOnUIThread extension method
public partial class MainForm : Form
{
  internal static readonly Caliburn.Micro.IEventAggregator _eventAggregator = new Caliburn.Micro.EventAggregator();

  public void Publish()
  {
   _eventAggregator.PublishOnUIThread("Hello from Caliburn");
   _eventAggregator.PublishOnUIThread(123);
  }
}

public partial class Form2Calibrun : Form, IHandle<string>, IHandle<int>
{
  public Form2Calibrun()
  {
    ...
    MainForm._eventAggregator.Subscribe(this);
  }

  public new void Handle(string message)
  {
    label1.Text = (string)message;
  }

  public new void Handle(int message)
  {
    label1.Text = Convert.ToString(message);
  }
}


More info and samples on: www.devarchweb.net

How to subscribe (with filter), handle, raise and unsubscribe events with EventAggregator (Prism)

// define event object
public class MyStringEvent : PubSubEvent<string> { } // string event

public class Person
{
public int Id;
public string Name;
}
public class MyPersonEvent : PubSubEvent<Person> { } /

// create aggregator class
IEventAggregator _aggregator = new EventAggregator();

// subscribe events
_aggregator.GetEvent<MyStringEvent>().Subscribe(StringEventHandler);
_aggregator.GetEvent<MyPersonEvent>().Subscribe(PersonEventHandler);

// subscribe events with filter
SubscriptionToken unsubscribeToken = _aggregator.GetEvent<MyStringEvent>()
  .Subscribe(StringEventHandler,
ThreadOption.UIThread,
keepSubscriberReferenceAlive: false,
filter: s => s.StartsWith("A"));


// handle events
private void StringEventHandler(string s) { ... }
private void PersonEventHandler(Person p) { ... }

// raise event
_aggregator.GetEvent<MyStringEvent>().Publish("Hello");
_aggregator.GetEvent<MyPersonEvent>().Publish(new Person() { Name = "John"} );

// unsubscribe
_aggregator.GetEvent<MyStringEvent>().Unsubscribe(StringEventHandler);
_aggregator.GetEvent<MyStringEvent>().Unsubscribe(unsubscribeToken);


More info and samples on: www.devarchweb.net

How use Lazy class to create a Singleton Lazy class can be used to create a thread safe singleton

public sealed class MySingleton
{
   private static readonly Lazy<MySingleton> lazy =
     new Lazy<MySingleton>(() => new MySingleton());

   public static MySingleton Instance { get { return lazy.Value; } }

   private MySingleton()
   {
   }
}





More info and samples on: www.devarchweb.net