Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/21: Рейтинг темы: голосов - 21, средняя оценка - 4.86
5 / 5 / 0
Регистрация: 08.12.2009
Сообщений: 213

Ошибка Could not start the MyService service on Local Computer. Error 5: Access denied.

26.02.2011, 10:14. Показов 4703. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Проблема описана в линке
http://www.relib.com/forums/topic.asp?id=847824

Я последовал совету от Messir и написал код на Си. (вернее использовал примеры от MSDN).
Он практически не отличается от приведенного ранее кода на VB, с той разницей, что на Си легче работать с поинтерами.

Инсталляция и удаление сервиса происходит на ура, без каких-либо осложнений.(впрочем как и в VB)
А вот запуск программы...

Если я запускаю сервис с помощью утилиты Services Console (помечаю сервис и делаю старт), то получаю сообщение
Code
1
2
Could not start the MyService service on Local Computer.
Error 5: Access denied.
Если я запускаю его через StartServiceCtrlDispatcher из главной процедуры то получаю false (запуск не удался), а GetLastError возвращает 1063.

Насколько я понимаю, StartServiceCtrlDispatcher должен запустить процедуру ServiceMain которая в свою очередь должна зарегистрировать Handler процедуру (плюс запуск дополнительных процессов и т.д.). Но до этого я так и не добрался. ServiceMain так и не запускается.

Вопрос в том, почему Access denied и какие флаги надо устанивливать чтобы получить доступ.
Хочу заметить, что я захожу в компьютер как администратор.

Да, и ещё. Я нашел несколько простых примеров на Си которые демонстрируют работу с сервисами, так они так же не работают, останавливаются на StartServiceCtrlDispatcher. Может нужен какой-то специальный доступ (логин) для запуска ?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
26.02.2011, 10:14
Ответы с готовыми решениями:

Ошибка запуска: Error while trying to run project: Unable to start debugging on the web server. Access is denied
Вот что пишут в MSDN When you try to debug on an application running on a Web server, you may sometimes get a message with this error...

error trying access the local web service: GetObject Failed
Здравствуйте, подскажите пожалуйста с чем связана ошибка. Когда устанавливаю php вылетает ошибка: error trying access the local web...

Ошибка Parser Error Message: Access is denied: 'WebApplication3'.
При старте ASP.NET приложения вываливается следующая ошибка: Configuration Error Description: An error occurred during the...

13
Messir
26.02.2011, 15:29
да простят меня за оффтопик от тематики форума, но приведу сишный код сервиса. Он 100% работает, проверено уже не раз... Правда, это всего лишь скелет - вся функциональность из кода вырезана

main.h:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <Windows.h>
 
#define SERVICE_NAME 'MyService'
#define SERVICE_DISPLAY_NAME 'MyService'
#define SERVICE_DESCRIPTION_TEXT 'My Service description'
 
#define WAIT_TIMEOUT 10
 
static SERVICE_STATUS ssStatus;
static SERVICE_STATUS_HANDLE sshStatusHandle;
 
VOID WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv);
VOID WINAPI service_ctrl(DWORD dwCtrlCode);
BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint);
 
int start();
void stop();
void wait();
DWORD WINAPI dispatcher(LPVOID param);
main.cpp:
C++
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include "main.h"
 
void install_service();
void remove_service();
void usage();
 
static SERVICE_TABLE_ENTRY dispatch_table[] = {{SERVICE_NAME, service_main},{NULL, NULL}};
 
int main(int argc, char* argv[])
{
    if (argc>2) {
        usage();
    } else if (argc > 1) {
        if (strcmpi(argv[1],"-install")==0) {
            install_service();
        } else if (strcmpi(argv[1],"-uninstall")==0) {
            remove_service();
        } else {
            usage();
        }
    } else {
        if (!StartServiceCtrlDispatcher(dispatch_table))
            printf("failed to start %s service\n", SERVICE_NAME);
    }
    return GetLastError();
}
 
void usage()
{
    printf("MyService [COMMAND]\n");
    printf("   Commands:\n");
    printf("             -install\n");
    printf("             -uninstall\n");
}
 
void install_service()
{
    SC_HANDLE   schService;
    SC_HANDLE   schSCManager;
    SERVICE_DESCRIPTION scDesc;
    CHAR szPath[MAX_PATH];
 
    if (GetModuleFileName(NULL, szPath, sizeof(szPath)) == 0) {
        printf("failed to get file path!\n");
        return;
    }
 
    schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
    if (schSCManager != NULL) {
        schService = CreateService(schSCManager,SERVICE_NAME,SERVICE_DISPLAY_NAME,
                    SERVICE_ALL_ACCESS,SERVICE_WIN32_OWN_PROCESS,SERVICE_AUTO_START,
                    SERVICE_ERROR_NORMAL,szPath,NULL,NULL,NULL,NULL,NULL);
        if (schService != NULL) {
            printf("%s service has been installed successfully\n",SERVICE_NAME);
            scDesc.lpDescription=SERVICE_DESCRIPTION_TEXT;
            ChangeServiceConfig2(schService,SERVICE_CONFIG_DESCRIPTION,&scDesc);
            CloseServiceHandle(schService);
        } else
            printf("failed to create %s service\n",SERVICE_NAME);
        CloseServiceHandle(schSCManager);
    }
    else
        printf("failed to access service database\n");
}
 
void remove_service()
{
    SC_HANDLE   schService;
    SC_HANDLE   schSCManager;
 
    schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
    if (schSCManager != NULL) {
        schService = OpenService(schSCManager, SERVICE_NAME, SERVICE_ALL_ACCESS);
        if (schService != NULL) {
            if (ControlService(schService, SERVICE_CONTROL_STOP, &ssStatus)) {
                printf("stopping %s...", SERVICE_NAME);
                Sleep(1000);
                while(QueryServiceStatus(schService,&ssStatus)) {
                    if (ssStatus.dwCurrentState == SERVICE_STOP_PENDING) {
                        printf("."); Sleep(500);
                    }
                    else
                        break;
                }
                printf("\n");
                if (ssStatus.dwCurrentState == SERVICE_STOPPED)
                    printf("%s successfully stopped\n",SERVICE_NAME);
                else
                    printf("failed to stop %s\n",SERVICE_NAME);
            }
Messir
26.02.2011, 16:04
Да, кстати, у тебя случайнов пути в файлу сервиса пробелов нету?
5 / 5 / 0
Регистрация: 08.12.2009
Сообщений: 213
26.02.2011, 16:38  [ТС]
Messir, спасибо.
Твой пример действительно работает, теперь буду разбираться где собака порылась.
А в пути к файлу у меня нет пробелов.
0
1 / 1 / 0
Регистрация: 22.04.2011
Сообщений: 47
24.06.2011, 00:07
Ну, оффтоп так оффтоп...

1. Взгляните пожалуйста на код, приведенный ниже. Он вроде работает. Но меня мучают
сомнения: 'Можно ли так?', 'А если нет, то почему?'

В частности:

2. В ServiceMain: нужно ли (для чего) дожидаться команды 'стоп' (SetEvent),
(т.е., фактически, все время работы сервиса) после создания потока?

3. В ServiceControl: нужно ли (для чего) дожидаться окончания потока по команде 'стоп'?

4. Что происходит при остановке сервиса в случае, если код внутри while (true) не доходит до
if (WaitForSingleObject(hEvent, MYWAIT_TIMEOUT) == WAIT_OBJECT_0) break;
например, при остановке сервиса вручную, или при выключении компьютера?

5. Как обрабатывать ошибки внутри цикла while, (например, можно ли выйти из цикла
не по WAIT_OBJECT_0 и тем самым завершить поток изнутри, без команды 'стоп')?

6. Если можно самостоятельно завершать поток, и соответственно сервис (см. п.5), то
нужно ли ожидание после
ReportStatus(SERVICE_STOPPED, NOERROR, 0);
до
return 0;
в процедуре потока?
Если да, то сойдет ли простое Sleep(500), или нужно дождаться от системы запроса
SERVICE_CONTROL_INTERROGATE в ServiceControl, и придет ли такой запрос в обязательном порядке?
Или же Windows сам сделает все что нужно (например, отметит для себя, что сервис
остановлен) и только потом выгрузит сервис?
В общем, решит ли Windows, что мы корректно завершили сервис без дополнительных манипуляций?

PS: В функции service_main (в реализации Messir'а) раз мы и так ожидаем команды 'стоп' не
выходя из функции, то нельзя ли обойтись без потока, а все что делается в потоке перенести
сюда вместо ожидания? Я понимаю, что от команды 'стоп' до завершения потока разница может
быть большая. Ну а если нет? Что если мы после команды 'стоп' мы можем быстренько закруглиться?
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

VOID WINAPI ServiceMain(DWORD argc, LPSTR *argv)
{
HANDLE hTread;
DWORD dwThreadId;

if(!(ssh = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceControl))) return;

ss.dwServiceSpecificExitCode = 0;
ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS;

if (!ReportStatus(SERVICE_START_PENDING, NO_ERROR, 5000)) return; //идет запуск

if (!(hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
{
MyLog('Ошибка создания объекта Event
');
ReportStatus(SERVICE_STOPPED, NOERROR, 0);
return;
}

if (!(hTread = CreateThread(NULL, 0, ThreadFunc, 0, 0, &dwThreadId)))
{
MyLog('Ошибка создания потока сервиса
');
CloseHandle(hEvent);
ReportStatus(SERVICE_STOPPED, NOERROR, 0);
return;
}
}

//-------------------------------------------------------------------------------------------

VOID WINAPI ServiceControl(DWORD dwControlCode)
{
if((dwControlCode == SERVICE_CONTROL_STOP) || (dwControlCode == SERVICE_CONTROL_SHUTDOWN))
{
ReportStatus(SERVICE_STOP_PENDING, NOERROR, 0); // идет остановка сервиса
if(hEvent) SetEvent(hEvent); // сигнал-запрос на завершение для Трейда
}
else ReportStatus(ss.dwCurrentState, NOERROR, 0); // обрабатываем другие команды
}

//-------------------------------------------------------------------------------------------

BOOL ReportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint)
{
static DWORD dwCheckPoint = 1;

if (dwCurrentState == SERVICE_START_PENDING) ss.dwControlsAccepted = 0;
else ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_CONTROL_SHUTDOWN;

ss.
0
Messir
24.06.2011, 18:45
по пунктам:

1. Пропускаем, все станет ясно из следующих пунктов

2. Не обязательно. Можно ждать, можно не ждать - тут уж как удобнее... (в приведенном сервисе этот код использовался - вот там wait и остался)

3. Очень желательно. Еще неплохо бы предусмотреть возможность насильного убиения потока в случае, если он сам умирать не хочет... Если на 100% есть уверенность, что поток не войдет в ступор и сам корректно завершится - можно не ждать.

4. Что значит - не доходит? И что есть 'остановка вручную'?
при выключении компьютера точно так же посылается сигнал остановки сервиса. И сервис завершается в штатном режиме. В случае когда мы заршаем сервис молотком и зубилом (т.е. через диспетчер задач и прочую тяжелую артиллерию), то не все ли нам равно, что будет с потоком? так или иначе - ему наступает п..дец

5. Выйти-то можно, но тогда это не будет корректным завершением. Лучшим решением является установка STOP_PENDING, и SetEvent для ожидаемого события (и, возможно, goto непосредственно к команде WaitForSingleObject). Короче, дублирование функциональности stop().

6. Ничего ждать не надо, просто завершаемся. Система сама позаботится о всех нужных действиях.

PS: А вот функциональность потока в service_main переносить - это плохая идея. Т.е. оно будет работать, но геморроя будет много. Контролировать поток куда проще и удобнее...
1 / 1 / 0
Регистрация: 22.04.2011
Сообщений: 47
25.06.2011, 03:19
Тоже, по пунктам:

2. можно какой нибудь намек, когда в ServiceMain ожидание окончания потока необходимо, или хотябы желательно?
2а.и чего правильней ожидать: стоп (SetEvent) или окончания потока, ведь если цель-100%-я уверенность в том, что поток сдох, то WaitForSingleObject(hEvent, ..) это не то, нужен WaitForSingleObject(hThread, ..)...

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

6. вопрос возник при попытке понять действия Windows при завершении сервиса:
а)если функция SetServiceStatus() только сообщает Windows адрес структуры, а он считывает эту инфу когда ему заблагорассудится возможно мы быстрее закроем свой поток и выгрузится сервис. А Windows будет пытаться счытыват уже несуществующую структуру со всеми вытекающими последствиями...
б) Windows узнает о сотоянии сервиса исходя из того, что мы отвечаем на запрос SERVICE_CONTROL_INTERROGATE - тогда, опять же, завершив сервис раньше времени мы столкнемся с приведенной выше проблемой.
в) в ходе обработки функции SetServiceStatus() Windows считывает и запоминает где-то у себя сотояние. Тогда получается системе SERVICE_CONTROL_INTERROGATE вообще нужен только в режиме SERVICE_..._PENDING, и только чтобы убедиться, что мы еще дышим. В других случаях SERVICE_CONTROL_INTERROGATE не посылается и не используется.

ЗЫ:Просто для тех кто пытается проделать все это на VB говорят multithread - это большая проблема

Новые вопросы:
- для чего в том коде SetLastError(0);
- как узнать, что поток в состоянии спячки (см. код ниже в функции ServiceControl)?
Ведь если поток спит, то сначала его нужно 'разбудить', иначе, во-первых, у него могли остаться незавершенные дела, а мы будем пываться его остановить насильно, во-вторых лучше он сам добровольно и корректно завершит свою работу.
А еще, наверое нельзя усыплять спящий поток, или будить бодрствующий?
- почему в оснастке 'Службы', кнопка 'Пауза' у моего сервиса неактивная, хотя в ReportStatus я внес соответствующие изменения?
- Где-то я слышал, что в ServiceMain как можно быстрее мы должны вызвать RegisterServiceCtrlHandler() и также быстро завершить инициализацию сервиса.
Но какое дело системе до нашей инициализации, если она выполняется в новом потоке, а если мы сразу схалявим и скажем, что все готово (т.е. вслед за вышепереупомянутой функцией сразу вызываем ReportStatus(SERVICE_RUNNING, NO_ERROR, 0)). В чем смысл SERVICE_START_PENDING'а ?

Спасибо огромное Messir!

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
А вот код с учетом замечаний Messir:

HANDLE hEvent;
HANDLE hThread;
SERVICE_STATUS_HANDLE ssh;
SERVICE_STATUS ss;

//-------------------------------------------------------------------------------------------

VOID WINAPI ServiceMain(DWORD argc, LPSTR *argv)
{
DWORD dwThreadId;

if(!(ssh = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceControl))) return;

ss.dwServiceSpecificExitCode = 0;
ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS;

if (!ReportStatus(SERVICE_START_PENDING, NO_ERROR, 5000))
{
MyLog('Ошибка установки статуса в SERVICE_START_PENDING
');
ReportStatus(SERVICE_STOPPED, NOERROR, 0);
return;
}

if (!(hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
{
MyLog('Ошибка создания объекта Event
');
ReportStatus(SERVICE_STOPPED, NOERROR, 0);
return;
}

if (!(hThread =
0
Messir
25.06.2011, 19:41
2. Только если это нужно автору для каких-либо целей. Сервису пофиг на это, он так или иначе корректно отработает.
2а. В силу вышесказанного - ждать того, что требуется, или не ждать ничего...

4. Ну, тогда нужно предусмотреть ожидание завершения потока, и, в случае если он не завершается в течение какого-то времени, прибивать его насильно.

6. ближе всего к в)

- SetLastError(0) - чтобы уведомить о корректном завершении сервиса, даже если какая-то функция внутри него завершилась с ошибками.
- Никак не надо узнавать. См. описания ResumeThread и SuspendThread.
- SERVICE_ACCEPT_PAUSE_CONTINUE
- RegisterServiceCtrlHandler - да, а вот быстрой инициализации - ничего такого не оговаривается.
1 / 1 / 0
Регистрация: 22.04.2011
Сообщений: 47
25.06.2011, 21:13
Спасибо большое.
Я вообще такой человек: мне мало знать 'как надо', мне еще всегда интересно 'а почему именно так?'. Вы практически полностью развеяли мои сомнения и терпеливо разжевали все. Уважаю!!!

... и последние два вопроса:
- >> Никак не надо узнавать. - тогда что можно сделать в такой ситуации, когда наш поток усыпляется посередине записи данных в файл? Ладно handle'ы и т.д. и т.п. - данные можем потерять!!! А в моем приложении это очень критично - что-то типа сетевого брокера локального сервера БД (DCOM и ADO, не устраивает по разным причинам).

- Я вроде разобрался с сокетами, и вроде работает без тормозов: Перегонял большие объемы данных как по 10, так и по 100-Мбитной сети. Так вот, индикатор загрузки сети показывал почти 80% (и фактически данные передавались тоже). Если увеличить объем буфера, получается еще больше, однако, у меня иногда бывали сбои. А при 32Кб работает просто шикарно. Блокирующий accept я, при завершении приложения, бужу посылкой запроса на соединение себе же... А обмен с клиентами происходит каждый в своем потоке. Но тут как снимать блокировку и корректо завершать поток не знаю - пока просто прибиваю поток и все
Но вот беда, разобрался я только с блокирующими сокетами, а про асинхронным чего-то очень мало инфы нашел, в общем, не разобрался.
Что посоветуете, оставить все как есть или все-таки попытаться испоьзовать асинхронные?
0
Messir
25.06.2011, 21:19
чтобы решить вопрос с потерей данных, могу предложить следующее: создаем событие, которое будет определять, может ли поток быть усыплен. перед началом критической операции сбрасываем это событие, в конце - устанавливаем. При усыплении сначала ждем этого события, потом усыпляем поток.
1 / 1 / 0
Регистрация: 22.04.2011
Сообщений: 47
25.06.2011, 21:23
А про блокирующие сокетами что скажете?
0
1 / 1 / 0
Регистрация: 22.04.2011
Сообщений: 47
25.06.2011, 21:29
Ну а SERVICE_PAUSE_CONTINUE вместо SERVICE_ACCEPT_PAUSE_CONTINUE - это я конечно же лоханулся. Хотя знал, как должно быть, так сказать, механическая ошибка, но в упор не замечал. Исправил, и конечно же заработало как надо.
0
Messir
25.06.2011, 21:55
не вижу проблемы с блокирующими сокетами.
пока ждем - тред можно смело прибивать/суспендить, когда вышли из ожидания - сбросили евент, разрешающий завершение/суспенд.
или, как вариант - отказаться от блокирующих сокетов в пользу ManualResetEvent'ов
1 / 1 / 0
Регистрация: 22.04.2011
Сообщений: 47
25.06.2011, 22:20
Ок, спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
25.06.2011, 22:20
Помогаю со студенческими работами здесь

Could not start the service MySQL. Error: 0
Во время установки MySQL при выполнении «Start service» выводит ошибку: Could not start the service MySQL. Error: 0 . Может кто...

Windows service на Python: access denied
ПРЕДИСЛОВИЕ. Начну со ссылки на вопрос на stackoverflow, но там пока ничего не посоветовали. Может, кому-то будет понятнее суть вопроса. ...

General Error SQL ERROR [ mysqli ] Access denied for user 'a5936757_0'@'10.3.2.19' (using password: NO) [1045]
Здравствуйте! Помогите, разобраться, пожалуйста! Я пытаюсь, создать сайт на хостинге 000webhost. Сначала, на локальном сервере...

Ошибка "Access denied" error 5 при вызове VirtualQueryEx
Всем привет. Не могу понять в чём проблема, запускаю программу от имени администратора, но данные не могу получить. Вот кусок кода,...

Ошибка "MySQL error 1044: access denied" при создании таблицы


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 31.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
Автоматическое создание документа при проведении другого документа
Maks 29.03.2026
Реализация из решения ниже выполнена на нетиповых документах, разработанных в конфигурации КА2. Есть нетиповой документ "ЗаявкаНаРемонтСпецтехники" и нетиповой документ "ПланированиеСпецтехники". В. . .
Настройка движения справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru