6 мая 2015 г.

DI - SYmfony

Symfony2 Dependency Injection в разрезе из песочницы

Из статьи можно узнать как стартует и работает приложение Symfony2. Мне бы хотелось продолжить цикл статей про этот современный фреймворк и уделить более пристальное внимание такому компоненту как Dependency Injection (DI — внедрение зависимости) так же известный как Service Container.

Предисловие


Хотелось бы сначала вкратце описать про архитектуру Symfony2. Ядро приложения состоит из компонентов (Component), которые являются независимыми между собой элементами и выполняют определенные функции. Бизнес-логика приложения заключена в т.н. бандлах. Наравне со встроенными компонентами Symfony2 можно подключить любые другие компоненты-библиотеки сторонних вендоров (в т.ч. популярный Zend), не забыв их правильно зарегистрировать в автолоадере. Как правило, вместе с ядром Symfony2, поставляются такие компоненты как Twig (шаблонизатор), Doctrine2 (ORM), SwiftMailer (mailer).

Сервисно-ориентированная архитектура


Идеология разделения функций на модули, которые выделяются в независимые сервисы, принято называть сервисно-ориентированной архитектурой (Service-oriented architecture, SOA). Она положена в основу Symfony2.

Dependency Injection и Inversion of Control


В приложении с использованием ООП разработчик оперирует и работает с объектами. Каждый объект нацелен на выполнение определенных функций (сервис) и не исключено, что внутри него инкапсулируются другие объекты. Получается зависимость одного объекта от другого, в результате которой родительскому объекту предстоит управлять состоянием экземпляров потомков. Шаблон внедрение зависимости (Dependency Injection, DI) призван избавиться от такой необходимости и предоставить управление зависимостями внешнему коду. Т.е. объект всегда будет работать с готовым экземпляром другого объекта (потомка) и не будет знать как этот объект создается, кем и какие еще зависимости существуют. Родительский объект просто предоставляет механизм подстановки зависимого объекта, как правило, через конструктор или сеттер-метод. Такая передача управления называется Inversion of Control (инверсия управления). Инверсия состоит в том, что сам объект уже не управляет состоянием своих объектов-потомков.
Компонент Dependency Injection в Symfony2 опирается на контейнер, управляет всеми зарегистрированными сервисами и отслеживает связи между ними, создает экземпляры сервисов и использует механизм подстановки.

IoC контейнер


Компоненту DI необходимо знать зависимости между объектами-сервисами, а также какими сервисами он может управлять. Для этого в Symfony2 есть ContainerBuilder, который формируется на основании xml-карты или прямого формирования зависимостей в бандле. Как это происходит в Symfony2. Допустим, в приложении есть App\HelloBundle. Чтобы сформировать контейнер и дополнить его своими сервисами (на уровне фреймворка контейнер уже существует и заполнен сервисами, определенными в стандартных бандлах), необходимо создать директорию DependencyInjection в корневой директории бандла и переопределить метод load класса \Symfony\Component\HttpKernel\DependencyInjection\Extension (согласно правилам Symfony2 класс должен называться AppHelloBundleExtension, т.е. [namespace][название бандла]Extension).

# App\HelloBundle\DependencyInjection\AppHelloBundleExtension.php
<?php

namespace App\HelloBundle\DependencyInjection;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;

class AppHelloBundleExtension extends Extension
{
    public function load(array $configs, ContainerBuilder $container)
    {
        ...
    }
}


Сервисы приложения


После того, когда у вас уже есть AppHelloBundleExtension, вы можете начать добавлять свои сервисы. Необходимо учесть, что в данном случае вы оперируете не самими объектами-сервисами, а только лишь их определениями (Definition). Потому что в данном контексте контейнер как таковой еще отсутствует, он лишь формируется на основании определений.
# App\HelloBundle\DependencyInjection\AppHelloBundleExtension.php
public function load(array $configs, ContainerBuilder $container)
{
    $definition = new Definition('HelloBundle\\SomePrettyService');
    $container->addDefinition($definition);
}

Помимо такого «ручного» создания кода, можно воспользоваться импортированием xml-карты сервисов, которая создается согласно определенным правилам. Очевидно, что он более удобнее и нагляднее.
# App\HelloBundle\DependencyInjection\AppHelloBundleExtension.php
public function load(array $configs, ContainerBuilder $container)
{
    $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
    $loader->load('services.xml');
}

Однако, нам ничего не мешает использовать оба способа создания определений.
# App\HelloBundle\DependencyInjection\AppHelloBundleExtension.php
public function load(array $configs, ContainerBuilder $container)
{
    $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
    $loader->load('services.xml');
    
    $definition = $container->getDefinition('some.pretty.service');
    // ...
    // do something with $definition
    // ...
}

Это удобно в том случае, когда в xml-файле задается структура определения, а в расширении (Extension) для определения подставляются значения нужных аргументов, например, из файла конфигурации. Создание собственной конфигурации немного выходит за рамки текущей статьи и может быть рассмотрена позднее. Предполагается, что в текущий момент есть коллекция с данными из конфигурации.

Теперь посмотрим, как создавать определения будущих сервисов в xml. Файл имеет следующую корневую структуру

<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services symfony.com/schema/dic/services/services-1.0.xsd">
  <parameters>
    <parameter>...</parameter>
    ...
  </parameters>
  <services>
    <service>...</service>
    ...
  </services>
</container>


* This source code was highlighted with Source Code Highlighter.

Каждое определение сервиса задается тегом service. Для него предусмотрены следующие атрибуты
  • id — название сервиса (то, по которому этот сервис можно получать из контейнера)
  • class — название класса сервиса, если он будет создаваться через конструкцию new (если сервис будет создаваться через фабрику, название класса может быть ссылкой на интерфейс или абстрактный класс)
  • scope
  • public — true или false — видимость сервиса
  • syntetic — true или false
  • abstract — true или false — является ли данное определение сервиса абстрактным, т.е. шаблоном для использования в определении других сервисов
  • factory-class — название класса-фабрики для статического вызова метода
  • factory-service — название существующего сервиса-фабрики для вызова публичного метода
  • factory-method — название метода фабрики, к которому обращается контейнер
  • alias — алиас сервиса
  • parent

Атрибуты задаваемых параметров parameter
  • type
  • id
  • key
  • on-invalid

Внутри тега service могут быть вложены следующие элементы
<argument />
<tag />
<call />


* This source code was highlighted with Source Code Highlighter.

argument — передача в качестве параметра какого-либо аргумента, либо это ссылка на существующий сервис, либо коллекция аргументов.
tag — тэг, назначаемый сервису.
call — вызов метода сервиса после его инициализации. При вызове метода передаваемые параметры перечисляются с помощью вложенного тега argument.
Значения атрибутов и тегов (к примеру, названия классов) чаще всего выносят в параметры, далее используют подстановку этого параметра в атрибут или тег. Параметр всегда можно различить по наличию знака % в начале и конце. Например

<parameters>
  <parameter key="some_service.class">App\HelloBundle\Service</parameter>
</parameters>
<services>
  <service id="some_service" class="%some_service.class%" />
</services>


* This source code was highlighted with Source Code Highlighter.

Удобно в таком случае все параметры перечислить в одном месте, а потом использовать не один раз в определениях сервисов.

Примеры определений сервисов


Теперь более наглядно описанное выше может быть представлено на примерах:
<service id="some_service_name" class="App\HelloBundle\Service\Class">
  <argument>some_text</argument>
  <argument type="service" id="reference_service" /><!-- в качестве аргумента передается ссылка на существующий сервис -->
  <argument type="collection">
    <argument key="key">value</argument>
  </argument>
  <call method="setRequest">
    <argument type="service" id="request" />
  </call>
</service>


* This source code was highlighted with Source Code Highlighter.

Выше описанный сервис контейнером при первом обращении к нему «превращается» примерно в следующее
// инстанцированные ранее контейнером сервисы
$referenceService = ... ;
$request = ... ;

$service = new App\HelloBundle\Service\Class('some_text', $referenceService, array('key' => 'value'));
$service->setRequest($request);

Тоже самое, но в определениях Symfony2
# App\HelloBundle\DependencyInjection\AppHelloBundleExtension.php
public function load(array $configs, ContainerBuilder $container)
{
    $definition = new Definition('App\HelloBundle\Service\Class');
    $definition->addArgument('some_text');
    $definition->addArgument(new Reference('reference_service'));
    $definition->addArgument(array('key' => 'value'));
    $definition->addMethodCall('setRequest', array(new Reference('request')));
    $container->setDefinition('some_service_name', $definition);
}

Получить данный сервис, например, в контроллере MVC можно так
$this->container->get('some_service_name');

Думаю, что более наглядные примеры создания определений сервисов можно посмотреть в стандартных бандлах, поставляемых вместе с ядром Symfony2.

Заключение


В качестве заключения стоит отметить что Service Container в Symfony2 очень удобен, позволяет однажды сконфигурировать все необходимые для приложения сервисы и использовать их по назначению. Также стоит отметить, что в Symfony2 существует «умная» система кэширования в том числе и для определений сервисов, поэтому каждый раз добавляя или изменяя их, не забывайте чистить кэш.

Ссылки по теме


Martin Fawler: Inversion of Control Containers and the Dependency Injection pattern
Внедрение зависимости
Обращение контроля (инверсия управления)
Symfony2 — The Service Container

5 мая 2015 г.

Symfony - Формы

Формы

Работа с формами очень распространенная и утомительная задача для веб мастеров. Symfony предлагает вам компонент Form способный сделать работу с формами очень простой. В этой статье мы будет строить  форму с нуля и рассмотрим все основные возможности компонента.
Компонент Form является автономной библиотекой, которая может быть использованна в любом проекте.

Создаем простую форму

Предположим что вы будете создавать органайзер, который будет отображать задачи,а так же позволять их добавлять и редактировать.
Разумеется поскольку речь идет о добавление и редактировании вам понадобиться форма. Но прежде чем мы начнем давайте создадим Сущность Task который представляет 1 задачу.
// src/AppBundle/Entity/Task.php
namespace AppBundle\Entity;
class Task
{
    protected $task;
    protected $dueDate;

    public function getTask()
    {
        return $this->task;
    }

    public function setTask($task)
    {
        $this->task = $task;
    }

    public function getDueDate()
    {
        return $this->dueDate;
    }

    public function setDueDate(\DateTime $dueDate = null)
    {
        $this->dueDate = $dueDate;
    }
}
Этот клас обычный PHP объект, он не имеет ничего общего ни с Symfony, ни с другими библиотеками. Этот объект довольно простой и нужен для удобной(человекопонятной) презентации такой сущности как Задача. Конечно в конце этой статьи вы сможете представлять данные объекта Task через формы, проверять входящие данные и сохранять их в базу данных.

Создание формы

Now that you've created a Task class, the next step is to create and render the actual HTML form. In Symfony, this is done by building a form object and then rendering it in a template. For now, this can all be done from inside a controller:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// src/AppBundle/Controller/DefaultController.php
namespace AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use AppBundle\Entity\Task;
use Symfony\Component\HttpFoundation\Request;

class DefaultController extends Controller
{
    public function newAction(Request $request)
    {
        // create a task and give it some dummy data for this example
        $task = new Task();
        $task->setTask('Write a blog post');
        $task->setDueDate(new \DateTime('tomorrow'));

        $form = $this->createFormBuilder($task)
            ->add('task', 'text')
            ->add('dueDate', 'date')
            ->add('save', 'submit', array('label' => 'Create Task'))
            ->getForm();

        return $this->render('default/new.html.twig', array(
            'form' => $form->createView(),
        ));
    }
}
This example shows you how to build your form directly in the controller. Later, in the "Creating Form Classes" section, you'll learn how to build your form in a standalone class, which is recommended as your form becomes reusable.
Creating a form requires relatively little code because Symfony form objects are built with a "form builder". The form builder's purpose is to allow you to write simple form "recipes", and have it do all the heavy-lifting of actually building the form.
In this example, you've added two fields to your form - task and dueDate - corresponding to the task and dueDate properties of the Task class. You've also assigned each a "type" (e.g. text, date), which, among other things, determines which HTML form tag(s) is rendered for that field.
Finally, you added a submit button with a custom label for submitting the form to the server.
2.3Support for submit buttons was introduced in Symfony 2.3. Before that, you had to add buttons to the form's HTML manually.
Symfony comes with many built-in types that will be discussed shortly (see Built-in Field Types).

Rendering the Form

Now that the form has been created, the next step is to render it. This is done by passing a special form "view" object to your template (notice the $form->createView() in the controller above) and using a set of form helper functions:
  • Twig
    1
    2
    3
    4
    {# app/Resources/views/default/new.html.twig #}
    {{ form_start(form) }}
    {{ form_widget(form) }}
    {{ form_end(form) }}
    
  • PHP
../_images/form-simple.png
This example assumes that you submit the form in a "POST" request and to the same URL that it was displayed in. You will learn later how to change the request method and the target URL of the form.
That's it! Just three lines are needed to render the complete form:
form_start(form)
Renders the start tag of the form, including the correct enctype attribute when using file uploads.
form_widget(form)
Renders all the fields, which includes the field element itself, a label and any validation error messages for the field.
form_end(form)
Renders the end tag of the form and any fields that have not yet been rendered, in case you rendered each field yourself. This is useful for rendering hidden fields and taking advantage of the automatic CSRF Protection.
As easy as this is, it's not very flexible (yet). Usually, you'll want to render each form field individually so you can control how the form looks. You'll learn how to do that in the "Rendering a Form in a Template" section.
Before moving on, notice how the rendered task input field has the value of the task property from the $task object (i.e. "Write a blog post"). This is the first job of a form: to take data from an object and translate it into a format that's suitable for being rendered in an HTML form.
The form system is smart enough to access the value of the protected task property via the getTask() and setTask() methods on the Task class. Unless a property is public, it must have a "getter" and "setter" method so that the Form component can get and put data onto the property. For a Boolean property, you can use an "isser" or "hasser" method (e.g. isPublished() or hasReminder()) instead of a getter (e.g. getPublished() or getReminder()).

Handling Form Submissions

The second job of a form is to translate user-submitted data back to the properties of an object. To make this happen, the submitted data from the user must be written into the form. Add the following functionality to your controller:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// ...
use Symfony\Component\HttpFoundation\Request;

public function newAction(Request $request)
{
    // just setup a fresh $task object (remove the dummy data)
    $task = new Task();

    $form = $this->createFormBuilder($task)
        ->add('task', 'text')
        ->add('dueDate', 'date')
        ->add('save', 'submit', array('label' => 'Create Task'))
        ->getForm();

    $form->handleRequest($request);

    if ($form->isValid()) {
        // perform some action, such as saving the task to the database

        return $this->redirectToRoute('task_success');
    }

    // ...
}
2.3The handleRequest() method was introduced in Symfony 2.3. Previously, the $request was passed to the submit method - a strategy which is deprecated and will be removed in Symfony 3.0. For details on that method, see Passing a Request to Form::submit() (Deprecated).
This controller follows a common pattern for handling forms, and has three possible paths:
  1. When initially loading the page in a browser, the form is simply created and rendered. handleRequest() recognizes that the form was not submitted and does nothing. isValid() returns false if the form was not submitted.
  2. When the user submits the form, handleRequest() recognizes this and immediately writes the submitted data back into the task and dueDate properties of the $task object. Then this object is validated. If it is invalid (validation is covered in the next section), isValid() returns false again, so the form is rendered together with all validation errors;
    You can use the method isSubmitted() to check whether a form was submitted, regardless of whether or not the submitted data is actually valid.
  3. When the user submits the form with valid data, the submitted data is again written into the form, but this time isValid() returns true. Now you have the opportunity to perform some actions using the $task object (e.g. persisting it to the database) before redirecting the user to some other page (e.g. a "thank you" or "success" page).
    Redirecting a user after a successful form submission prevents the user from being able to hit the "Refresh" button of their browser and re-post the data.
If you need more control over exactly when your form is submitted or which data is passed to it, you can use the submit() for this. Read more about it in the cookbook.

Submitting Forms with Multiple Buttons

2.3Support for buttons in forms was introduced in Symfony 2.3.
When your form contains more than one submit button, you will want to check which of the buttons was clicked to adapt the program flow in your controller. To do this, add a second button with the caption "Save and add" to your form:
1
2
3
4
5
6
$form = $this->createFormBuilder($task)
    ->add('task', 'text')
    ->add('dueDate', 'date')
    ->add('save', 'submit', array('label' => 'Create Task'))
    ->add('saveAndAdd', 'submit', array('label' => 'Save and Add'))
    ->getForm();
In your controller, use the button's isClicked() method for querying if the "Save and add" button was clicked:
1
2
3
4
5
6
7
8
9
if ($form->isValid()) {
    // ... perform some action, such as saving the task to the database

    $nextAction = $form->get('saveAndAdd')->isClicked()
        ? 'task_new'
        : 'task_success';

    return $this->redirectToRoute($nextAction);
}

Form Validation

In the previous section, you learned how a form can be submitted with valid or invalid data. In Symfony, validation is applied to the underlying object (e.g. Task). In other words, the question isn't whether the "form" is valid, but whether or not the $task object is valid after the form has applied the submitted data to it. Calling $form->isValid() is a shortcut that asks the $task object whether or not it has valid data.
Validation is done by adding a set of rules (called constraints) to a class. To see this in action, add validation constraints so that the task field cannot be empty and the dueDate field cannot be empty and must be a valid DateTime object.
  • Annotations
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    // AppBundle/Entity/Task.php
    use Symfony\Component\Validator\Constraints as Assert;
    
    class Task
    {
        /**
         * @Assert\NotBlank()
         */
        public $task;
    
        /**
         * @Assert\NotBlank()
         * @Assert\Type("\DateTime")
         */
        protected $dueDate;
    }
    
  • YAML
  • XML
  • PHP
That's it! If you re-submit the form with invalid data, you'll see the corresponding errors printed out with the form.
As of HTML5, many browsers can natively enforce certain validation constraints on the client side. The most common validation is activated by rendering a required attribute on fields that are required. For browsers that support HTML5, this will result in a native browser message being displayed if the user tries to submit the form with that field blank.
Generated forms take full advantage of this new feature by adding sensible HTML attributes that trigger the validation. The client-side validation, however, can be disabled by adding the novalidate attribute to the form tag or formnovalidate to the submit tag. This is especially useful when you want to test your server-side validation constraints, but are being prevented by your browser from, for example, submitting blank fields.
  • Twig
    1
    2
    {# app/Resources/views/default/new.html.twig #}
    {{ form(form, {'attr': {'novalidate': 'novalidate'}}) }}
    
  • PHP
Validation is a very powerful feature of Symfony and has its own dedicated chapter.

Validation Groups

If your object takes advantage of validation groups, you'll need to specify which validation group(s) your form should use:
1
2
3
$form = $this->createFormBuilder($users, array(
    'validation_groups' => array('registration'),
))->add(...);
If you're creating form classes (a good practice), then you'll need to add the following to the setDefaultOptions() method:
1
2
3
4
5
6
7
8
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'validation_groups' => array('registration'),
    ));
}
In both of these cases, only the registration validation group will be used to validate the underlying object.

Disabling Validation

2.3The ability to set validation_groups to false was introduced in Symfony 2.3.
Sometimes it is useful to suppress the validation of a form altogether. For these cases you can set the validation_groups option to false:
1
2
3
4
5
6
7
8
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'validation_groups' => false,
    ));
}
Note that when you do that, the form will still run basic integrity checks, for example whether an uploaded file was too large or whether non-existing fields were submitted. If you want to suppress validation, you can use the POST_SUBMIT event.

Groups based on the Submitted Data

If you need some advanced logic to determine the validation groups (e.g. based on submitted data), you can set the validation_groups option to an array callback:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

// ...
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'validation_groups' => array(
            'AppBundle\Entity\Client',
            'determineValidationGroups',
        ),
    ));
}
This will call the static method determineValidationGroups() on the Client class after the form is submitted, but before validation is executed. The Form object is passed as an argument to that method (see next example). You can also define whole logic inline by using a Closure:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
use Acme\AcmeBundle\Entity\Client;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

// ...
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'validation_groups' => function(FormInterface $form) {
            $data = $form->getData();
            if (Client::TYPE_PERSON == $data->getType()) {
                return array('person');
            }

            return array('company');
        },
    ));
}
Using the validation_groups option overrides the default validation group which is being used. If you want to validate the default constraints of the entity as well you have to adjust the option as follows:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
use Acme\AcmeBundle\Entity\Client;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

// ...
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'validation_groups' => function(FormInterface $form) {
            $data = $form->getData();
            if (Client::TYPE_PERSON == $data->getType()) {
                return array('Default', 'person');
            }

            return array('Default', 'company');
        },
    ));
}
You can find more information about how the validation groups and the default constraints work in the book section about validation groups.

Groups based on the Clicked Button

2.3Support for buttons in forms was introduced in Symfony 2.3.
When your form contains multiple submit buttons, you can change the validation group depending on which button is used to submit the form. For example, consider a form in a wizard that lets you advance to the next step or go back to the previous step. Also assume that when returning to the previous step, the data of the form should be saved, but not validated.
First, we need to add the two buttons to the form:
1
2
3
4
5
$form = $this->createFormBuilder($task)
    // ...
    ->add('nextStep', 'submit')
    ->add('previousStep', 'submit')
    ->getForm();
Then, we configure the button for returning to the previous step to run specific validation groups. In this example, we want it to suppress validation, so we set its validation_groups option to false:
1
2
3
4
5
6
$form = $this->createFormBuilder($task)
    // ...
    ->add('previousStep', 'submit', array(
        'validation_groups' => false,
    ))
    ->getForm();
Now the form will skip your validation constraints. It will still validate basic integrity constraints, such as checking whether an uploaded file was too large or whether you tried to submit text in a number field.

Built-in Field Types

Symfony comes standard with a large group of field types that cover all of the common form fields and data types you'll encounter:

3 мая 2014 г.

Установить флешплеер в linux

Пишу для Debian
1) Добавить несвободные источники в список репозиторий
2) Обновить список
3) Установить плеер
deb ftp://ftp.debian.org/debian stable main contrib non-free
sudo apt-get update
apt-get install flashplugin-nonfree

23 апр. 2014 г.

Django way | Путь Django

Разбираюсь в Django, а попутно и в python3
в этой теме буду писать о возникших проблемах и их решениях


Для поиска Описание проблемыРешение
_imaging.c:76:20: fatal error: Python.h: Нет такого файла или каталога compilation terminated. error: command 'gcc' failed with exit status 1 Нет заголовочных файлов python Решение установить python-dev, sudo apt-get install python{3,}-dev в debian-based

22 авг. 2013 г.

Всем пиратам посвящается

Программы не запускаются «Ошибка при запуске приложения (0xc0000005)» в Windows 7 и Windows 8.2013

Ошибка появляется после установки обновления операционных систем Windows 7 и Windows 8 KB2859537, выпущенное с целью исправить ряд уязвимостей ядра Windows. При установке обновления меняются многие системные файлы Windows, в том числе и файлы ядра. При этом, если у вас в системе было каким-либо образом модифицированное ядро (стоит пиратская версия ОС, потрудились вирусы), то установка обновления может привести к тому, что не запускаются программы и вы видите упомянутое сообщение об ошибке.
Для того, чтобы исправить данную ошибку вы можете:
  • Установить себе, наконец, лицензионный Windows
  • Удалить обновление KB2859537

Как удалить обновление KB2859537

Для того, чтобы удалить данное обновление,запустите командную строку от имени администратора (в Windows 7 — найдите командную строку в Пуск — Программы — Стандартные, кликните по ней правой кнопкой мыши и выберите «Запуск от имени Администратора», в Windows 8 на рабочем столе нажмите клавиши Win + X и выберите пункт меню Командная строка (Администратор)). В командной строке введите:
wusa.exe /uninstall /kb:2859537
Также вы можете произвести откат системы или зайти в Панель управления — Программы и компоненты и нажать ссылку «Просмотр установленных обновлений», после чего выбрать и удалить нужное.
Список установленных обновлений WindowsСписок установленных обновлений Windows