| title | description | author | ms.author | ms.date | ms.service | ms.subservice | ms.topic | ms.custom | helpviewer_keywords | ||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
Enable Remote Errors (Reporting Services) |
Learn how to set server properties on a Reporting Services report server to return additional information about error conditions that occur on remote servers. |
maggiesMSFT |
maggies |
03/20/2017 |
reporting-services |
report-server |
conceptual |
updatefrequency5 |
|
Enable Remote Errors (Reporting Services)
You can set server properties on a [!INCLUDEssRSnoversion] report server to return additional information about error conditions that occur on remote servers. If an error message contains the text «For more information about this error, navigate to the report server on the local server machine, or enable remote errors», you can set the EnableRemoteErrors property to access additional information that can help you troubleshoot the problem. For more information, see Report Server System Properties.
In this topic:
-
Enable Remote Errors for SharePoint Mode
-
Enable remote errors through SQL Server Management Studio (Native Mode)
-
Enable remote errors through script (Native Mode)
-
Modifying the ConfigurationInfo table (Native Mode)
Enable Remote Errors for SharePoint Mode
There are two different procedures for enabling remote errors for [!INCLUDEssRSnoversion] SharePoint mode. The procedure is different for the two different report server architectures. The newer SharePoint service based architecture that was introduced in the [!INCLUDEssSQL11] release, utilizes a setting that can be configured for each [!INCLUDEssRSnoversion] service application. The older architecture utilizes a single site level setting.
Enable Remote errors for a Reporting Services Service Application
-
For a SharePoint mode report server installed with [!INCLUDEssSQL11] or a newer version of [!INCLUDEssRSnoversion], enable the service application setting Enable remote errors. The setting can be configured for each [!INCLUDEssRSnoversion] service application.
-
In SharePoint Central Administration, click Manage service applications in the Application Management group.
-
Find your [!INCLUDEssRSnoversion] service application and click the name of your service application.
-
Click System Settings.
-
Click Enable Remote Errors in the Security section.
-
Click OK.
Enable Remote Errors for a SharePoint Site
-
For a SharePoint mode report server installed with a version of [!INCLUDEssRSnoversion] prior to [!INCLUDEssSQL11], enable the site setting Enable remote errors in local mode.
-
In Site Actions click Site Settings for the site you want to modify.
-
Click Reporting Services Site Settings in the Reporting Services group.
-
Click Enable remote errors in local mode.
-
Click OK
Enable remote errors through SQL Server Management Studio (Native Mode)
-
Start Management Studio and connect to a report server instance. For more information, see Connect to a Report Server in Management Studio.
-
Right-click the report server node, and select Properties.
-
Click Advanced to open the properties page. For more information, see Server Properties (Advanced Page) — Reporting Services.
-
In the Security section, in EnableRemoteErrors, select True.
-
Select OK.
Enable remote errors through script (Native Mode)
-
Create a text file and copy the following script into the file.
Public Sub Main() Dim P As New [Property]() P.Name = "EnableRemoteErrors" P.Value = True Dim Properties(0) As [Property] Properties(0) = P Try rs.SetSystemProperties(Properties) Console.WriteLine("Remote errors enabled.") Catch SE As SoapException Console.WriteLine(SE.Detail.OuterXml) End Try End Sub -
Save the file as EnableRemoteErrors.rss.
-
Click Start, point to Run, type cmd, and click OK to open a command prompt window.
-
Navigate to the directory that contains the .rss file you just created.
-
Type the following command line, replacing servername with the actual name of your server:
rs -i EnableRemoteErrors.rss -s https://servername/ReportServer -
For more information, see RS.exe Utility (SSRS)
Modifying the ConfigurationInfo table (Native Mode)
[!NOTE]
You can edit the ConfigurationInfo table in the report server database to set EnableRemoteErrors to True, but if the report server is actively used, you should use SQL Server Management Studio or script to modify the settings. If you modify the setting in the database, you need to restart the [!INCLUDEssRSnoversion] service before the changes take effect.
После переноса Microsoft SQL Server Reporting Services работает — отчёты создаются.
Но стоит перейти к настройкам подписки/рассылки отчётов в административном разделе, как мы получаем интересное сообщение: В базе данных сервера отчетов произошла ошибка. Это могло произойти из-за ошибки соединения, истечения времени ожидания или недостатка места на диске с базой данных. (rsReportServerDatabaseError)
На редкость информативное сообщение обязывает заглянуть в логи SSRS, где расскрываются подробности произошедшего:
library!ReportServer_0-14!13e8!04/07/2011-17:42:40:: Call to GetSystemPermissionsAction(). library!ReportServer_0-14!13e8!04/07/2011-17:42:40:: Call to ListSchedulesAction(). library!ReportServer_0-14!13e8!04/07/2011-17:42:40:: e ERROR: Throwing Microsoft.ReportingServices.Diagnostics.Utilities.ReportServerStorageException: , В базе данных сервера отчетов произошла ошибка. Это могло произойти из-за ошибки соединения, истечения времени ожидания или недостатка места на диске с базой данных.; library!ReportServer_0-14!13e8!04/07/2011-17:42:40:: e ERROR: Microsoft.ReportingServices.Diagnostics.Utilities.ReportServerStorageException: В базе данных сервера отчетов произошла ошибка. Это могло произойти из-за ошибки соединения, истечения времени ожидания или недостатка места на диске с базой данных. ---> System.Data.SqlClient.SqlException: The EXECUTE permission was denied on the object 'xp_sqlagent_notify', database 'mssqlsystemresource', schema 'sys'. в System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) в System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) в System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) в System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) в System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) в System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) в System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) в System.Data.SqlClient.SqlCommand.ExecuteNonQuery() в Microsoft.ReportingServices.Library.InstrumentedSqlCommand.b__0() в Microsoft.ReportingServices.Library.SqlBoundaryWithReturn`1.Invoke(Method m) --- Конец трассировки внутреннего стека исключений --- в Microsoft.ReportingServices.Library.Storage.WrapAndThrowKnownExceptionTypes(Exception e) в Microsoft.ReportingServices.Library.SqlBoundaryWithReturn`1.Invoke(Method m) в Microsoft.ReportingServices.Library.SqlAgentScheduler.get_IsSchedulerRunning() в Microsoft.ReportingServices.Library.SchedulingDBInterface.CheckIfSchedulerIsRunning(Boolean error) в Microsoft.ReportingServices.Library.SchedulingDBInterface.ListTasks(CatalogItemPath path) в Microsoft.ReportingServices.Library.ScheduleCoordinator.ListTasksAsArray(ExternalItemPath externalPath) в Microsoft.ReportingServices.Library.ListSchedulesAction.PerformActionNow() в Microsoft.ReportingServices.Library.RSSoapAction`1.Execute() ui!ReportManager_0-15!1298!04/07/2011-17:42:40:: e ERROR: System.Web.Services.Protocols.SoapException: В базе данных сервера отчетов произошла ошибка. Это могло произойти из-за ошибки соединения, истечения времени ожидания или недостатка места на диске с базой данных. ---> Microsoft.ReportingServices.Diagnostics.Utilities.ReportServerStorageException: В базе данных сервера отчетов произошла ошибка. Это могло произойти из-за ошибки соединения, истечения времени ожидания или недостатка места на диске с базой данных. ---> System.Exception: Чтобы получить дополнительные сведения об этой ошибке, перейдите к серверу отчетов на локальном сервере или включите удаленный контроль ошибок в Microsoft.ReportingServices.UI.ScheduleItems.LoadItems() в Microsoft.ReportingServices.UI.SortableItems.Control_Init(Object sender, EventArgs args) в System.EventHandler.Invoke(Object sender, EventArgs e) в System.Web.UI.Control.OnInit(EventArgs e) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.AddedControl(Control control, Int32 index) в Microsoft.ReportingServices.UI.SubTabs.Control_Init(Object sender, EventArgs args) в System.EventHandler.Invoke(Object sender, EventArgs e) в System.Web.UI.Control.OnInit(EventArgs e) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.AddedControl(Control control, Int32 index) в Microsoft.ReportingServices.UI.SettingsPage.Control_Init(Object sender, EventArgs e) в System.EventHandler.Invoke(Object sender, EventArgs e) в System.Web.UI.Control.OnInit(EventArgs e) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.AddedControl(Control control, Int32 index) в Microsoft.ReportingServices.UI.SharedArea.Control_Init(Object sender, EventArgs args) в System.EventHandler.Invoke(Object sender, EventArgs e) в System.Web.UI.Control.OnInit(EventArgs e) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.AddedControl(Control control, Int32 index) в Microsoft.ReportingServices.UI.Pages.Settings.Page_Init(Object sender, EventArgs e) в System.EventHandler.Invoke(Object sender, EventArgs e) в System.Web.UI.Control.OnInit(EventArgs e) в System.Web.UI.Page.OnInit(EventArgs e) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) ui!ReportManager_0-15!1298!04/07/2011-17:42:40:: e ERROR: HTTP status code --> 200 -------Details-------- System.Web.Services.Protocols.SoapException: В базе данных сервера отчетов произошла ошибка. Это могло произойти из-за ошибки соединения, истечения времени ожидания или недостатка места на диске с базой данных. ---> Microsoft.ReportingServices.Diagnostics.Utilities.ReportServerStorageException: В базе данных сервера отчетов произошла ошибка. Это могло произойти из-за ошибки соединения, истечения времени ожидания или недостатка места на диске с базой данных. ---> System.Exception: Чтобы получить дополнительные сведения об этой ошибке, перейдите к серверу отчетов на локальном сервере или включите удаленный контроль ошибок в Microsoft.ReportingServices.UI.ScheduleItems.LoadItems() в Microsoft.ReportingServices.UI.SortableItems.Control_Init(Object sender, EventArgs args) в System.EventHandler.Invoke(Object sender, EventArgs e) в System.Web.UI.Control.OnInit(EventArgs e) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.AddedControl(Control control, Int32 index) в Microsoft.ReportingServices.UI.SubTabs.Control_Init(Object sender, EventArgs args) в System.EventHandler.Invoke(Object sender, EventArgs e) в System.Web.UI.Control.OnInit(EventArgs e) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.AddedControl(Control control, Int32 index) в Microsoft.ReportingServices.UI.SettingsPage.Control_Init(Object sender, EventArgs e) в System.EventHandler.Invoke(Object sender, EventArgs e) в System.Web.UI.Control.OnInit(EventArgs e) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.AddedControl(Control control, Int32 index) в Microsoft.ReportingServices.UI.SharedArea.Control_Init(Object sender, EventArgs args) в System.EventHandler.Invoke(Object sender, EventArgs e) в System.Web.UI.Control.OnInit(EventArgs e) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Control.AddedControl(Control control, Int32 index) в Microsoft.ReportingServices.UI.Pages.Settings.Page_Init(Object sender, EventArgs e) в System.EventHandler.Invoke(Object sender, EventArgs e) в System.Web.UI.Control.OnInit(EventArgs e) в System.Web.UI.Page.OnInit(EventArgs e) в System.Web.UI.Control.InitRecursive(Control namingContainer) в System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) library!ReportServer_0-14!13e8!04/07/2011-17:42:40:: Call to GetSystemPropertiesAction(). ui!ReportManager_0-15!1298!04/07/2011-17:42:40:: e ERROR: System.Threading.ThreadAbortException: Поток находился в процессе прерывания. в System.Threading.Thread.AbortInternal() в System.Threading.Thread.Abort(Object stateInfo) в System.Web.HttpResponse.End() в Microsoft.ReportingServices.UI.ReportingPage.ShowErrorPage(String errMsg)
Трассировка SQL-сервера также выдала это сообщение:
Идём на исходный сервер (с которого был перенесён SSRS), проверяем права на указанный объект:
А теперь проверяем новый сервер (куда перенесли службу серера отчётов):
Невооружённым взглядом видно, что необходимые разрешения для роли RSExecRole отсутствуют, и, как раз вовремя, находим статью How to: Create the RSExecRole.
Осталось только раздать недостающие права. Сделать это можно вручную, как описанно в статье приведённой чуть выше, либо выполнить следующий запрос:
USE master GO GRANT EXECUTE ON master.dbo.xp_sqlagent_notify TO RSExecRole GO GRANT EXECUTE ON master.dbo.xp_sqlagent_enum_jobs TO RSExecRole GO GRANT EXECUTE ON master.dbo.xp_sqlagent_is_starting TO RSExecRole GO -- Permissions for SQL Agent SP's USE msdb GO GRANT EXECUTE ON msdb.dbo.sp_help_category TO RSExecRole GO GRANT EXECUTE ON msdb.dbo.sp_add_category TO RSExecRole GO GRANT EXECUTE ON msdb.dbo.sp_add_job TO RSExecRole GO GRANT EXECUTE ON msdb.dbo.sp_add_jobserver TO RSExecRole GO GRANT EXECUTE ON msdb.dbo.sp_add_jobstep TO RSExecRole GO GRANT EXECUTE ON msdb.dbo.sp_add_jobschedule TO RSExecRole GO GRANT EXECUTE ON msdb.dbo.sp_help_job TO RSExecRole GO GRANT EXECUTE ON msdb.dbo.sp_delete_job TO RSExecRole GO GRANT EXECUTE ON msdb.dbo.sp_help_jobschedule TO RSExecRole GO GRANT EXECUTE ON msdb.dbo.sp_verify_job_identifiers TO RSExecRole GO GRANT SELECT ON msdb.dbo.sysjobs TO RSExecRole GO GRANT SELECT ON msdb.dbo.syscategories TO RSExecRole GO
via http://sqlserver-qa.net/blogs/bi/archive/2008/05/27/execute-permission-d…
С этим случаем покончено. Сейчас ещё напишу про разворачивание Microsoft SQL Server Reporting Services на NLB-кластере и успокоюсь на сегодня : )
|
|
#1 |
|
Участник |
Отчеты. Источник данных. Возникает ошибка при открытии отчетов: Открываю MSCRM_Datasource в Репортинге, а там Microsoft CRM Data Extension. Исправляю на Microsoft SQL Server, прописываю строку соединения, и отчёты начинают работать. Но! через некоторое время источник перезаписывается и опять в нем Microsoft CRM Data Extension и отчеты не работают. Как исправить? P.S. |
|
|
#2 |
|
Moderator Регистрация: 16.08.2007 Адрес: Пермь! Записей в блоге: 151 |
Посмотрите что говорит об этой ошибке RS. Если установлен Data Connector, то источник, насколько я понимаю, и должен быть CRM Data Extension.
__________________
|
|
|
#3 |
|
Консультант-джедай Регистрация: 18.12.2008 Адрес: default city |
А с чего пошла эта ошибка? она повторяется на всех отчетах, у всех пользователей?
__________________ |
|
|
#4 |
|
Участник |
Цитата: Сообщение от Артем Enot Грунин Посмотрите что говорит об этой ошибке RS. Если установлен Data Connector, то источник, насколько я понимаю, и должен быть CRM Data Extension. То есть коннектор не всегда нужен даже если CRM и Reporting на разных серверах? Цитата: Сообщение от slivka_83 А с чего пошла эта ошибка? она повторяется на всех отчетах, у всех пользователей? На своих так сказать, то есть которые сами сваяли в Visual Studio. |
|
|
#5 |
|
Moderator Регистрация: 16.08.2007 Адрес: Пермь! Записей в блоге: 151 |
Цитата: Сообщение от Dvar То есть коннектор не всегда нужен даже если CRM и Reporting на разных серверах? Да, если настроены доверительные отношения между серверами.Это есть в документации по 3.0. Цитата: Сообщение от Dvar На своих так сказать, то есть которые сами сваяли в Visual Studio. Публиковали тоже из студии, или через CRM?
__________________
|
|
|
#6 |
|
Участник |
Цитата: Сообщение от Артем Enot Грунин Да, если настроены доверительные отношения между серверами.Это есть в документации по 3.0. Публиковали тоже из студии, или через CRM? Через CRM. |
|
|
#8 |
|
Консультант-джедай Регистрация: 18.12.2008 Адрес: default city |
нееее… тут дело в кривом запросе… откройте Management Studio и подключитесь к экземпляру Reportig Services (не Database Engine) щелкните правой кнопкой по руту и выберите свойства, перейдите к Advsnced и включите EnableRemoteErrors. Полсе этого вместо «Не удалось выполнить запрос для набора данных «DataSet1»,Вы увидите вменяемое описание ошибки
__________________ |
|
|
#9 |
|
Участник |
Цитата: Сообщение от slivka_83 нееее… тут дело в кривом запросе… откройте Management Studio и подключитесь к экземпляру Reportig Services (не Database Engine) щелкните правой кнопкой по руту и выберите свойства, перейдите к Advsnced и включите EnableRemoteErrors. Полсе этого вместо «Не удалось выполнить запрос для набора данных «DataSet1»,Вы увидите вменяемое описание ошибки Да запрос нормальный, на простейшем Select * from пробовали. Вменяемое описание ошибки вот такое:
Ничего путевого не получилось нагуглить |
|
|
#10 |
|
Участник |
Артем Enot Грунин, снес коннектор, без него только с самого сервера СРМ работают отчеты |
|
|
#11 |
|
Консультант-джедай Регистрация: 18.12.2008 Адрес: default city |
Цитата: Сообщение от Dvar Да запрос нормальный, на простейшем Select * from пробовали. А полностью селект приведите плиз
__________________ |
|
|
#12 |
|
Moderator Регистрация: 16.08.2007 Адрес: Пермь! Записей в блоге: 151 |
Цитата: Сообщение от Dvar Артем Enot Грунин, снес коннектор, без него только с самого сервера СРМ работают отчеты В смысле при запуске на сервере отрабатывают, но на клиентских машинах валятся с той ошибкой?
__________________
|
|
|
#13 |
|
Участник |
Цитата: Сообщение от slivka_83 А полностью селект приведите плиз Вот, например, по быстрому набран в визарде тока для проверки Цитата: Сообщение от Артем Enot Грунин В смысле при запуске на сервере отрабатывают, но на клиентских машинах валятся с той ошибкой? Да. |
|
|
#14 |
|
Консультант-джедай Регистрация: 18.12.2008 Адрес: default city |
Ну, вот и первый касяк
__________________ |
|
|
#15 |
|
Чайный пьяница Регистрация: 02.07.2008 Адрес: Greenville, SC |
Цитата: Сообщение от slivka_83 Ну, вот и первый касяк «Касяк» — не косяк. Поскольку активно занимаетесь переводами, то и эту страничку наверняка видели. По поводу фильтрованых вьюх написано should, т.е. следует. Использование таблицы не может привести к ошибке. 2 Dvar выложите куда нибудь файл с отчётом и ссылку сюда — надосуге посмотрю. Если в отчёте «касяков» не будет, то скорее всего проблема по админской части, в коей, к сожалению, я не силён. |
|
|
#16 |
|
Консультант-джедай Регистрация: 18.12.2008 Адрес: default city |
Не поверите, но приводилось и не раз
__________________ |
| За это сообщение автора поблагодарили: Dvar (1). |
|
|
#17 |
|
Чайный пьяница Регистрация: 02.07.2008 Адрес: Greenville, SC |
Цитата: Сообщение от slivka_83 Не поверите, но приводилось и не раз Безспорно мои знания в разработке под Reporting Services в общем и под CRM в частности — ничтожно слабы. Даже не смею оспорить эту аксиому. |
|
|
#18 |
|
Участник |
slivka_83, спасибо, помогло. |
|
|
#19 |
|
Консультант-джедай Регистрация: 18.12.2008 Адрес: default city |
ну, типа так система безопасности срм устроена
__________________ |
|
|
#20 |
|
Moderator Регистрация: 16.08.2007 Адрес: Пермь! Записей в блоге: 151 |
Сдается мне, что не в системе безопасности дело, а в правах. На таблицы они только у админа под которым вы, вероятно, заходили на сервер есть, а вот у ReportingGroup их нет.
__________________
|
| За это сообщение автора поблагодарили: Bondonello (1). |
- Remove From My Forums

Не удалось установить соединение с сервером отчетов
-
Общие обсуждения
-
На странице
Центр администрирования
Интеграция со службами Reporting Services
Получаю ошибку
Не удалось установить соединение с сервером отчетов. Убедитесь, что используется правильный URL-адрес или просмотрите журналы ULS. Область продукта: Службы SQL Server Reporting Services, Категория:
Страницы настройкиСлужбы запущены, но не могу зайти на сервер типа http://moss:80/reports ?
-
Изменен тип
22 апреля 2011 г. 6:30
-
Изменен тип
null
При построении или изменении отчетов в Microsoft System Center Configuration Manager 2012 у меня возникали следующие ошибки :
Не удалось выполнить запрос для набора данных "DataSetAdminID". (rsErrorExecutingCommand) ---------------------------- Произошла ошибка при обработке отчета. (rsProcessingAborted)
а так же
При подготовке к просмотру на клиенте произошла ошибка. Произошла ошибка при обработке отчета. (rsProcessingAborted) Не удалось выполнить запрос для набора данных "DataSet0". (rsErrorExecutingCommand) Чтобы получить дополнительные сведения об этой ошибке, перейдите к серверу отчетов на локальном сервере или включите удаленный контроль ошибок
Замечу, что имя набора данных («DataSet0», как в данном случае, или «DataSetAdminID») не играет существенной роли в решении конкретной проблемы.
Путей неправильного решения (в том числе от компании производителя) приводить не буду.
В моем случае в конфигурации служб отчетов используется учетная запись sccm (консоль Configuration Manager -> Имя системы с установленной рольюю «Точка служб отчетов» -> «Точка служб отчетов» -> Свойства -> Учетная запись точки служб отчетов)
Решением в моем случае являлось включение в члены роли sysadmin Microsoft SQL сервера данной учетной записи (sccm). Обращаю внимание на роли сервера, а не роли базы данных, в соответствующей роли которой пользователь уже состоял.






MS Certified Dirty Magic Professional
Блога

ну, а дальше Гугл Вам в помощь 