Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C++ Builder
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.11.2017, 19:49   #1
AlexAES
Пользователь
 
Регистрация: 27.02.2017
Сообщений: 28
По умолчанию Из-за приложения глючит explorer.exe - C++ Builder

Привет всем. Написал приложение, которое по заданному интервалу времени осуществляет перезапуск других приложений. Все работает. Однако в процессе тестирования было обнаружено, что через половину суток - сутки возникают проблемы с рабочим столом. На Win7 возникает черный рабочий стол (остается видным только кнопка "Пуск" и панель задач), на WinXP при нажатии правой кнопки мыши вместо контекстного меню открывается черный квадрат. При этом есть возможность зайти в диспетчер задач, перезапустить explorer.exe и на некоторое время проблема устраняется. Вот код:
Код:
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
#include "IniFiles.hpp"
TForm1 *Form1;
TIniFile *Ini=new TIniFile(ExtractFilePath(Application->ExeName)+"Restarter_config.ini");
 
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void restart(void);   //прототип функци перезапуска приложений
int Sek;              //интервал времени (в сек.) до перезапуска приложений
char Moxa[][255]={"Moxa1.exe","Moxa2.exe","Moxa3.exe","Moxa4.exe"};   //название приложений, кот. д.б. перезапущены
String Mox[]={Moxa[0],Moxa[1],Moxa[2],Moxa[3]};
int NMox;             //количество этих приложений. Может меняться, берется из ini файла.
int i;                //счетчик цикла
AnsiString command;   //сюда будет записываться команда на убийство приложения
 
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Button1Click(TObject *Sender)   //кнопка старт
{
NMox=Ini->ReadInteger("NMox","NMox1",NMox);          //загружается кол-во программ, подлежащих перезапуску
if (Button1->Caption=="Старт")
  {
  Sek=StrToInt(ComboBox1->Text)*60;
  Timer1->Interval=Sek*1000;                  //задается интервал перезапуска приложений
  restart();
  Timer1->Enabled=true;
  Timer2->Enabled=true;
  Button1->Caption="Стоп";
  ComboBox1->Enabled=false;
  }
else
  {
  Timer1->Enabled=false;
  Timer2->Enabled=false;
  Button1->Caption="Старт";
  ComboBox1->Enabled=true;
  }
}
 //-------------------------------------------------------------------------
 
void restart(void)        //функция перезапуска приложений
{
 for (i=0;i<NMox;i++)
  {
  //----------------закрытие приложения-------------------
  Sleep(1000);
  command =  AnsiString("taskkill.exe /f /im "+Mox[i]);
  WinExec(command.c_str(),SW_HIDE);
   //----------------запуск приложения-------------------
  Sleep(1000);
  STARTUPINFO cif;
  PROCESS_INFORMATION pi;
  GetStartupInfo(&cif);
  CreateProcess(Moxa[i],NULL,NULL,NULL,FALSE,0,NULL,NULL,&cif,&pi);
  }
Sek=StrToInt(Form1->ComboBox1->Text)*60;       //по выполнению этой функции уставить полный интервал времени
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::ComboBox1Change(TObject *Sender)
{
Label4->Caption=IntToStr(StrToInt(ComboBox1->Text)*60);   //надпись с количеством секунд, оставшихся до перезапуска
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Label4->Caption=IntToStr(StrToInt(ComboBox1->Text)*60);   //надпись с количеством секунд, оставшихся до перезапуска
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::RestarterMox1Click(TObject *Sender)
{
Application->Terminate();
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose)    //сворачивание в трей
{
TrayIcon1->Visible=true;
CanClose = false;
ShowWindow(Form1->Handle, SW_HIDE); // спрятать главное окно
ShowWindow(Application->Handle, SW_HIDE);
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::TrayIcon1Click(TObject *Sender)      // разворачивание из трея
{
ShowWindow(Form1->Handle, SW_RESTORE);
ShowWindow(Application->Handle, SW_SHOW);
TrayIcon1->Visible=false;
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Timer1Timer(TObject *Sender)      //старт функции перезапуска приложений
{
restart();        
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Timer2Timer(TObject *Sender)      //таймер, ведет обратный отсчет оставшегося времени до перезапуска
{
Sek--;
Label4->Caption=IntToStr(Sek);
}
AlexAES вне форума Ответить с цитированием
Старый 19.11.2017, 21:03   #2
Black Fregat
Программист
Участник клуба
 
Аватар для Black Fregat
 
Регистрация: 23.06.2009
Сообщений: 1,772
По умолчанию

Попробуйте сделать
Код:
  CloseHandle(pi.hProcess); 
  CloseHandle(pi.hThread);
сразу после CreateProcess(). По идее, должно помочь.

И ещё. Непонятно, зачем Вам читать собственную STARTUPINFO через GetStartupInfo.
Мало ли какие флаги там в ней взведены..
В общем случае её нужно просто обнулить и заполнить поле длины:
Код:
  STARTUPINFO si = {sizeof(STARTUPINFO)};
Black Fregat вне форума Ответить с цитированием
Старый 19.11.2017, 23:17   #3
AlexAES
Пользователь
 
Регистрация: 27.02.2017
Сообщений: 28
По умолчанию

Исправил, как-то так:

Код:
//----------------запуск приложения-------------------
  Sleep(1000);
  STARTUPINFO cif = {sizeof(STARTUPINFO)};
  PROCESS_INFORMATION pi;
  CreateProcess(Moxa[i],NULL,NULL,NULL,FALSE,0,NULL,NULL,&cif,&pi);
  CloseHandle(pi.hProcess); 
  CloseHandle(pi.hThread);
  }
Все верно я Вас понял?
Пошел ставить под наблюдение.
AlexAES вне форума Ответить с цитированием
Старый 20.11.2017, 06:51   #4
AlexAES
Пользователь
 
Регистрация: 27.02.2017
Сообщений: 28
По умолчанию

Результат тот же, глюки продолжаются...
AlexAES вне форума Ответить с цитированием
Старый 20.11.2017, 14:05   #5
Black Fregat
Программист
Участник клуба
 
Аватар для Black Fregat
 
Регистрация: 23.06.2009
Сообщений: 1,772
По умолчанию

Я больше мест утечки навскидку не вижу. Остаётся предположить, что снятие Ваших программ через taskkill имеет какие-то побочные эффекты.

Eсли натравить программу на какой-нибудь нейтральный notepad - останется ли баг?
Black Fregat вне форума Ответить с цитированием
Старый 21.11.2017, 20:45   #6
AlexAES
Пользователь
 
Регистрация: 27.02.2017
Сообщений: 28
По умолчанию

В CreateProcess() указал полный путь, где находится перезапускаемое приложение. Результат положительный. Еще понаблюдаю.
AlexAES вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
explorer.exe SOS!!!!!!!!!! CREAZ Безопасность, Шифрование 2 06.03.2011 14:48
Запуск explorer.exe niki2012 Общие вопросы Delphi 20 13.01.2011 19:35
explorer.exe voland123454321 Операционные системы общие вопросы 11 19.07.2010 13:23
ошибка explorer.exe Bodnya1994 Помощь студентам 5 02.04.2009 21:02
explorer.exe x2 -- ?? h0rr0r Помощь студентам 1 12.01.2009 19:12