Monday 23 August 2010

.Net with unmanaged code P/Invoke. ( Робота з unmanaged кодом за допомогою C#)

Настав час виконати свою обіцянку і поговорити про використання “некерованиго” коду з .NET середовища. Хочу сказати зразу що для роботи з некерованим кодом існує зразу 3 методи – це procedure invoke (p/invoke), com interop і unsafe, але радіти тут не потрібно, тому, що в кожного з них є свої переваги і недоліки, сьогодні я попробую розглянути основний найчастіше використовуваний P/Invoke, інформацю по інших я думаю ви без проблем знайдете в інтернеті.

Чому працювати з unmanaged кодом з C# так важко?

Все діло в тому що з самого початку створення керованого(.NET) коду, на нього були покладені певні обовязки такі як управління памяттю та вивільненням ресурсів, відсутність прямої адресації, потенційно небезпечних вказівників і тд. Це все зробило його набагто легшим в використанні, але й добавило певні недоліки(менша швидкодія, необхідність встановленого .NET Framework…), тому для нормальної роботи некерованого коду його необхідно подавати таким чином щоб він відповідав вимогам керованого. При використанні некерованого коду є певні недоліки – це те, що іноді для використання некерованого коду необхідно прописати доступність операції яку він буде виконувати в маніфесті програми, і якщо в вашому коді є обмежання по роботі з певними ресурсами, використовуючи функцію з некерованого коду ці обмежання можна легко обійти.

Трохи про маршалинг.

Кожному типу змінної в некерованому коді відповідає певна змінна з керованого коду, але прямо вони не є сумісними, тому коли ми передаємо в метод стрічку типу string компілятор автоматично перетворює її(маршалить) на LPTSTR (TCHAR*), але це можна змінити. Дуже хороша стаття по темі маршалінгу і роботи з некерованим кодом є тут а я розгляну лише те що вам найчастіше може знадобитись.

Метод перший P/Invoke.

P/Invoke це спеціальний механізм для виклику функцій з dll. Для цього нам необхідно створити статичний аналог даної функції з тим же набором параметрів і помітити його атрибутом [DLLImport(“Назвафайлу.dll”)] .

using System.Runtime.InteropServices;
public class Win32
{
        [DllImport("User32.Dll")]
        public static extern void SetWindowText(IntPtr hwnd, String lpString);
}

В даному випадку ми викликаємо метод SetWindowText який приймає змінну hwnd типу IntPtr, та стрічку lpString. Тип IntPtr завжди відповідає змінним типу HWND і HMENU, він містить посилання на обєкт для якого ми хочемо виконати дану функцію, тобто якщо ми хочемо викликати цю функцію для поточного вікна то ми повинні в якості параметра передати this.Handle, якщо інший обєкт то відповідно ссилку на його “хендл”. Атрибут [DLLImport(“Назвафайлу.dll”)]  служить для того щоб компілятор знав в якому саме файлі шукати необхідну нам функцію.

Наступним кроком розглянемо виклик функції яка повертає значення типу string – GetWindowText, в неї є вихідний параметр типу  char* і позамовчуванню він нам буде маршалитись на System.String. Та тут виникає одна проблема System.String в нас є незмінним і після його ініціалізації дані в ньому змінити не можна, тому для того щоб мати змогу приймати повернений з функції текст нам необхідно використати класс StringBuilder.

using System.Text;  // для StringBuilder
[DllImport("user32.dll")]
public static extern int GetWindowText(IntPtr hwnd,StringBuilder buf, int nMaxCount);

Тип маршалингу для StringBuilder теж LPTSTR тому ми без проблем зможемо працювати з ним.

StringBuilder sTitleBar = new StringBuilder(255);
GetWindowText(this.Handle, sTitleBar, sTitleBar.Capacity);
MessageBox.Show(sTitleBar.ToString());

В вище наведеному коді ми створюємо новий обєкт StringBuilder – sTitleBar з розмірністю 255. Викликаємо функцію GetWindowText та передаємо в неї параметри: посилання не поточне вікно, змінна для отримання результату виконання, та вказуємо розмір буферу, після чого виводимо результат на екран.

Зміна типу для маршалингу.

Іноді буває необхідно викликати метод передавши йому в якості параметра стрічку в вигляді ANSI а не Unicode який використовується по замовчуванню. Для цього нам необхідно задати відповідний атрибут, розглянемо детальніше на наступному прикладі:

[DllImport("user32.dll")]
public static extern int GetClassName(IntPtr hwnd, [MarshalAs(UnmanagedType.LPStr)] StringBuilder buf, int nMaxCount);

[MarshalAs(UnmanagedType.LPStr)] StringBuilder buf – вказує компілятору що змінна буде передана в вигляді символів ANSI а не Unicode.

Виклик функцій з структурами в якості параметрів.

Для прикладу розглянемо фінкцію GetWindowRect, вона в якості одного з параметру примає структуру в яку записує координати вікна. Щоб передати їй цю структуру ми повинні позначити її атрибутом StructLayout.

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public int left ;
    public int top;
    public int right;
    public int bottom;
}
[DllImport("user32.dll")]
public static extern int GetWindowRect(IntPtr hwnd, ref RECT rc);

Структура в даному випадку передана по ссилці для того щоб функція модифікувала саме ваш обєкт а не його копію. Для використання вище наведеного коду достатньо зробити наступне:

RECT rc = new RECT();
GetWindowRect(this.Handle, ref rc);

Після його виконання наша структура буде заповнена відповідними значеннями.

Висновок, працювати з некерованим кодом важко і незвично але цілком підсилу любому, головне трохи бажання і часу для ознайомлення з основними правилами. Надалі я попробую розширити дану тему, та доповнити новими постами, та через навантеженість на роботі думаю що це буде ще не скоро.

Всім удачі!

Friday 13 August 2010

Live Writer Source code highlighter plugins test (Плагін для підсвітки коду в Live Writer)

Перш за все хочу сказати про нововведення в моєму блозі, це те що можна замітити в шапці, а саме імя посту на англійській мові. Зроблено це для пошукової оптимізації, з метою збільшення кількості відвідувачів, атже більшість людей шукають інформацю технічоного характеру на англійській мові.

INTRO

Все почалось з того що в твітері наткнувся на повідомлення Дениса Резника про те що він шукає собі плагін для підсвітки коду у Live Writer-і. До цього я ніколи не користувався подібними програмами отож вирішив спробувати. Скажу чесно сподобалось мені в ній не все, але писати та оформляти пости стало набагато легше. В певний момент я зіткнувся з тою ж проблемою що й денис, поставивши декілька плагінів для підсвітки коду я не отримав бажаного результату доки не наткнувся на … ) а це ми зараз і попробуємо вияснити, провівши невелике тестування плагінів для підсвітки коду!

Let’s start!

Кандидати:

Заінстальовані плагіни добавляться вам до списку зправа та в меню “Insert”, виглядають вони наступним чином :

Снимок

На палароїд піксер і снаджіт, увагу не звертаємо )

 

Отож переходимо безпосередньо до тестування, яке проходитиму в нас наступним чином, спочатку ми протестуємо відображення xaml а потім C#. Фрагменти будуть однакові. При можливості додаткових опцій які можуть покращити вигляд коду вони будуть увімкнені.

Paste Code

Судячи з інтерфесу цей плагін передбачає додаткове налаштування на блозі і код який він нам вставив в блог по змовчуванню був без кольорової схеми.

Безымянный

xaml:

 

<UserControl x:Class="Allscripts.Common.UI.UserControls.UCBrowsableTextBox" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid x:Name="browsableGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="350" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<TextBox Name="brTextBox" Grid.Column="0" IsReadOnly="True" Margin="0,0,20,0" FocusVisualStyle="{x:Null}" TabIndex="0" Focusable="True" />

<Button Name="btnBrowseImportFilePath" Grid.Column="1" Content="Browse" TabIndex="2" BorderThickness="2" FontSize="13" HorizontalAlignment="Left" Height="23" Width="100" VerticalAlignment="Center" Click="btnBrowseImportFilePath_Click">
<Button.Effect>
<DropShadowEffect BlurRadius="5" Color="DarkOrange" />
</Button.Effect>
</Button>

</Grid>

</UserControl>

 


C#:

        /// <summary>
/// Greate new Schelder task, wich will start every hour
/// </summary>
/// <param name="user">User name with domain</param>
/// <param name="pass">User password</param>
/// <param name="pathToFile">Path to the executable file</param>
/// <returns>True if operation completed successful </returns>
public static bool CreateTask(string user, string pass, string pathToFile)
{
Process schedule = new Process();
schedule.StartInfo.FileName = "schtasks";

StringBuilder commandLineParams = new StringBuilder();

if (OSInfo.Name == OSInfo.OSNames.Windows_XP || OSInfo.Name == OSInfo.OSNames.Windows_2000 || OSInfo.Name == OSInfo.OSNames.Windows_Server_2003)
{
commandLineParams.AppendFormat("/Create /TN PMReadyTask /SC HOURLY /TR \"\\\"{2}\\\" auto \" /ST 06:00:00 /RU {0} /RP {1} ", user, pass, pathToFile);
schedule.StartInfo.Arguments = commandLineParams.ToString();
}
else if (OSInfo.Name == OSInfo.OSNames.Windows_Vista || OSInfo.Name == OSInfo.OSNames.Windows_7 || OSInfo.Name == OSInfo.OSNames.Windows_Server_2008)
{
commandLineParams.AppendFormat("/Create /TN PMReadyTask /SC HOURLY /TR \"\\\"{2}\\\" auto \" /ST 06:00:00 /RU {0} /RP {1} /DISABLE", user, pass, pathToFile);
schedule.StartInfo.Arguments = commandLineParams.ToString();
}
schedule.Start();

schedule.WaitForExit();
if (0 != schedule.ExitCode)
{
return false;
}
return true;

}


Code Formatter for Windows Live Writer


Інтерфейс набагато кращий, більше опцій і тд. Одним словом досить хороший варіант.


Безымянный1 


xaml:


<UserControl x:Class="Allscripts.Common.UI.UserControls.UCBrowsableTextBox"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid x:Name="browsableGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="350" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<TextBox Name="brTextBox" Grid.Column="0" IsReadOnly="True" Margin="0,0,20,0" FocusVisualStyle="{x:Null}" TabIndex="0" Focusable="True" />

<Button Name="btnBrowseImportFilePath" Grid.Column="1" Content="Browse" TabIndex="2" BorderThickness="2" FontSize="13" HorizontalAlignment="Left" Height="23" Width="100" VerticalAlignment="Center" Click="btnBrowseImportFilePath_Click">
<Button.Effect>
<DropShadowEffect BlurRadius="5" Color="DarkOrange" />
</Button.Effect>
</Button>

</Grid>

</UserControl>

C#:


/// <summary>
/// Greate new Schelder task, wich will start every hour
/// </summary>
/// <param name="user">User name with domain</param>
/// <param name="pass">User password</param>
/// <param name="pathToFile">Path to the executable file</param>
/// <returns>True if operation completed successful </returns>
public static bool CreateTask(string user, string pass, string pathToFile)
{
Process schedule
= new Process();
schedule.StartInfo.FileName
= "schtasks";

StringBuilder commandLineParams
= new StringBuilder();

if (OSInfo.Name == OSInfo.OSNames.Windows_XP || OSInfo.Name == OSInfo.OSNames.Windows_2000 || OSInfo.Name == OSInfo.OSNames.Windows_Server_2003)
{
commandLineParams.AppendFormat(
"/Create /TN PMReadyTask /SC HOURLY /TR \"\\\"{2}\\\" auto \" /ST 06:00:00 /RU {0} /RP {1} ", user, pass, pathToFile);
schedule.StartInfo.Arguments
= commandLineParams.ToString();
}
else if (OSInfo.Name == OSInfo.OSNames.Windows_Vista || OSInfo.Name == OSInfo.OSNames.Windows_7 || OSInfo.Name == OSInfo.OSNames.Windows_Server_2008)
{
commandLineParams.AppendFormat(
"/Create /TN PMReadyTask /SC HOURLY /TR \"\\\"{2}\\\" auto \" /ST 06:00:00 /RU {0} /RP {1} /DISABLE", user, pass, pathToFile);
schedule.StartInfo.Arguments
= commandLineParams.ToString();
}
schedule.Start();

schedule.WaitForExit();
if (0 != schedule.ExitCode)
{
return false;
}
return true;

}


Source Code Formatter


Один з найкращих варіантів. Порадувала функція підсвітки пених фрагментів коду та простота інтерфейсу.


Безымянный2


 xaml:

  1: <UserControl x:Class="Allscripts.Common.UI.UserControls.UCBrowsableTextBox" 
  2:              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  3: 	<Grid x:Name="browsableGrid">
  4: 		<Grid.ColumnDefinitions>
  5: 			<ColumnDefinition Width="350" />
  6: 			<ColumnDefinition Width="*" />
  7: 		</Grid.ColumnDefinitions>
  8: 
  9: 		<TextBox Name="brTextBox" Grid.Column="0" IsReadOnly="True" Margin="0,0,20,0" FocusVisualStyle="{x:Null}" TabIndex="0" Focusable="True" />
 10: 
 11: 		<Button Name="btnBrowseImportFilePath" Grid.Column="1" Content="Browse" TabIndex="2" BorderThickness="2" FontSize="13" HorizontalAlignment="Left" Height="23" Width="100" VerticalAlignment="Center" Click="btnBrowseImportFilePath_Click">
 12: 			<Button.Effect>
 13: 				<DropShadowEffect BlurRadius="5" Color="DarkOrange" />
 14: 			</Button.Effect>
 15: 		</Button>
 16: 
 17: 	</Grid>
 18: 
 19: </UserControl>

C#: 

  1:         /// <summary>
  2:         /// Greate new Schelder task, wich will start every hour
  3:         /// </summary>
  4:         /// <param name="user">User name with domain</param>
  5:         /// <param name="pass">User password</param>
  6:         /// <param name="pathToFile">Path to the executable file</param>
  7:         /// <returns>True if operation completed successful </returns>
  8:         public static bool CreateTask(string user, string pass, string pathToFile)
  9:         {
 10:             Process schedule = new Process();
 11:             schedule.StartInfo.FileName = "schtasks";
 12: 
 13:             StringBuilder commandLineParams = new StringBuilder();
 14: 
 15:             if (OSInfo.Name == OSInfo.OSNames.Windows_XP || OSInfo.Name == OSInfo.OSNames.Windows_2000 || OSInfo.Name == OSInfo.OSNames.Windows_Server_2003)
 16:             {
 17:                 commandLineParams.AppendFormat("/Create /TN PMReadyTask /SC HOURLY /TR \"\\\"{2}\\\" auto \" /ST 06:00:00 /RU {0} /RP {1}  ", user, pass, pathToFile);
 18:                 schedule.StartInfo.Arguments = commandLineParams.ToString();
 19:             }
 20:             else if (OSInfo.Name == OSInfo.OSNames.Windows_Vista || OSInfo.Name == OSInfo.OSNames.Windows_7 || OSInfo.Name == OSInfo.OSNames.Windows_Server_2008)
 21:             {
 22:                 commandLineParams.AppendFormat("/Create /TN PMReadyTask /SC HOURLY /TR \"\\\"{2}\\\" auto \" /ST 06:00:00 /RU {0} /RP {1} /DISABLE", user, pass, pathToFile);
 23:                 schedule.StartInfo.Arguments = commandLineParams.ToString();
 24:             }
 25:             schedule.Start();
 26: 
 27:             schedule.WaitForExit();
 28:             if (0 != schedule.ExitCode)
 29:             {
 30:                 return false;
 31:             }
 32:             return true;
 33: 
 34:         }

Syntax Higlighter 2.0 for Windows Live Writer


Знову ж виявилось що цей плагін (я так зрозумів) передбачає додавання до блогу додаткових сккриптів. Що не завжди зручно і може виявитись для декого досить важкою проблемою.


 Безымянный3


 xaml:


 

<UserControl x:Class="Allscripts.Common.UI.UserControls.UCBrowsableTextBox" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid x:Name="browsableGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="350" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<TextBox Name="brTextBox" Grid.Column="0" IsReadOnly="True" Margin="0,0,20,0" FocusVisualStyle="{x:Null}" TabIndex="0" Focusable="True" />

<Button Name="btnBrowseImportFilePath" Grid.Column="1" Content="Browse" TabIndex="2" BorderThickness="2" FontSize="13" HorizontalAlignment="Left" Height="23" Width="100" VerticalAlignment="Center" Click="btnBrowseImportFilePath_Click">
<Button.Effect>
<DropShadowEffect BlurRadius="5" Color="DarkOrange" />
</Button.Effect>
</Button>

</Grid>

</UserControl>

 C#:


 

/// <summary>
/// Greate new Schelder task, wich will start every hour
/// </summary>
/// <param name="user">User name with domain</param>
/// <param name="pass">User password</param>
/// <param name="pathToFile">Path to the executable file</param>
/// <returns>True if operation completed successful </returns>
public static bool CreateTask(string user, string pass, string pathToFile)
{
Process schedule = new Process();
schedule.StartInfo.FileName = "schtasks";

StringBuilder commandLineParams = new StringBuilder();

if (OSInfo.Name == OSInfo.OSNames.Windows_XP || OSInfo.Name == OSInfo.OSNames.Windows_2000 || OSInfo.Name == OSInfo.OSNames.Windows_Server_2003)
{
commandLineParams.AppendFormat("/Create /TN PMReadyTask /SC HOURLY /TR \"\\\"{2}\\\" auto \" /ST 06:00:00 /RU {0} /RP {1} ", user, pass, pathToFile);
schedule.StartInfo.Arguments = commandLineParams.ToString();
}
else if (OSInfo.Name == OSInfo.OSNames.Windows_Vista || OSInfo.Name == OSInfo.OSNames.Windows_7 || OSInfo.Name == OSInfo.OSNames.Windows_Server_2008)
{
commandLineParams.AppendFormat("/Create /TN PMReadyTask /SC HOURLY /TR \"\\\"{2}\\\" auto \" /ST 06:00:00 /RU {0} /RP {1} /DISABLE", user, pass, pathToFile);
schedule.StartInfo.Arguments = commandLineParams.ToString();
}
schedule.Start();

schedule.WaitForExit();
if (0 != schedule.ExitCode)
{
return false;
}
return true;

}

 RESUME


З чотирьох встановдених мною плагінів лише 2 виявились придатними для застосування без додаткових налаштувань, через що чесно кажучи огляд не дав нам великого вибору. Особисто для себе я залишив Source Code Formatter, він легкий та зручний в використанні, містить все необхідне для мене та думаю для більшості користувачів Live Writer-а, але вибір за вами.


Якщо у вас є кращі варіанти форматування тексту буду радий почути їх.

Saturday 7 August 2010

Визначення версії ОС та створення Запланованого завдання.

Сьогодні ми поговримо про визначення версії операційної системи на якій запущена програма, та відповідно від версії віндовса визвати створення нового "Запланованого завдання" (Scheduled tasks).
INTRO
На роботі постало просте завдання, добавити нове завдання до Менеджера завдань.
Після отримання завдання та пошуку даних в інтернеті було знайдено два варіанти:
  • Використання сторонніх бібліотек.
  • Створення таску через параметри командної стрічки.
Так як підтягувати сторонні бібліотеки до проекту не рекомендувалось, я зупинився на конфігуруванні таску з командної стрічки. Зважаючи на цпецифіку необхідного нам таску виявилось що в віндовсі ХР, через доступні параметри таск повністю сконфігурувати не вдасться тому що параметр /DISABLE став доступним лише після виходу Вісти. Було прийняте рішення реалізувати створення спираючись на версію ОС і при можливості створити таск повністю а коли такої можливості немає задати максимум можливих параметрів, а ті що залишились юзер введе сам.

Для початку визначаємо версію ОС:

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

namespace Bats.Common.ServiceAgents
{
  public class OSInfo
  {
    private static OSNames sName = OSNames.Windows_XP;

    public enum OSNames
    {
      Windows_95_OSR2,
      Windows_95,
      Windows_98_Second_Edition,
      Windows_98,
      Windows_Me,
      Windows_NT_3_51,
      Windows_NT_4_0,
      Windows_NT_4_0_Server,
      Windows_2000,
      Windows_XP,
      Windows_Server_2003,
      Windows_Vista,
      Windows_7,
      Windows_Server_2008
    }

    [StructLayout(LayoutKind.Sequential)]
    protected struct OSVERSIONINFOEX
    {
      public int OSVersionInfoSize;
      public int MajorVersion;
      public int MinorVersion;
      public int BuildNumber;
      public int PlatformId;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
      public string SzCSDVersion;
      public short WServicePackMajor;
      public short WServicePackMinor;
      public short WSuiteMask;
      public byte WProductType;
      public byte WReserved;
    }

    [DllImport("kernel32.dll")]
    protected static extern bool GetVersionEx(ref OSVERSIONINFOEX osVersionInfo);

    /// <summary>
    /// Gets the name of the operating system running on this computer.
    /// </summary>
    public static OSNames Name
    {
      get
      {
        //if (sName != null)
        //{
        //  return sName;
        //}

        //string name = "unknown";
        OSNames name = OSNames.Windows_XP;

        OperatingSystem osVersion = Environment.OSVersion;
        OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX();
        osVersionInfo.OSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEX));

        if (GetVersionEx(ref osVersionInfo))
        {
          int majorVersion = osVersion.Version.Major;
          int minorVersion = osVersion.Version.Minor;

          switch (osVersion.Platform)
          {
            case PlatformID.Win32Windows:
              {
                if (majorVersion == 4)
                {
                  string csdVersion = osVersionInfo.SzCSDVersion;
                  switch (minorVersion)
                  {
                    case 0:
                      if (csdVersion == "B" || csdVersion == "C")
                      {
                        name = OSNames.Windows_95_OSR2;
                      }
                      else
                      {
                        name = OSNames.Windows_95;
                      }
                      break;
                    case 10:
                      if (csdVersion == "A")
                      {
                        name = OSNames.Windows_98_Second_Edition;
                      }
                      else
                      {
                        name = OSNames.Windows_98;
                      }
                      break;
                    case 90:
                      name = OSNames.Windows_Me;
                      break;
                  }
                }
                break;
              }

            case PlatformID.Win32NT:
              {
                byte productType = osVersionInfo.WProductType;

                switch (majorVersion)
                {
                  case 3:
                    name = OSNames.Windows_NT_3_51;
                    break;
                  case 4:
                    switch (productType)
                    {
                      case 1:
                        name = OSNames.Windows_NT_4_0;
                        break;
                      case 3:
                        name = OSNames.Windows_NT_4_0_Server;
                        break;
                    }
                    break;
                  case 5:
                    switch (minorVersion)
                    {
                      case 0:
                        name = OSNames.Windows_2000;
                        break;
                      case 1:
                        name = OSNames.Windows_XP;
                        break;
                      case 2:
                        name = OSNames.Windows_Server_2003;
                        break;
                    }
                    break;
                  case 6:
                    switch (productType)
                    {
                      case 1:
                        switch (minorVersion)
                        {
                          case 0:
                            name = OSNames.Windows_Vista;
                            break;
                          case 1:
                            name = OSNames.Windows_7;
                            break;
                        }
                        break;
                      case 3:
                        name = OSNames.Windows_Server_2008;
                        break;
                    }
                    break;
                }
                break;
              }
          }
        }

        sName = name;
        return name;
      }
    }
  }
}

* This source code was highlighted with Source Code Highlighter.

Далі пишемо класс для додавання таску:

using System;
using System.Diagnostics;
using System.Text;

namespace Bats.Common.ServiceAgents
{
  public static class TaskScheduler
  {
    /// <summary>
    /// Greate new Schelder task, wich will start every hour
    /// </summary>
    /// <param name="user">User name with domain</param>
    /// <param name="pass">User password</param>
    /// <param name="pathToFile">Path to the executable file</param>
    /// <returns>True if operation completed successful </returns>
    public static bool CreateTask(string user, string pass, string pathToFile)
    {
      Process schedule = new Process();
      schedule.StartInfo.FileName = "schtasks";

      StringBuilder commandLineParams = new StringBuilder();

      if (OSInfo.Name == OSInfo.OSNames.Windows_XP || OSInfo.Name == OSInfo.OSNames.Windows_2000 || OSInfo.Name == OSInfo.OSNames.Windows_Server_2003)
      {
        commandLineParams.AppendFormat("/Create /TN PMReadyTask /SC HOURLY /TR \"\\\"{2}\\\" auto \" /ST 06:00:00 /RU {0} /RP {1} ", user, pass, pathToFile);
        schedule.StartInfo.Arguments = commandLineParams.ToString();
      }
      else if (OSInfo.Name == OSInfo.OSNames.Windows_Vista || OSInfo.Name == OSInfo.OSNames.Windows_7 || OSInfo.Name == OSInfo.OSNames.Windows_Server_2008)
      {
        commandLineParams.AppendFormat("/Create /TN PMReadyTask /SC HOURLY /TR \"\\\"{2}\\\" auto \" /ST 06:00:00 /RU {0} /RP {1} /DISABLE", user, pass, pathToFile);
        schedule.StartInfo.Arguments = commandLineParams.ToString();
      }
      schedule.Start();

      schedule.WaitForExit();
      if (0 != schedule.ExitCode)
      {
        return false;
      }
      return true;

    }

    /// <summary>
    /// Remove an existing Task by name
    /// </summary>
    /// <param name="taskName">Name of the task to remove</param>
    public static void RemoveTask(string taskName)
    {
      Process schedule = new Process();
      schedule.StartInfo.FileName = "schtasks";

      schedule.StartInfo.Arguments = " /delete /tn " + taskName + "/f";

      schedule.Start();
    }

  }
}

* This source code was highlighted with Source Code Highlighter.

По суті два класи повністю робочі і їх можна добавляти до проекту такими як вони є, але дещо для джуніорів, все таки обяснити не помішає.

Два коди були добросовісно знайдені в інтернеті та змінені відповідно до того що було потрібно мені. Чесно кажучи мені недовподоби те, що я не написав його сам, та на практиці досить часто получається, що перед вами стоїть завдання і вам якомога швидше необхідно його виконати, та й зробити бажано це не через заднє місце, тому перш за все дивимось в інтернет і використовуємо щось з того що знайшли там.
Такий підхід в більшості випадків оправданий, він економить вам час, вчить шукати необхідну інформацію та не дозволяє вам витрачати час на винаходження колеса, а той час який ви зекономили краще потратити на вивчення даного коду.

class OSInfo
Клас містить статичну властивість яка саме й повертає нам імя операційної системи. Імена у нас винесені в енам OSNames. OSVERSIONINFOEX та GetVersionEx нам необхідні для роботи з бібліотекою kernel32.dll, яка відноситься до неуправляємого коду і відповідно C# не може працювати з її функціями на пряму. На даний час вам необхідно зрозуміти лише роботу властивості OSNames. про роботу з некерованим (unmanaget) кодом я постараюсь написати невеличкий титоріал.


class TaskScheduler
Цей клас містить всього два методи обидва вони статичні тобто для їх виклику не потрібно створювати обєкт класу, CreateTask служить для створення завдання, а RemoveTask для його видалення.
CreateTask приймає три параметри необхідних в моєму випадку, це імя та пароль користувача від якого запускатиметься програма вказана третім параметром.
Далі створюємо процес, та запускаємо в ньому программу schtasks з відповідними параметрами. Після закінчення її роботи аналізуємо повернутий код і в залежності від нього повертаємо true або false.

Два вище наведених методи дійсно легкі тому не потребують особливого розяснення, та якщо у вас винекнуть питання то пишіть в коментах.

Tuesday 3 August 2010

Цикл розробки програмного забезпечення

Увага це матеріал є повною копією сторінки з вікіпедії! В свій блог я добавляю її лише тому що вважаю просто необхідною для нормального розуміння виробничого циклу програмного забезпечення.

Матеріал з Вікіпедії - вільної енціклопедіі.
Цикл розробки програмного забезпечення - структурований поділ, покладений в процесі розробки програмного продукту. Існують кілька моделей для цього процесу, кожна з яких описує свій підхід до елементів поділу, присутніх у процесі розробки програмного забезпечення.

Зміст

1 Передмова

2 Дії в процесі написання програмного забезпечення

2.1 Аналіз вимог до продукту

2.2 Специфікація

2.3 Архітектура

2.4 Проектування, реалізація і тестування

2.5 Розповсюдження та підтримка

3 Моделі

3.1 Водоспад

3.1.1 Гнучка модель розробки

3.2
Ітеративна та інкрементна модель - еволюційний підхід. 

3.2.1 Спіральна модель 
 

3.2.2 XP: Екстремальне програмування

3.3 Інші моделі

4 Формальні методи

5 Див також

6 Примітки

 7 Links 



Передмова

Величезна кількість організацій, що займаються виробництвом програмного забезпечення, використовують різні методології виробництва.
Десятиліття зайняв процес пошуку повторюваних процесів, які збільшують продуктивність і якість продукту. Деякі намагаються систематизувати або формалізувати начебто не підпорядковуване правилам завдання написання програмного забезпечення. Інші застосовують менеджмент для його написання. Без хорошого менеджменту, проекти швидко переходять у ранг не встигаючих за термінами або не влізаючих по бюджету. Існують тонни хороших проектів, розвалившихся через поганий менеджмент.

Дії у процесі написання програмного забезпечення

Дії у процесі написання, представлені в моделі водоспаду (дивись рисунок). Є й інші моделі, які по іншому описують цей процес.


Малюнок 2. Водоспадна модель.

Аналіз вимог до продукту

Найважливіше завдання при створенні програмного продукту - це вироблення вимог, або аналіз вимог до продукту. Замовник найчастіше представляє досить розмиту ідею про те, яким повинен бути кінцевий результат, і не має уявлення про те, як повинна працювати програма. Незакінчені, безглузді, а іноді суперечать один одному вимоги розпізнаються добрими інженерами на цій стадії. Часта демонстрація живого коду може зменшити ризик того, що початкові вимоги були не вірні. Один з методів знаходження проблем такого роду - це аналіз елементів програмного забезпечення.
Коли загальні вимоги отримані від клієнта, їх необхідно уточнити і відобразити в документі. Реалізована функціональність може відрізнятися від визначеної, в результаті високої вартості розробки та / або незрозумілих вимогах до продукту. Якщо розробка проводиться поза фірмою замовника, то даний документ може використовуватися для вирішення питань пов'язаних з функціональністю продукту.
Аналіз області роботи часто є першою сходинкою проектування нового фрагмента програмного забезпечення, незалежно від того, чи є він додаванням до вже існуючого додатка або новим додатком, підсистемою або зовсім новою системою. Зважаючи на те, що розробники (так само як і аналітик) не є на початку досить освіченими у галузі нового програмного забезпечення, перше завдання - це власне дослідження цієї самої галузі. Чим краще розробники знають область, в якій працюють, тим менше потім виникає роботи. Також її проводять для того, щоб пізніше не з'являлося плутанини в термінології, і розумінні того, що робить ця програма. Якщо аналітик використовує невірну термінологію, то знову ж таки можливі непорозуміння, в результаті того, що програма буде робити не те, що потрібно. Ця робота виключає випадки на зразок «Я знаю, що ви вірите в те, що зрозуміли, що я говорю, але я не впевнений, що ви розумієте, що те, що ви чули - це не те, що я маю на увазі.»

Специфікація

Специфікація це завдання, що описує до дрібниць програмний продукт, який буде написаний, можливо, у вигляді суворого опису. На практиці більшість вдалих специфікацій написані для того, щоб зрозуміти і відточити вже написані програми. Специфікації найбільш важливі для зовнішніх інтерфейсів, які повинні залишатися стабільними. Гарний спосіб визначити, чи добра специфікація - це попросити третю сторону провести аналіз, щоб переконатися що вимоги і способи їх рішень логічно вірні.

Архітектура

Архітектура системи програми створюється для того, щоб бути впевненим, що програмне забезпечення буде виконувати вимоги які покладені на нього, а також залишає можливість для того, щоб додавати рішення для нових вимог. Так само на етапі архітектури вирішуються проблеми інтерфейсів між програмним забезпеченням і операційною системою, чи обладнанням.

Проектування, реалізація і тестування

Проектування - процес створення загальної архітектури і алгоритмів відповідно до специфікацій. Реалізація (імплементація) - це та частина процесу, під час якої програмісти власне створюють програмний код продукту. Тестування - всеосяжна і важлива частина процесу розробки програмного забезпечення. Ця частина процесу полягає в тому, щоб виявити і вирішити різні помилки. Документування проводиться для того, щоб у майбутньому було простіше підтримувати і покращувати програмний продукт. Це також може в себе включати опис зовнішніх або внутрішніх програмних інтерфейсів.

Розповсюдження та підтримка

Поширення починається після того, як код достатньо відтестуваний, і визнаний готовим до релізу.
Технічна підтримка та навчання важливі, тому що великий відсоток проектів провалюється тому, що багато розробників не розуміють, що скільки б не було витрачено часу на програмний продукт, він буде безглуздим, якщо його ніхто не використовує. Люди часто чинять опір і уникають змін програмних продуктів, так що дуже важливо провести навчання нових клієнтів.
Підтримка та поліпшення продукту разом з виправленням знайдених помилок може займати більше часу, ніж власне процес розробки цього продукту. Може бути корисним відкоригувати код, який не підходить по дизайну - це може спростити знаходження помилок і їх виправлення до того, як їх помітять користувачі.

Моделі

Водоспад

Моделлю водоспаду називається методологія, що розділяє процес розробки на наступні етапи (ступені):
1.Спеціфікація вимог

2.Проектування

3.Кодірованіе

4.Інтеграція

5.Тестірованіе та налагодження (валідація та верифікація)

6.Установка

7 . Підтримка


Гнучка модель розробки

Гнучка модель розробки створена організаціями, що займаються розробкою ітераційної. Для цього використовується більш гнучкий, централізований на людях підхід, ніж використовується в традиційних підходах. Гнучкі процеси використовують зворотний зв'язок замість планування як головного контролюючого механізму. Зворотній зв'язок ведеться за допомогою регулярних тестів, а також частих релізів розробки продукту. Цікаво, що дослідження показують потенціал для хорошого поліпшення продуктивності щодо стандартного «Водопадного» методу. Наприклад дослідження, опубліковане в серпні 2006 року, і базоване на опитуваннях більш ніж 700 компаній, свідчить про величезний прибуток при використанні цієї моделі. Дослідження було повторене в серпні 2007 року з базою в 1,700 компаній.


Ітеративна та інкрементна модель - еволюційний підхід.
Малюнок 2. Ітеративна та інкрементна модель.

Ітеративна модель передбачає розбиття життєвого циклу проекту на послідовність ітерацій, кожна з яких нагадує "міні-проект", включаючи всі фази життєвого циклу в застосуванні до створення менших фрагментів функціональності, порівняно з проектом в цілому. Мета кожної ітерації - отримання працюючої версії програмної системи, що включає функціональність, визначену інтегрованим змістом всіх попередніх та поточної ітерації. Результат фінальної ітерації містить всю необхідну функціональність продукту. Таким чином, із завершенням кожної ітерації,
продукт розвивається інкрементно.

З точки зору структури життєвого циклу таку модель називають ітеративною (iterative). З
точки зору розвитку продукту - інкрементальною (incremental). Досвід індустрії показує, що  неможливо розглядати кожен з цих поглядів ізольовано. Найчастіше таку змішану еволюційну модель називають просто ітеративна (кажучи про процес) та / або інкрементна (Кажучи про нарощування функціональності продукту).

Еволюційна модель має на увазі не лише складання працюючої (з точки зору результатів
тестування) версії системи, але і її розгортання в реальних умовах з аналізом відгуків користувачів для визначення змісту і планування наступної ітерації. "Чиста" інкрементна модель не передбачає розгортання проміжних збірок (релізів) системи і всі ітерації проводяться за наперед визначеним планом нарощування функціональності, а користувачі (замовник) отримує тільки результат фінальної ітерації як повну версію системи. З іншого боку, Скотт Амблер [Ambler, 2004], наприклад, визначає еволюційну модель як поєднання ітеративного та інкрементального підходів. У свою чергу, Мартін Фаулер [Фаулер, 2004, с.47] пише: "ітеративну розробку називають по- різному: інкрементна, спіральна, еволюційна і поступова. Різні люди вкладають у
ці терміни різний зміст, але ці відмінності не мають широкого визнання і не так важливі, як
протистояння ітеративного методу і методу водоспаду. "

Брукс пише [Брукс, 1995, с.246-247], що, в ідеалі, оскільки на кожному кроці ми маємо
працюючу систему:


• можна дуже рано почати тестування користувачами;


• можна прийняти стратегію розробки відповідно до бюджету, повністю захищає від перевитрати часу або коштів (зокрема, за рахунок скорочення другорядної функціональності).

Таким чином, Значимість еволюційного підходу на основі організації ітерацій особливо
проявляється у зниженні невизначеності із завершенням кожної ітерації. У свою чергу,
зниження невизначеності дозволяє зменшити ризики. Рисунок 2 ілюструє деякі ідеї
еволюційного підходу, припускаючи, що ітеративному розбиттю може бути підданий не
тільки життєвий цикл у цілому, включаючий перекриваючі фази - формування
вимог, проектування, конструювання і т.п., але і кожна фаза може, у свою чергу,
розбиватися на уточнюючі ітерації, пов'язані, наприклад, з деталізацією структури
декомпозиції проекту - наприклад, архітектури модулів системи.



Спіральна модель 

Спіральна модель (представлена на рисунку 3) була вперше сформульована Баррі Боемом
(Barry Boehm) у 1988 році [Boehm, 1988]. Відмінною особливістю цієї моделі є спеціальна увага на ризиках, що впливає на організацію життєвого циклу. 

Боем формулює "top-10" найбільш поширених (за пріоритетами) ризиків (використовується з
дозволу автора):

1. Дефіцит фахівців.
2. Нереалістичні терміни і бюджет.
3. Реалізація невідповідної функціональності.
4. Розробка неправильного користувальницького інтерфейсу.
5. "Золота сервіровка", перфекціонізм, непотрібна оптимізація і відточування деталей.
6. Безперервний потік змін.
7. Брак інформації про зовнішні компоненти, що визначають оточення системи залученої до інтеграції.
8. Недоліки в роботах, виконуваних зовнішніми (по відношенню до проекту) ресурсами.
9. Недостатня продуктивність одержуваної системи.
10. "Розрив" в кваліфікації фахівців різних галузей знань.

Велика частина цих ризиків пов'язана з організаційними та процесними аспектами взаємодії фахівців у проектній команді. 



Малюнок 3. Оригінальна спіральна модель життєвого циклу розробки по Боему  (Використовується з дозволу автора) [Boehm, 1988]

Сам Баррі Боем так характеризує спіральну модель розробки (використовується з дозволу
автора):
"Головне досягнення спіральної моделі полягає в тому, що вона пропонує спектр можливостей
адаптації вдалих аспектів існуючих моделей процесів життєвого циклу. У той же час,  орієнтований на ризики підхід дозволяє уникнути багатьох складнощів, присутніх у цих моделях. У певних ситуаціях спіральна модель стає еквівалентної однією з існуючих моделей. В інших випадках вона забезпечує можливість найкращого з'єднання існуючих підходів у контексті даного проекту. 
Спіральна модель володіє рядом переваг:
Модель приділяє спеціальну увагу раннього аналізу можливостей повторного використання. Це забезпечується, в першу чергу, в процесі ідентифікації та оцінки альтернатив. 
Модель припускає можливість еволюції життєвого циклу, розвиток і зміна програмного продукту. Головні джерела змін закладені в цілях, для досягнення яких створюється продукт. Підхід, що передбачає приховування інформації про деталі на певному рівні дизайну, дозволяє розглядати різні архітектурні альтернативи так, як якщо б ми говорили про єдине проектне рішення, що зменшує ризик неможливості узгодження функціоналу продукту і змінюючихся цілей (вимог).

Модель надає механізми досягнення необхідних параметрів якості як складову частину процесу розробки програмного продукту. Ці механізми будуються на основі ідентифікації всіх типів цілей (вимог) обмежень на всіх "циклах" спіралі розробки. Наприклад, обмеження по безпеці можуть розглядатися як ризики на етапі специфікування вимог. 
Модель приділяє спеціальну увагу запобіганню помилок і відкиданню непотрібних,  необгрунтованих або незадовільних альтернатив на ранніх етапах проекту. Це досягається явно певними роботами з аналізу ризиків, перевірці різних характеристик створюваного продукту (включаючи архітектуру, відповідність вимогам і т.п.) і  підтвердження можливості рухатися далі на кожному "циклі" процесу розробки.

Модель дозволяє контролювати джерела проектних робіт і відповідних витрат. По-суті мова йде про відповідь на питання - як багато зусиль необхідно затратити на аналіз вимог, планування, конфігураційне управління, забезпечення якості, тестування, формальну верифікацію і т.д.

Модель, орієнтована на ризики, дозволяє в контексті конкретного проекту вирішити завдання програми адекватного рівня зусиль, що визначається рівнем ризиків, пов'язаних з недостатнім виконанням тих чи інших робіт.

Модель не проводить різниці між розробкою нового продукту і розширенням (або супроводом) існуючого. Цей аспект дозволяє уникнути часто зустрічаного відношення до підтримки і супроводу як до "другосортної" діяльності. Такий підхід попереджає велику кількість проблем, що виникають в результаті однакового приділення уваги як звичайному супроводу, так і критичним питань, пов'язаних з розширенням функціональності продукту, завжди асоційованим з підвищеними ризиками.  

Модель дозволяє вирішувати інтегрований завдання системної розробки, яка охоплює і  програмну і апаратну складові створюваного продукту. Підхід, заснований на управлінні ризиками та можливості своєчасного відкидання непривабливих альтернатив (на ранніх стадіях проекту) скорочує витрати і однаково можна застосувати й до апаратної частини, і до програмного забезпечення. " 

Описуючи створену спіральну модель, Боем звертає увагу на те, що маючи явні переваги в порівнянні з іншими поглядами на життєвий цикл, необхідно уточнити, деталізувати кроки, тобто цикли спіральної моделі для забезпечення цілісного контексту для всіх осіб, залучених до проекту (Боем це формулює так: "Need for further elaboration of spiral model steps. In general, the spiral model process steps need further elaboration to ensure that all software development participants are operating in a consistent context. "). Організація ролей (Відповідальності членів проектної команди), деталізація етапів життєвого циклу і процесів, визначення активів (артефактів), важливих на різних етапах проекту, практики аналізу та попередження ризиків - все це питання вже конкретного процесного фреймворку або, як прийнято говорити, методології розробки. 

Дійсно, деталізація процесів, ролей і активів - питання методології. Проте, розглядаючи модель розробки, будучи концептуальним поглядом на створення продукту, вимагає, як і в будь-якому проекті, визначення ключових контрольних точок проекту - milestones. Це, у великій мірі, пов'язано з намаганням відповісти на питання "де ми?". Питання, особливо актуальне для менеджерів і лідерів проектів, які відстежують хід їх виконання і планують подальші роботи. 

У 2000 році [Boehm, 2000], представляючи аналіз використання спіральної моделі і, зокрема,
побудованого на його основі підходу MBASE - Model-Based (System) Architecting and Software
Engineering (MBASE), Боем формулює 6 ключових характеристик або практик, що забезпечують
успішне застосування спіральної моделі:

1. Паралельне, а не послідовне визначення артефактів (активів) проекту
2. Згода в тому, що на кожному циклі приділяється увага::
• цілям та обмеженням, важливим для замовника
• альтернатив організації процесу і технологічних рішень, які закладаються в продукт
• ідентифікації та вирішення ризиків
• оцінки з боку зацікавлених осіб (у першу чергу замовника)
• досягнення згоди в тому, що можна і необхідно рухатись далі
3. Використання міркувань, пов'язаних з ризиками, для визначення рівня зусиль, необхідного для кожної роботи на всіх циклах спіралі.
4. Використання міркувань, пов'язаних з ризиками, для визначення рівня деталізації кожного артефакту, що створюється на всіх циклах спіралі.
5. Управління життєвим циклом в контексті зобов'язань усіх зацікавлених осіб на основі трьох контрольних точок:
• Life Cycle Objectives (LCO)
• Life Cycle Architecture (LCA)
• Initial Operational Capability (IOC)
6. Приділення спеціальної уваги до проектних робіт і артефактів створюваної системи (Включаючи безпосередньо програмне забезпечення яке розробляється, її оточення, а також експлуатаційні характеристики) та життєвого циклу (розроблення та використання). 

Еволюціонування спіральної моделі пов'язано з питаннями деталізації робіт. Особливо варто виділити акцент на більш важливих питаннях - вимог, дизайну та коду, тобто надання більшої важливості питанням ітерацій, в тому числі, збільшення їх кількості при скороченні тривалості кожної ітерації. У результаті, можна визначити загальний набір контрольних точок в сьогоднішній спіральної моделі:
• Concept of Operations (COO) - концепція <використання> системи;
• Life Cycle Objectives (LCO) - цілі і зміст життєвого циклу;
• Life Cycle Architecture (LCA) - архітектура життєвого циклу; тут же можливо говорити про  готовності концептуальної архітектури цільової програмної системи;
• Initial Operational Capability (IOC) - перша версія створюваного продукту, придатна для дослідної експлуатації;
• Final Operational Capability (FOC) - готовий продукт, розгорнутий (встановлений і налаштований) для реальної експлуатації. 

Таким чином, ми приходимо до можливого сучасному погляду (див., наприклад, подання  спіральної моделі в [Фатрелл, Шефер і Шафер, 2003, с.159]) на ітеративний і  інкрементальинй- еволюційний життєвий цикл у формі спіральної моделі, зображеної на рисунку 4.


Малюнок 4. Оновлена спіральна модель c контрольними точками проекту.

Схоже, нам вдалося більш чітко і природно визначити контрольні точки проекту, в певній мірі, підкресливши еволюційну природу життєвого циклу. Тепер же настав час поглянути на життєвий цикл у контексті методологій, не просто деталізуючих ту чи іншу модель, але додавши до них ключовий елемент - людей. Ролі, як представлення різних функціональних груп робіт, пов'язує створення, зміну та використання активів проектів з конкретними учасниками проектних команд. У сукупності із процесами і активами (Артефактами) вони дозволяють нам створити цілісну і докладну картину життєвого циклу. 
Так як поглядів на деталізацію опису життєвого циклу може бути багато - безумовно, існують різні методології. Далі ми розглянемо концепції найбільш поширених методологій: 

• Rational Unified Process (RUP)
• Enterprise Unified Process (EUP)
• Microsoft Solutions Framework (MSF) попередньої версії 3 та її якісного оновлення - Версії 4 в обох виставах: MSF for Agile і MSF for CMMI (анонсована  спочатку як "MSF Formal")
• Agile-практики (eXtreme Programming (XP), Feature Driven Development (FDD), Dynamic Systems Development Method (DSDM), SCRUM ,...).

XP: Екстремальне програмування

Екстремальне програмування (XP) - найвідоміший ітераційний процес. У XP процес ділиться на дуже маленькі сходинки, у порівнянні з планованими процесами. Це призводить до того, що перші кроки можуть займати дні або тижні замість місяців або навіть років для кожного ступеня в моделі «водопад». Спочатку пишуться автоматичні тести, щоб описати цілі розробки. Потім іде програмування, яке закінчується в той момент, коли всі тести проходять, і програмісти не можуть придумати нових тестів. Дизайн робиться тими ж людьми, які пишуть код. (Тільки остання ступінь - підключення дизайну та коду є загальним для всіх гнучких процесів). Незакінчена, але функціонуюча система показується вузькому колу користувачів (найчастіше це самі розробники). У цей момент починають писати тести для наступної найбільш важливої частини системи.
Після того, як закінчується робота в першій фазі, процес переходить до наступної фази; Продукт не випускається до того, поки не будуть завершені всі щаблі розробки.
Проблема цієї системи полягає в тому, що процес не пропонує можливостей для виправлення помилок на ранніх стадіях (приміром, у вимогах).
Даний підхід використовується в проектах з великим ризиком в основному у великих контрактах для системи оборони.

Інші моделі

ISO / IEC 15504 - один з американських стандартів Six sigma - методологія для управління варіативністю процесу, що використовує дані і статистичний аналіз, щоб виміряти і збільшити продуктивність компанії. Test Driven Development - розробка через тестування - техніка програмування, при якій модульні тести для програми або її фрагмента пишуться до самої програми і, по суті, управляють її розробкою. Є однією з основних практик екстремального програмування.

Формальні методи

Формальні методи - математичні представлення проблеми створення програмного забезпечення, а також обладнання на рівнях вимог, специфікації, а також дизайну. Як приклад можна навести B-Method, Мережі Петрі, RAISE. Доступні різні формальні нотації специфікацій, такі як Z notation. Частіше за все для створення та валідації додатків і їх дизайну використовується теорія кінцевих автоматів.
Формальні методи використовуються при розробці авіаційного софту, а також там, де безпека софта найбільш критична. Існують так само стандарти на критерії безпеки.

Links:
http://sorlik.blogspot.com
http://ru.wikipedia.org/wiki/Цикл_разработки_программного_обеспечения