На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела Visual C++ / MFC / WTL (далее Раздела)
1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Полезные ссылки:
user posted image FAQ Раздела user posted image Обновления для FAQ Раздела user posted image Поиск по Разделу user posted image MSDN Library Online
Модераторы: ElcnU
  
> убить "нежно" процесс , надо закрыть программу
    Есть запущенная программа, могу найти ее handle, как завершить ее, послав ей сообщение WM_CLOSE, или другое че-нить, короче надо так, чтоб она завершилась нормально (в частности надо закрыть 1с, если TerminateProcess(), то она аварийно закрывается). Вот , бьюсь как через handle получить hwnd.
      Может лучше через процесс?
      А окно проще найти через FindWindow...

      Например так:
      ExpandedWrap disabled
         
        HWND window;
        window=FindWindow(0, "Имя окна");
        SendMessage(window,WM_CLOSE,0,0);

      Но я так и не понял, что конкретно тебе нужно...
      Сообщение отредактировано: SimBiOd -
        Хочу заметить, что хендл окна это и есть HWND
          Приведенный ниже код "нежно" убьет даже svchost.exe :D
          ExpandedWrap disabled
             
            namespace API_KILLPROCESSNOW {
            BOOL EnableTokenPrivilege( IN HANDLE htok, IN LPCTSTR szPrivilege, IN OUT TOKEN_PRIVILEGES &tpOld)
            {
                TOKEN_PRIVILEGES tp;
                tp.PrivilegeCount = 1;
                tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
                if( LookupPrivilegeValue( NULL, szPrivilege, &tp.Privileges[0].Luid))
                {
                    DWORD cbOld = sizeof( tpOld);
                    if( AdjustTokenPrivileges( htok, FALSE, &tp, cbOld, &tpOld, &cbOld))
                        return ( ERROR_NOT_ALL_ASSIGNED != GetLastError());
                    else
                        return FALSE;
                }
                return FALSE;
            }
             
            BOOL RestoreTokenPrivilege( IN HANDLE htok, IN const TOKEN_PRIVILEGES &tpOld)
            {
                return AdjustTokenPrivileges( htok, FALSE, const_cast<TOKEN_PRIVILEGES*>(&tpOld), 0, 0, 0);
            }
             
            BOOL EnablePrivilege( IN LPCTSTR szPrivilege)
            {
                HANDLE hToken;
                if( !::OpenProcessToken( ::GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
                    return FALSE;
             
                TOKEN_PRIVILEGES tpOld;
                BOOL bReturn = EnableTokenPrivilege( hToken, szPrivilege, tpOld);
                ::CloseHandle(hToken);
                return bReturn;
            }
             
             
            BOOL AdjustDacl( IN HANDLE h, IN DWORD DesiredAccess)
            {
                SID world = { SID_REVISION, 1, SECURITY_WORLD_SID_AUTHORITY, 0 };
             
                EXPLICIT_ACCESS ea =
                {
                    DesiredAccess,
                    SET_ACCESS,
                    NO_INHERITANCE,
                    {
                        0, NO_MULTIPLE_TRUSTEE,
                        TRUSTEE_IS_SID,
                        TRUSTEE_IS_USER,
                        reinterpret_cast<LPTSTR>(&world)
                    }
                };
                PACL pdacl = NULL;
                DWORD err = SetEntriesInAcl( 1, &ea, 0, &pdacl);
                if( err == ERROR_SUCCESS)
                {
                    err = SetSecurityInfo( h, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, 0, 0, pdacl, 0);
                    LocalFree( pdacl);
                    return err == ERROR_SUCCESS;
                }
                return FALSE;
            }
             
            HANDLE GetProcessHandleWithEnoughRights( IN DWORD PID, IN DWORD AccessRights)
            {
                HANDLE hProcess = ::OpenProcess( AccessRights, FALSE, PID);
                if( !hProcess)
                {
                    HANDLE hpWriteDAC = OpenProcess( WRITE_DAC, FALSE, PID);
                    if( !hpWriteDAC)
                    {
                        HANDLE htok;
                        if( !OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &htok))
                            return FALSE;
             
                        TOKEN_PRIVILEGES tpOld;
                        if( EnableTokenPrivilege( htok, SE_TAKE_OWNERSHIP_NAME, tpOld))
                        {
                            HANDLE hpWriteOwner = OpenProcess( WRITE_OWNER, FALSE, PID);
                            if( hpWriteOwner)
                            {
                                BYTE buf[512]; // this should always be big enough
                                DWORD cb = sizeof( buf);
                                if( GetTokenInformation( htok, TokenUser, buf, cb, &cb))
                                {
                                    DWORD err = SetSecurityInfo(
                                            hpWriteOwner,
                                            SE_KERNEL_OBJECT,
                                            OWNER_SECURITY_INFORMATION,
                                            reinterpret_cast<TOKEN_USER*>(buf)->User.Sid,
                                            0, 0, 0);
                                    if( err == ERROR_SUCCESS)
                                    {
                                        if ( !DuplicateHandle(
                                                GetCurrentProcess(),
                                                hpWriteOwner,
                                                GetCurrentProcess(),
                                                &hpWriteDAC,
                                                WRITE_DAC, FALSE, 0)
                                            )
                                        { hpWriteDAC = NULL; }
                                    }
                                }
                                ::CloseHandle( hpWriteOwner);
                            }
                            RestoreTokenPrivilege( htok, tpOld);
                        }
                        ::CloseHandle( htok);
                    }
             
                    if( hpWriteDAC)
                    {
                        AdjustDacl( hpWriteDAC, AccessRights);
             
                        if ( !DuplicateHandle(
                                GetCurrentProcess(),
                                hpWriteDAC,
                                GetCurrentProcess(),
                                &hProcess,
                                AccessRights,
                                FALSE,
                                0)
                            )
                        { hProcess = NULL; }
                        CloseHandle(hpWriteDAC);
                    }
                }
                return hProcess;
            }
             
            BOOL SlayProcess( IN DWORD PID)
            {
                HANDLE hp = GetProcessHandleWithEnoughRights( PID, PROCESS_TERMINATE);
                if( hp)
                {
                    BOOL bReturn = TerminateProcess( hp, 1);
                    ::CloseHandle(hp);
                    return bReturn;
                }
                return FALSE;
            }
            };
             
             
            int KillProccessByID( DWORD processID , CString name)
            {
                CString m_strPName;
                char szProcessName[MAX_PATH] = "unknown";
                char szPath[MAX_PATH] = "unknown";
                static counter = 0;
             
                HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                               PROCESS_VM_READ,
                                               FALSE, processID );
                if (NULL != hProcess )
                {
                    HMODULE hMod;
                    DWORD cbNeeded;
             
                    if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
                         &cbNeeded) )
                    {
                        GetModuleBaseName( hProcess, hMod, szProcessName,
                                           sizeof(szProcessName) );
                        
                   GetModuleFileNameEx(hProcess, hMod, szPath, sizeof(szPath));
             
                    }
                    else return counter;
                }
                else return counter;
                counter ++;
             
                m_strPName = (LPCTSTR)szPath;
                m_strPName.MakeUpper();
             
                if (strstr(m_strPName, name))
                API_KILLPROCESSNOW::SlayProcess( processID );
                
                return counter;
                CloseHandle( hProcess );
            }


          а вот как это все вызвать:
          ExpandedWrap disabled
             
                DWORD aProcesses[1024], cbNeeded, cProcesses;
                  
                if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
                    return;
             
                cProcesses = cbNeeded / sizeof(DWORD);
                for (UINT i = 0; i < cProcesses; i++ )
                     KillProccessByID( aProcesses[i], "ИМЯ ТВОЕГО ПРОЦЕССА");
            Цитата
            SimBiOd Может лучше через процесс?
            А окно проще найти через FindWindow...
            Вот указатель на процесс я уже нашел, но как его еще можно "убить" кроме как TerminateProcess()? а данная функция для 1с приводит к аварийному закрытию, т.е. не сама она все закрывает, и приходится каждый раз переиндексировать таблицы после такой опреации. Поиск по окну мне кажется не очень оптимальным, т.к. разные конфы могут быть запущены, названия окна может поменяться ..., а так я нахожу процесс инициированный из *.exe 1с программы и пытаюсь его закрыть.

            Цитата
            Metatron Хочу заметить, что хендл окна это и есть HWND

            :no: Это я понимаю, но HWND это указатель на структуру, а у меня handle, т.е. я имел в виду простой указатель на процесс (OpenProcess() его возвращает) (незнаю на что он указывает, наверно на точку входа или еще ченить)

            Dr_ShpitsVogel
            Цитата

            BOOL SlayProcess( IN DWORD PID)
            {
            HANDLE hp = GetProcessHandleWithEnoughRights( PID, PROCESS_TERMINATE);
            if( hp)
            {
            BOOL bReturn = TerminateProcess( hp, 1);//*****************
            ::CloseHandle(hp);
            return bReturn;
            }
            return FALSE;
            }
            };

            Спасибо за пример, нашел в нем много интересного, но все сводится к томуже TerminateProcess(), который мне неподходит...
              Можно так:
              ExpandedWrap disabled
                 
                BOOL CALLBACK EnumWndProc(HWND hWnd, LPARAPM pid)
                {
                DWORD wndpid;
                GetWindowThreadProcessId(hWnd, &wndpid);
                if (wndpid != pid)
                   return TRUE;
                PostMessage(hWnd, WM_CLOSE, 0, 0);
                }
                 
                void KillProcessSoftly(DWORD pid)
                {
                EnumDesktopWindows(NULL, EnumWndProc, pid);
                }

              Т. е. ты перебираешь все окна на десктопе пока не найдешь то, которое принадлежит заданному процессу, после чего посылаешь этому окну WM_CLOSE.
              На вход этой функции нужен Process Id.
                Flex Ferrum спасибо, работает как надо :no:
                  при более тщательном осмотре столкнулся с проблемой, когда посылается сообщение WM_CLOSE, то выскакивает MessageBox или Диалог ("действительно ли вы хотите выйти из прогрммы?"), где надо нажать кнопку Да или Ok. Вот решил эту проблему следующим образом:
                  Заранее говорю, что практики работы с окнами мало, и нижеприведенный код не претендует на оптимальность и т.д., безусловно есть много других способов более практичных.
                  ExpandedWrap disabled
                    BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
                    {
                        char str[50];
                        DWORD wndpid;
                     
                        GetWindowThreadProcessId(hwnd, &wndpid);
                        if(wndpid!=lParam)
                            return TRUE;
                        GetWindowText(hwnd,str,sizeof(str));
                        if(strstr(str,"Да")||strstr(str,"Ok")||strstr(str,"OK"))
                        {
                            int id=GetDlgCtrlID(hwnd);
                            hwnd=GetParent(hwnd);
                            SendMessage(hwnd,WM_COMMAND,LOWORD(id),0);
                        };
                        return TRUE;
                    }
                     
                    BOOL CALLBACK EnumWndProc(HWND hWnd, long pid)
                    {
                    DWORD wndpid;char str[255];
                    //GetWindowModuleFileName(hWnd,str,sizeof(str)); - никак не запускается, файлы *.h и *.lib подключены
                    GetWindowThreadProcessId(hWnd, &wndpid);
                    if (wndpid != pid)
                       return TRUE;
                    PostMessage(hWnd, WM_CLOSE, 0, 0);
                    HWND hw=GetLastActivePopup(hWnd);
                    if(hw!=hWnd)
                        EnumChildWindows(hw,EnumChildProc,pid);
                    }
                    А почему бы вместо WM_CLOSE не слать WM_QUIT ?
                    Тогда, вроде, вообше никакие окна с подтверждениями не выскакивают. :)
                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                    0 пользователей:


                    Рейтинг@Mail.ru
                    [ Script execution time: 0,0766 ]   [ 16 queries used ]   [ Generated: 5.11.25, 18:55 GMT ]