diff --git a/pykd/pykdver.h b/pykd/pykdver.h
index 7c60e11..3906302 100644
--- a/pykd/pykdver.h
+++ b/pykd/pykdver.h
@@ -2,7 +2,7 @@
 #define PYKD_VERSION_MAJOR      0
 #define PYKD_VERSION_MINOR      3
 #define PYKD_VERSION_SUBVERSION 0
-#define PYKD_VERSION_BUILDNO    24
+#define PYKD_VERSION_BUILDNO    25
 
 #define __VER_STR2__(x) #x
 #define __VER_STR1__(x) __VER_STR2__(x)
diff --git a/pykd_bootstrapper/version.h b/pykd_bootstrapper/version.h
index 2099c89..3ecc07a 100644
--- a/pykd_bootstrapper/version.h
+++ b/pykd_bootstrapper/version.h
@@ -3,7 +3,7 @@
 #define PYKDEXT_VERSION_MAJOR      1
 #define PYKDEXT_VERSION_MINOR      0
 #define PYKDEXT_VERSION_SUBVERSION 1
-#define PYKDEXT_VERSION_BUILDNO    7
+#define PYKDEXT_VERSION_BUILDNO    8
 
 #define __VER_STR2__(x) #x
 #define __VER_STR1__(x) __VER_STR2__(x)
diff --git a/pykd_bootstrapper/windbgext.cpp b/pykd_bootstrapper/windbgext.cpp
index b9d13e0..8436ddb 100644
--- a/pykd_bootstrapper/windbgext.cpp
+++ b/pykd_bootstrapper/windbgext.cpp
@@ -1,14 +1,15 @@
 #include "stdafx.h"
 
+#include <vector>
+
+#include <DbgEng.h>
+#include <atlbase.h>
 #include <comutil.h>
 
 #include <boost/python.hpp>
-
 namespace python = boost::python;
 
-#include "kdlib/windbg.h"
-
-using namespace kdlib;
+#include <boost/tokenizer.hpp>
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -21,12 +22,6 @@ public:
         m_state = PyEval_SaveThread();
     }
 
-    explicit AutoRestorePyState(PyThreadState **state)
-    {
-        *state = PyEval_SaveThread();
-        m_state = *state;
-    }
-
     ~AutoRestorePyState()
     {
         PyEval_RestoreThread(m_state);
@@ -37,21 +32,39 @@ private:
     PyThreadState*    m_state;
 };
 
+//////////////////////////////////////////////////////////////////////////////
 
-///////////////////////////////////////////////////////////////////////////////
-
-class DbgOut : public  windbg::WindbgOut
+class DbgOut
 {
 public:
 
-    virtual void write(const std::wstring& str) {
+    DbgOut(PDEBUG_CLIENT client)
+        : m_control(client)
+    {}
+
+    void write(const std::wstring& str)
+    {
         AutoRestorePyState  pystate;
-        windbg::WindbgOut::write(str);
+
+        m_control->ControlledOutputWide(
+            DEBUG_OUTCTL_THIS_CLIENT,
+            DEBUG_OUTPUT_NORMAL,
+            L"%ws",
+            str.c_str()
+            );
+
     }
 
-    virtual void writedml(const std::wstring& str) {
+    void writedml(const std::wstring& str) 
+    {
         AutoRestorePyState  pystate;
-        windbg::WindbgOut::writedml(str);
+
+        m_control->ControlledOutputWide(
+            DEBUG_OUTCTL_THIS_CLIENT | DEBUG_OUTCTL_DML,
+            DEBUG_OUTPUT_NORMAL,
+            L"%ws",
+            str.c_str()
+            );
     }
 
     void flush() {
@@ -60,273 +73,61 @@ public:
     std::wstring encoding() {
         return L"ascii";
     }
+
+private:
+
+    CComQIPtr<IDebugControl4>  m_control;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
-class DbgIn : public windbg::WindbgIn
+class DbgIn
 {
 public:
 
-    std::wstring readline() {
+    DbgIn(PDEBUG_CLIENT client)
+        : m_control(client)
+        {}
+
+    std::wstring readline()
+    {
         AutoRestorePyState  pystate;
-        return kdlib::windbg::WindbgIn::readline();
-    }
 
-    std::wstring encoding() {
-        return L"ascii";
-    }
-};
+        std::vector<wchar_t>  inputBuffer(0x10000);
 
+        ULONG  read = 0;
+        m_control->InputWide(&inputBuffer[0], static_cast<ULONG>(inputBuffer.size()), &read);
 
-///////////////////////////////////////////////////////////////////////////////
+        std::wstring  inputstr = std::wstring(&inputBuffer[0]);
 
-class PythonSingleton
-{
-
-public:
-
-    static PythonSingleton* get() {
-        if (!m_instance)
-            m_instance = new PythonSingleton();
-
-        return m_instance;
-    }
-
-    void beginPythonCode()
-    {
-        PyEval_RestoreThread(m_pyState);
-    }
-
-    void endPythonCode()
-    {
-        m_pyState = PyEval_SaveThread();
+        return inputstr.empty() ? L"\n" : inputstr;
     }
 
 private:
 
-    PythonSingleton()
-    {
-        PyEval_InitThreads();
-        
-        Py_Initialize();
-        
-        python::object  main = boost::python::import("__main__");
-        
-        python::object  main_namespace = main.attr("__dict__");
-        
-        // Python debug output console helper classes
-        python::class_<::DbgOut>("dout", "dout", python::no_init)
-            .def("write", &::DbgOut::write)
-            .def("writedml", &::DbgOut::writedml)
-            .def("flush", &::DbgOut::flush)
-            .add_property("encoding", &::DbgOut::encoding);
-        
-        python::class_<::DbgIn>("din", "din", python::no_init)
-            .def("readline", &::DbgIn::readline)
-            .add_property("encoding", &::DbgIn::encoding);
-        
-        python::object       sys = python::import("sys");
-        
-        sys.attr("stdout") = python::object(::DbgOut());
-        sys.attr("stderr") = python::object(::DbgOut());
-        sys.attr("stdin") = python::object(::DbgIn());
-        
-        m_pyState = PyEval_SaveThread();
-    }
-
-    static PythonSingleton*  m_instance;
-
-    PyThreadState  *m_pyState;
+    CComQIPtr<IDebugControl4>  m_control;
 };
 
-PythonSingleton*   PythonSingleton::m_instance = 0;
-
-
 ///////////////////////////////////////////////////////////////////////////////
 
-class PykdBootsTrapper: public windbg::WindbgExtension
+class PythonInterpreter
 {
-
 public:
 
-    KDLIB_EXT_COMMAND_METHOD(py);
-    KDLIB_EXT_COMMAND_METHOD(install);
-    KDLIB_EXT_COMMAND_METHOD(upgrade);
-
-    virtual void setUp();
-
-    virtual void tearDown();
-
-private:
-
-    void printUsage();
-    
-    void printException();
-
-    std::string getScriptFileName(const std::string &scriptName);
-
-    std::string findScript(const std::string &fullFileName);
-
-
-    bool  m_pykdInitialized;
-
-};
-
-
-///////////////////////////////////////////////////////////////////////////////
-
-class InterruptWatch : public windbg::InterruptWatch
-{
-    virtual bool onInterrupt()
+    PythonInterpreter()
     {
-        HANDLE  quitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
-        PyGILState_STATE state = PyGILState_Ensure();
-        Py_AddPendingCall(&quit, (void*)quitEvent);
-        PyGILState_Release(state);
-        WaitForSingleObject(quitEvent, INFINITE);
-        CloseHandle(quitEvent);
-        return true;
+        PyThreadState*  state = Py_NewInterpreter();
+
+        PyThreadState_Swap(state);
+
+        m_state = PyEval_SaveThread();
     }
 
-    static int quit(void *context)
+    ~PythonInterpreter()
     {
-        HANDLE   quitEvent = (HANDLE)context;
-        kdlib::eprintln(L"User Interrupt: CTRL+BREAK");
-        PyErr_SetString(PyExc_SystemExit, "CTRL+BREAK");
-        SetEvent(quitEvent);
-        return -1;
-    }
-};
+        PyEval_RestoreThread(m_state);
 
-///////////////////////////////////////////////////////////////////////////////
-
-KDLIB_WINDBG_EXTENSION_INIT(PykdBootsTrapper);
-
-KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, py)
-{
-    ArgsList   args = getArgs();
-
-    bool  global = false;
-    bool  local = false;
-    bool  clean = false;
-
-    ArgsList::iterator  foundArg;
-
-    if (!args.empty())
-    {
-        if (args[0] == "-h" || args[0] == "--help")
-        {
-            printUsage();
-            return;
-        }
-        else
-        if (args[0] == "-g" || args[0] == "--global")
-        {
-            global = true;
-            args.erase(args.begin());
-        }
-        else
-        if (args[0] == "-l" || args[0] == "--local")
-        {
-            local = true;
-            args.erase(args.begin());
-        }
-    }
-
-    PyThreadState   *localState = NULL;
-    PyThreadState   *globalState = NULL;
-
-    PythonSingleton::get()->beginPythonCode();
-
-    try {
-
-        InterruptWatch  interruptWatch;
-
-        if (!global)
-        {
-            globalState = PyThreadState_Swap(NULL);
-
-            Py_NewInterpreter();
-
-            localState = PyThreadState_Get();
-
-            python::object       sys = python::import("sys");
-
-            sys.attr("stdout") = python::object(::DbgOut());
-            sys.attr("stderr") = python::object(::DbgOut());
-            sys.attr("stdin") = python::object(::DbgIn());
-        }
-
-        std::string  scriptFileName;
-        if (args.size() > 0)
-        {
-            scriptFileName = getScriptFileName(args[0]);
-
-            if (scriptFileName.empty())
-                throw std::invalid_argument("script not found");
-
-            global = !(global || local) ? false : global; //set local by default
-        }
-        else
-        {
-            global = !(global || local) ? true : global; //set global by default
-        }
-
-        // �������� ������ � ����������� ���� ( ����� ��� ������ exec_file )
-        python::object       main = python::import("__main__");
-        python::object       globalScope(main.attr("__dict__"));
-
-
-        if (!m_pykdInitialized)
-        {
-            python::handle<>  pykdHandle(python::allow_null(PyImport_ImportModule("pykd")));
-            if (!pykdHandle)
-            {
-                PyErr_SetString(PyExc_Exception, "Pykd package is not installed. You can install it by command \"!pykd.install\"");
-                python::throw_error_already_set();
-            }
-
-            python::exec("__import__('pykd').initialize()", globalScope);
-            m_pykdInitialized = true;
-        }
-
-        if (args.size() == 0)
-        {
-            python::exec("import pykd", globalScope);
-            python::exec("from pykd import *", globalScope);
-            python::exec("__import__('code').InteractiveConsole(__import__('__main__').__dict__).interact()", globalScope);
-        }
-        else
-        {
-            // �������������� ����������� ���������
-            char  **pythonArgs = new char*[args.size()];
-
-            pythonArgs[0] = const_cast<char*>(scriptFileName.c_str());
-
-            for (size_t i = 1; i < args.size(); ++i)
-                pythonArgs[i] = const_cast<char*>(args[i].c_str());
-
-            PySys_SetArgv((int)args.size(), pythonArgs);
-
-            delete[]  pythonArgs;
-
-            python::exec_file(scriptFileName.c_str(), globalScope);
-        }
-    }
-    catch (const python::error_already_set&)
-    {
-        printException();
-    }
-    catch (const std::exception& invalidArg)
-    {
-        _bstr_t    bstrInavalidArg(invalidArg.what());
-        kdlib::eprintln(std::wstring(bstrInavalidArg));
-    }
-    
-    if (!global && localState)
-    {
-        PyInterpreterState  *interpreter = localState->interp;
+        PyInterpreterState  *interpreter = m_state->interp;
 
         while (interpreter->tstate_head != NULL)
         {
@@ -342,145 +143,499 @@ KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, py)
         PyInterpreterState_Clear(interpreter);
 
         PyInterpreterState_Delete(interpreter);
-
-        PyThreadState_Swap(globalState);
     }
 
-    PythonSingleton::get()->endPythonCode();
-}
+    void acivate()
+    {
+        PyEval_RestoreThread(m_state);
+    }
+
+    void deactivate()
+    {
+        m_state = PyEval_SaveThread();
+    }
+
+private:
+
+    PyThreadState*  m_state;
+
+};
 
 ///////////////////////////////////////////////////////////////////////////////
 
-KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, install)
+class PythonSingleton
 {
-    PythonSingleton::get()->beginPythonCode();
 
-    try {
+public:
 
-        // �������� ������ � ����������� ���� ( ����� ��� ������ exec_file )
-        python::object       main = python::import("__main__");
-
-        python::object       global(main.attr("__dict__"));
-        
-        InterruptWatch  interruptWatch;
-
-        python::exec("import pip\n", global);
-        python::exec("pip.logger.consumers = []\n", global);
-        python::exec("pip.main(['install', 'pykd'])\n", global);
-
-    }
-    catch (python::error_already_set const &)
+    static PythonSingleton* get()
     {
-        printException();
+        if (!m_instance)
+            m_instance = new PythonSingleton();
+
+        return m_instance;
     }
-    catch (const std::exception& invalidArg)
+
+    void stop()
     {
-        _bstr_t    bstrInavalidArg(invalidArg.what());
-        kdlib::eprintln(std::wstring(bstrInavalidArg));
+        delete m_globalInterpreter;
+        m_globalInterpreter = 0;
     }
 
-    PythonSingleton::get()->endPythonCode();
-}
+    void start()
+    {
+        PyEval_RestoreThread(m_globalState);
 
-///////////////////////////////////////////////////////////////////////////////
+        m_globalInterpreter = new PythonInterpreter();
 
-KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, upgrade)
-{
-    PythonSingleton::get()->beginPythonCode();
+        m_globalInterpreter->acivate();
 
-    try {
+        python::object  main = boost::python::import("__main__");
 
-        InterruptWatch  interruptWatch;
+        python::object  main_namespace = main.attr("__dict__");
+
+        // Python debug output console helper classes
+        python::class_<DbgOut>("dout", "dout", python::no_init)
+            .def("write", &DbgOut::write)
+            .def("writedml", &DbgOut::writedml)
+            .def("flush", &DbgOut::flush)
+            .add_property("encoding", &DbgOut::encoding);
+
+        python::class_<DbgIn>("din", "din", python::no_init)
+            .def("readline", &DbgIn::readline);
+
+        m_globalInterpreter->deactivate();
+    }
+
+    void acivateGlobal() {
+        m_globalInterpreter->acivate();
+    }
+
+    void deactivateGlobal() {
+        m_globalInterpreter->deactivate();
+    }
+
+    void acivateLocal() {
+        PyEval_RestoreThread(m_globalState);
+        m_locallInterpreter = new PythonInterpreter();
+        m_locallInterpreter->acivate();
+    }
+
+    void deactivateLocal() {
+        m_locallInterpreter->deactivate();
+        delete m_locallInterpreter;
+        m_locallInterpreter = 0;
+        PyThreadState_Swap(m_globalState);
+        m_globalState = PyEval_SaveThread();
+    }
+
+    void checkPykd()
+    {
+        if (m_pykdInit)
+            return;
+
+        python::handle<>  pykdHandle(python::allow_null(PyImport_ImportModule("pykd")));
+        if (!pykdHandle)
+            throw std::exception("Pykd package is not installed.You can install it by command \"!pykd.install\"");
 
         python::object       main = python::import("__main__");
-        python::object       global(main.attr("__dict__"));
-        python::exec("import pip\n", global);
-        python::exec("pip.logger.consumers = []\n", global);
-        python::exec("pip.main(['install', '--upgrade', 'pykd'])\n", global);
+        python::object       globalScope(main.attr("__dict__"));
+        python::exec("__import__('pykd').initialize()", globalScope);
+
+        m_pykdInit = true;
     }
-    catch (python::error_already_set const &)
+
+private:
+
+    static PythonSingleton*  m_instance;
+
+    PythonSingleton()
     {
-        printException();
-    }
-    catch (const std::exception& invalidArg)
-    {
-        _bstr_t    bstrInavalidArg(invalidArg.what());
-        kdlib::eprintln(std::wstring(bstrInavalidArg));
+        Py_Initialize();
+        PyEval_InitThreads();
+        m_globalState = PyEval_SaveThread();
     }
 
-    PythonSingleton::get()->endPythonCode();
-}
+    PythonInterpreter*  m_globalInterpreter;
+    PythonInterpreter*  m_locallInterpreter;
+    PyThreadState*  m_globalState;
 
-/////////////////////////////////////////////////////////////////////////////
+    bool  m_pykdInit;
+};
 
-void PykdBootsTrapper::setUp()
+PythonSingleton*   PythonSingleton::m_instance = 0;
+
+//////////////////////////////////////////////////////////////////////////////
+
+class InterruptWatch
 {
-    WindbgExtension::setUp();
-}
+public:
 
-/////////////////////////////////////////////////////////////////////////////
-
-void PykdBootsTrapper::tearDown()
-{
-    if (m_pykdInitialized)
+    InterruptWatch(PDEBUG_CLIENT client)
     {
-        PythonSingleton::get()->beginPythonCode();
+        m_control = client;
+        m_stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+        m_thread = CreateThread(NULL, 0, threadRoutine, this, 0, NULL);
+    }
 
-        try {
-            python::object  main = python::import("__main__");
-            python::object  global(main.attr("__dict__"));
-            python::exec("__import__('pykd').deinitialize()", global);
-            m_pykdInitialized = false;
-        }
-        catch (python::error_already_set const &)
+    ~InterruptWatch()
+    {
+        SetEvent(m_stopEvent);
+        WaitForSingleObject(m_thread, INFINITE);
+        CloseHandle(m_stopEvent);
+        CloseHandle(m_thread);
+    }
+
+    bool onInterrupt()
+    {
+        HANDLE  quitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+        PyGILState_STATE state = PyGILState_Ensure();
+        Py_AddPendingCall(&quit, (void*)quitEvent);
+        PyGILState_Release(state);
+        WaitForSingleObject(quitEvent, INFINITE);
+        CloseHandle(quitEvent);
+        return true;
+    }
+
+    static int quit(void *context)
+    {
+        HANDLE   quitEvent = (HANDLE)context;
+        PyErr_SetString(PyExc_SystemExit, "CTRL+BREAK");
+        SetEvent(quitEvent);
+        return -1;
+    }
+
+private:
+
+    static DWORD WINAPI threadRoutine(LPVOID lpParameter) {
+        return  static_cast<InterruptWatch*>(lpParameter)->interruptWatchRoutine();
+    }
+
+    DWORD InterruptWatch::interruptWatchRoutine()
+    {
+        while (WAIT_TIMEOUT == WaitForSingleObject(m_stopEvent, 250))
         {
-            printException();
+            HRESULT  hres = m_control->GetInterrupt();
+            if (hres == S_OK)
+            {
+                HANDLE  quitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+                PyGILState_STATE state = PyGILState_Ensure();
+                Py_AddPendingCall(&quit, (void*)quitEvent);
+                PyGILState_Release(state);
+                WaitForSingleObject(quitEvent, INFINITE);
+                CloseHandle(quitEvent);
+            }
         }
 
-        PythonSingleton::get()->endPythonCode();       
+        return 0;
     }
 
-    WindbgExtension::tearDown();
-}
+    HANDLE  m_thread;
 
-///////////////////////////////////////////////////////////////////////////////
+    HANDLE  m_stopEvent;
 
-void PykdBootsTrapper::printUsage()
+    CComQIPtr<IDebugControl>  m_control;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+typedef  std::vector< std::string >  ArgsList;
+typedef  boost::escaped_list_separator<char>    char_separator_t;
+typedef  boost::tokenizer< char_separator_t >   char_tokenizer_t;
+
+ArgsList  getArgsList(
+    PCSTR args
+    )
 {
-    kdlib::dprintln(L"usage:");
-    kdlib::dprintln(L"!py [options] [file]");
-    kdlib::dprintln(L"\tOptions:");
-    kdlib::dprintln(L"\t-g --global  : run code in the common namespace");
-    kdlib::dprintln(L"\t-l --local   : run code in the isolate namespace");
-    kdlib::dprintln(L"!install");
-    kdlib::dprintln(L"!upgrade");
+    std::string  argsStr(args);
+
+    char_tokenizer_t  token(argsStr, char_separator_t("", " \t", "\""));
+    ArgsList  argsList;
+
+    for (char_tokenizer_t::iterator it = token.begin(); it != token.end(); ++it)
+    {
+        if (*it != "")
+            argsList.push_back(*it);
+    }
+
+    return argsList;
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-std::string PykdBootsTrapper::getScriptFileName(const std::string &scriptName)
-{
-    std::string scriptFileName = findScript(scriptName);
+static const char  printUsageMsg[] =
+    "usage:\n"
+    "!py [options] [file]\n"
+    "\tOptions:\n"
+    "\t-g --global  : run code in the common namespace\n"
+    "\t-l --local   : run code in the isolate namespace\n"
+    "!install\n"
+    "!upgrade\n";
 
-    if (scriptFileName.empty())
+void printUsage(PDEBUG_CLIENT client)
+{
+    CComQIPtr<IDebugControl>(client)->
+        ControlledOutput(
+            DEBUG_OUTCTL_THIS_CLIENT,
+            DEBUG_OUTPUT_NORMAL,
+            "%s",
+            printUsageMsg
+            );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+extern "C"
+HRESULT
+CALLBACK
+DebugExtensionInitialize(
+    PULONG  Version,
+    PULONG  Flags
+    )
+{
+    PythonSingleton::get()->start();
+    return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+extern "C"
+VOID
+CALLBACK
+DebugExtensionUninitialize()
+{
+    PythonSingleton::get()->stop();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+std::string getScriptFileName(const std::string &scriptName);
+
+void printException(DbgOut &dbgOut);
+
+//////////////////////////////////////////////////////////////////////////////
+
+extern "C"
+HRESULT
+CALLBACK
+py(
+    PDEBUG_CLIENT client,
+    PCSTR args
+    )
+{
+    ArgsList  argsList = getArgsList(args);
+
+    bool  global = false;
+    bool  local = false;
+    bool  clean = false;
+
+    if (!argsList.empty())
     {
-        std::string scriptNameLow;
-        scriptNameLow.resize(scriptName.size());
-        std::transform(
-            scriptName.begin(),
-            scriptName.end(),
-            scriptNameLow.begin(),
-            ::tolower);
-        if (scriptNameLow.rfind(".py") != (scriptNameLow.length() - 3))
-            scriptFileName = findScript(scriptName + ".py");
+        if (argsList[0] == "-h" || argsList[0] == "--help")
+        {
+            printUsage(client);
+            return S_OK;
+        }
+        else
+        if (argsList[0] == "-g" || argsList[0] == "--global")
+        {
+            global = true;
+            argsList.erase(argsList.begin());
+        }
+        else
+        if (argsList[0] == "-l" || argsList[0] == "--local")
+        {
+            local = true;
+            argsList.erase(argsList.begin());
+        }
     }
 
-    return scriptFileName;
+    if (argsList.size() > 0)
+    {
+        global = !(global || local) ? false : global; //set local by default
+    }
+    else
+    {
+        global = !(global || local) ? true : global; //set global by default
+    }
+
+    DbgOut   dbgOut(client);
+    DbgOut   dbgErr(client);
+    DbgIn    dbgIn(client);
+
+    ULONG   oldMask;
+    client->GetOutputMask(&oldMask);
+    client->SetOutputMask(DEBUG_OUTPUT_NORMAL | DEBUG_OUTPUT_ERROR);
+
+
+    if (global)
+        PythonSingleton::get()->acivateGlobal();
+    else
+        PythonSingleton::get()->acivateLocal();
+
+    try {
+
+        InterruptWatch  interruptWatch(client);
+
+        python::object  sys = python::import("sys");
+
+        sys.attr("stdout") = python::object(dbgOut);
+        sys.attr("stderr") = python::object(dbgErr);
+        sys.attr("stdin") = python::object(dbgIn);
+
+        python::object  main = python::import("__main__");
+        python::object  globalScope(main.attr("__dict__"));
+
+        PythonSingleton::get()->checkPykd();
+
+        if (argsList.size() == 0)
+        {
+
+            python::exec("import pykd", globalScope);
+            python::exec("from pykd import *", globalScope);
+            python::exec("__import__('code').InteractiveConsole(__import__('__main__').__dict__).interact()", globalScope);
+        }
+        else
+        {
+
+            std::string  scriptFileName = getScriptFileName(argsList[0]);
+            if (scriptFileName.empty())
+                throw std::invalid_argument("script not found");
+
+            // �������������� ����������� ���������
+            char  **pythonArgs = new char*[argsList.size()];
+        
+            pythonArgs[0] = const_cast<char*>(scriptFileName.c_str());
+        
+            for (size_t i = 1; i < argsList.size(); ++i)
+                pythonArgs[i] = const_cast<char*>(argsList[i].c_str());
+        
+            PySys_SetArgv((int)argsList.size(), pythonArgs);
+        
+            delete[]  pythonArgs;
+
+            python::exec_file(scriptFileName.c_str(), globalScope);
+        }
+    }
+    catch (const python::error_already_set&)
+    {
+        printException(dbgOut);
+    }
+    catch (const std::exception& invalidArg)
+    {
+        _bstr_t    bstrInavalidArg(invalidArg.what());
+        dbgOut.write(std::wstring(bstrInavalidArg));
+    }
+
+    if (global)
+        PythonSingleton::get()->deactivateGlobal();
+    else
+        PythonSingleton::get()->deactivateLocal();
+
+    client->SetOutputMask(oldMask);
+
+    return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+extern "C"
+HRESULT
+CALLBACK
+install(
+    PDEBUG_CLIENT client,
+    PCSTR args
+    )
+{
+    DbgOut   dbgOut(client);
+    DbgOut   dbgErr(client);
+    DbgIn    dbgIn(client);
+
+    PythonSingleton::get()->acivateGlobal();
+    
+    try {
+    
+        python::object  sys = python::import("sys");
+
+        sys.attr("stdout") = python::object(dbgOut);
+        sys.attr("stderr") = python::object(dbgErr);
+        sys.attr("stdin") = python::object(dbgIn);
+
+        // �������� ������ � ����������� ���� ( ����� ��� ������ exec_file )
+        python::object       main = python::import("__main__");
+        python::object       global(main.attr("__dict__"));
+
+        python::exec("import pip\n", global);
+        python::exec("pip.logger.consumers = []\n", global);
+        python::exec("pip.main(['install', 'pykd'])\n", global);
+    
+    }
+    catch (const python::error_already_set&)
+    {
+        printException(dbgOut);
+    }
+    catch (const std::exception& invalidArg)
+    {
+        _bstr_t    bstrInavalidArg(invalidArg.what());
+        dbgOut.write(std::wstring(bstrInavalidArg));
+    }
+    
+    PythonSingleton::get()->deactivateGlobal();
+
+    return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+extern "C"
+HRESULT
+CALLBACK
+upgrade(
+    PDEBUG_CLIENT client,
+    PCSTR args
+    )
+{
+    DbgOut   dbgOut(client);
+    DbgOut   dbgErr(client);
+    DbgIn    dbgIn(client);
+
+    PythonSingleton::get()->acivateGlobal();
+
+    try {
+
+        python::object  sys = python::import("sys");
+
+        sys.attr("stdout") = python::object(dbgOut);
+        sys.attr("stderr") = python::object(dbgErr);
+        sys.attr("stdin") = python::object(dbgIn);
+
+        // �������� ������ � ����������� ���� ( ����� ��� ������ exec_file )
+        python::object       main = python::import("__main__");
+        python::object       global(main.attr("__dict__"));
+
+        python::exec("import pip\n", global);
+        python::exec("pip.logger.consumers = []\n", global);
+        python::exec("pip.main(['install', '--upgrade', 'pykd'])\n", global);
+
+    }
+    catch (const python::error_already_set&)
+    {
+        printException(dbgOut);
+    }
+    catch (const std::exception& invalidArg)
+    {
+        _bstr_t    bstrInavalidArg(invalidArg.what());
+        dbgOut.write(std::wstring(bstrInavalidArg));
+    }
+
+    PythonSingleton::get()->deactivateGlobal();
+
+    return S_OK;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-std::string PykdBootsTrapper::findScript(const std::string &fullFileName)
+std::string findScript(const std::string &fullFileName)
 {
     if (GetFileAttributesA(fullFileName.c_str()) != INVALID_FILE_ATTRIBUTES)
         return fullFileName;
@@ -519,7 +674,7 @@ std::string PykdBootsTrapper::findScript(const std::string &fullFileName)
 
             DWORD   fileAttr = GetFileAttributesA(&fullFileNameCStr[0]);
 
-            if ( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) == 0 )
+            if ((fileAttr & FILE_ATTRIBUTE_DIRECTORY) == 0)
                 return std::string(&fullFileNameCStr[0]);
         }
     }
@@ -529,8 +684,29 @@ std::string PykdBootsTrapper::findScript(const std::string &fullFileName)
 
 ///////////////////////////////////////////////////////////////////////////////
 
+std::string getScriptFileName(const std::string &scriptName)
+{
+    std::string scriptFileName = findScript(scriptName);
 
-void PykdBootsTrapper::printException()
+    if (scriptFileName.empty())
+    {
+        std::string scriptNameLow;
+        scriptNameLow.resize(scriptName.size());
+        std::transform(
+            scriptName.begin(),
+            scriptName.end(),
+            scriptNameLow.begin(),
+            ::tolower);
+        if (scriptNameLow.rfind(".py") != (scriptNameLow.length() - 3))
+            scriptFileName = findScript(scriptName + ".py");
+    }
+
+    return scriptFileName;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void printException(DbgOut &dbgOut)
 {
     // ������ � �������
     PyObject  *errtype = NULL, *errvalue = NULL, *traceback = NULL;
@@ -539,26 +715,25 @@ void PykdBootsTrapper::printException()
 
     PyErr_NormalizeException(&errtype, &errvalue, &traceback);
 
-    if (errtype == PyExc_SystemExit)
-        return;
+    if (errtype != PyExc_SystemExit)
+    {
+        python::object  tracebackModule = python::import("traceback");
 
-    python::object  tracebackModule = python::import("traceback");
+        std::wstringstream  sstr;
 
-    std::wstringstream  sstr;
+        python::object   lst =
+            python::object(tracebackModule.attr("format_exception"))(
+            python::handle<>(errtype),
+            python::handle<>(python::allow_null(errvalue)),
+            python::handle<>(python::allow_null(traceback)));
 
-    python::object   lst =
-        python::object(tracebackModule.attr("format_exception"))(
-        python::handle<>(errtype),
-        python::handle<>(python::allow_null(errvalue)),
-        python::handle<>(python::allow_null(traceback)));
+        sstr << std::endl << std::endl;
 
-    sstr << std::endl << std::endl;
+        for (long i = 0; i < python::len(lst); ++i)
+            sstr << std::wstring(python::extract<std::wstring>(lst[i])) << std::endl;
 
-    for (long i = 0; i < python::len(lst); ++i)
-        sstr << std::wstring(python::extract<std::wstring>(lst[i])) << std::endl;
-
-    kdlib::eprintln(sstr.str());
+        dbgOut.write(sstr.str());
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-
diff --git a/setup/setup.py b/setup/setup.py
index 557a4b4..b824fcf 100644
--- a/setup/setup.py
+++ b/setup/setup.py
@@ -8,7 +8,7 @@ import zipfile
 
 _name = "pykd"
 _desc = "python windbg extension"
-_version = '0.3.0.22'
+_version = '0.3.0.25'
 
 def  makeWheel(args):