Russian Qt Forum

Qt => Общие вопросы => Тема начата: iukash от Ноябрь 09, 2010, 12:53



Название: Как программно выключить компьютер
Отправлено: iukash от Ноябрь 09, 2010, 12:53
Собственно вопрос, есть несколько компьютеров с виндой в локальной сети, как можно программно один компьютер выключить с другого компьютера, или хотя бы один без сети как выключить программно?


Название: Re: Как программно выключить компьютер
Отправлено: Sancho_s_rancho от Ноябрь 09, 2010, 13:00
Собственно вопрос, есть несколько компьютеров с виндой в локальной сети, как можно программно один компьютер выключить с другого компьютера, или хотя бы один без сети как выключить программно?
Код:
QProcess::startDetached("shutdown -s -f -t 00");


Название: Re: Как программно выключить компьютер
Отправлено: iukash от Ноябрь 09, 2010, 13:36
Цитировать
shutdown -s -f -t 00
Извините а что означают эти ключи после shutdown?


Название: Re: Как программно выключить компьютер
Отправлено: Пантер от Ноябрь 09, 2010, 13:39
Почитай
shutdown /?


Название: Re: Как программно выключить компьютер
Отправлено: sendevent от Ноябрь 09, 2010, 13:45
ну мож винды нету у человека и трафик считается ;D
Код:
-s - stop (для рибута - -r);
-f - force;
-t - time (кажись, в секундах);
00 - количество того самого тайма, второй ноль - видимо, очепятка (для "неотменяемой" операции "прямо щас" достаточного одного).
если тайм задан !0 - можно успеть отменить выключение/ребут опцией -a (abort).
также понимает имена/адреса машин в локалке, может показать сообщение а-ля "плановая перезагрузка инициирована админом"+таймер.


Название: Re: Как программно выключить компьютер
Отправлено: iukash от Ноябрь 09, 2010, 14:05
Всем спасибо огромное!


Название: Re: Как программно выключить компьютер
Отправлено: iukash от Ноябрь 09, 2010, 18:18
Пишу так
Цитировать
QProcess::startDetached(tr("shutdown -s -f -c \"Запланированная остановка\" -t 10 -m 192.168.0.85"));
Если задаю ip компьютера на котором запускаю то себя он выключает, а если компьютера из сети то не выключает (Причем сеть нормальная, данные передаются и принимаются другими прогами)! В чем может быть проблема?


Название: Re: Как программно выключить компьютер
Отправлено: stump от Ноябрь 09, 2010, 19:37
А учетные записи на удаленном и локальном компах одинаковые???
Возможно в этом проблема...хотя я бы посоветовал для этих целей использовать wmi... исходники, если что, могу выложить...


Название: Re: Как программно выключить компьютер
Отправлено: iukash от Ноябрь 09, 2010, 19:42
Учетные записи разные, а как решить эту проблему? С разными учетными некак?
Цитировать
хотя я бы посоветовал для этих целей использовать wmi... исходники, если что, могу выложить...
что такое wmi?


Название: Re: Как программно выключить компьютер
Отправлено: stump от Ноябрь 09, 2010, 20:07
Учетные записи разные, а как решить эту проблему?
попробуй создать на удаленном компе учетку с такими же реквизитами, как и на локальном... или наоборот.

Цитировать
С разными учетными некак?
можно...через wmi.
проще говоря, wmi предоставляет интерфейс доступа к комп. системам под управлением Windows. делаешь коннект к менеджеру объектов на удаленном компе и ты можешь делать с ним все, что тебе захочется...и получить всю возможную инфу от ОС...
лично я юзал wmi для получения информации с удаленного компа о запущенных процессах, загрузке проца, страничного файла, сети, дисков...для слежения за определенными процессами...для запуска приложений и для его перезагрузки.
во всем остальном...гугль тебе в помощь...



Название: Re: Как программно выключить компьютер
Отправлено: iukash от Ноябрь 09, 2010, 20:19
Проблема не в учетных записях, сделал их всех с именем Admin,(а у некоторых совпадали и до изменения) не помогло!


Название: Re: Как программно выключить компьютер
Отправлено: stump от Ноябрь 09, 2010, 20:29
Проблема не в учетных записях, сделал их всех с именем Admin,(а у некоторых совпадали и до изменения) не помогло!

пароли тоже совпадают??? пустые пароли не прокатят...


Название: Re: Как программно выключить компьютер
Отправлено: iukash от Ноябрь 10, 2010, 10:20
Одинаковый пароль admin тоже не помог! :(
Цитировать
хотя я бы посоветовал для этих целей использовать wmi... исходники, если что, могу выложить...
Выложите исходники пожалуйста!


Название: Re: Как программно выключить компьютер
Отправлено: Пантер от Ноябрь 10, 2010, 10:23
Скорее всего нужно политики настраивать. Это было бы неправильно, если бы любой компьютер из сети мог бы выключить другой компьютер.


Название: Re: Как программно выключить компьютер
Отправлено: iukash от Ноябрь 10, 2010, 11:03
Блин, мне отказано в доступе, точно! Может кто знает как права настроить?


Название: Re: Как программно выключить компьютер
Отправлено: Пантер от Ноябрь 10, 2010, 11:16
Команда mmc, там добавляешь оснастку (не помню какую) и настраиваешь. Но это тебе уже не другой форум.


Название: Re: Как программно выключить компьютер
Отправлено: stump от Ноябрь 10, 2010, 14:07
Код:

bool Reboot()
{
DWORD Res=0;

IWbemLocator  *locator=NULL;
IWbemServices *pSvc=NULL;
IWbemClassObject *object=NULL;

COAUTHIDENTITY *userAcct=NULL;

Res=CoInitializeEx(0,COINIT_MULTITHREADED);

if(Res!=NO_ERROR)
{
qDebug()<<"Error CoInitialize";
return 0;
}
Res=CoInitializeSecurity(NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
NULL
);
if(Res!=NO_ERROR)
{
qDebug()<<"Error CoInitializeSecurity";
return 0;
}

Res=CoCreateInstance(CLSID_WbemLocator,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
(LPVOID*)&locator
);

if(Res!=NO_ERROR)
{
qDebug()<<"Error CoCreateInstance";

CoUninitialize();
return 0;
}

Res=locator->ConnectServer(_bstr_t(L"\\\\server\\root\\cimv2"),     //вместо server - имя удаленного компа или его IP
   _bstr_t(L"Admin"),   //логин
   _bstr_t(L"1"),       //пароль
   NULL,
   NULL,
   NULL,
   NULL,
   &pSvc
   );

if(Res!=NO_ERROR)
{
qDebug()<<"Error ConnectServer";
locator->Release();

CoUninitialize();
return 0;
}

userAcct=new COAUTHIDENTITY;
ZeroMemory(userAcct,sizeof(COAUTHIDENTITY));

QString *login = new QString("Admin"); //входные параметры
QString *password = new QString("1");

std::wstring log = login->toStdWString();
std::wstring pas = password->toStdWString();

userAcct->User = (USHORT*)log.c_str();
userAcct->UserLength = login->length();

userAcct->Password = (USHORT*)pas.c_str();;
userAcct->PasswordLength = password->length();

userAcct->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;

Res = CoSetProxyBlanket(
pSvc,                           
RPC_C_AUTHN_DEFAULT ,     
RPC_C_AUTHZ_DEFAULT,           
NULL,    
RPC_C_AUTHN_LEVEL_CALL ,    
RPC_C_IMP_LEVEL_IMPERSONATE,   
userAcct,                       
EOAC_NONE   
);

if(Res!=NO_ERROR)
{
qDebug()<<"Error CoSetProxyBlanket";
pSvc->Release();
locator->Release();

CoUninitialize();
return 0;
}

IEnumWbemClassObject *pEnumerator = NULL;
Res = pSvc->ExecQuery(_bstr_t(L"WQL"),
  _bstr_t(L"SELECT * FROM Win32_OperatingSystem"),
  WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
  NULL,
  &pEnumerator);

if(Res!=NO_ERROR)
{
qDebug()<<"Error ExecQuery";
pSvc->Release();
locator->Release();

CoUninitialize();
return 0;
}

Res = CoSetProxyBlanket(
pEnumerator,                         
RPC_C_AUTHN_DEFAULT ,   
RPC_C_AUTHZ_DEFAULT,           
NULL,    
RPC_C_AUTHN_LEVEL_CALL ,    
RPC_C_IMP_LEVEL_IMPERSONATE,   
userAcct,                       
EOAC_NONE   
);

if(FAILED(Res))
{
pEnumerator->Release();
pSvc->Release();
locator->Release();
CoUninitialize();

return 0;
}

IWbemClassObject  *System = NULL;
ULONG Returned = 0;

Res = pEnumerator->Next(WBEM_INFINITE,
1,
&System,
&Returned);

if(Res != NO_ERROR)
{
pEnumerator->Release();
pSvc->Release();
locator->Release();
CoUninitialize();

return 0;
}

VARIANT var;
ZeroMemory(&var,sizeof(VARIANT));

Res = System->Get(L"Name",0,&var,NULL,NULL);

if(Res != NO_ERROR && var.vt != VT_BSTR)
{
System->Release();
pEnumerator->Release();
pSvc->Release();
locator->Release();
CoUninitialize();

return 0;
}

QString name(_com_util::ConvertBSTRToString(var.bstrVal));
QString objPath("Win32_OperatingSystem.Name=\""+ name +"\"");

objPath.replace(QString("\\"),QString("\\\\"));

Res = pSvc->ExecMethod(_com_util::ConvertStringToBSTR(objPath.toStdString().c_str()),_bstr_t(L"Shutdown"),0,NULL,NULL,NULL,NULL);

if(Res != NO_ERROR)
{
SysFreeString(var.bstrVal);
System->Release();
pEnumerator->Release();
pSvc->Release();
locator->Release();
CoUninitialize();

return 0;
}

SysFreeString(var.bstrVal);
System->Release();
pEnumerator->Release();
pSvc->Release();
locator->Release();
CoUninitialize();

return 1;
}



Название: Re: Как программно выключить компьютер
Отправлено: iukash от Ноябрь 10, 2010, 14:42
stump спасибо за код но проект не компилится, вот только часть ошибок
Цитировать
mainwindow.cpp: In member function 'bool MainWindow::Reboot()':

mainwindow.cpp:73: error: 'DWORD' was not declared in this scope

mainwindow.cpp:73: error: expected ';' before 'Res'

mainwindow.cpp:75: error: 'IWbemLocator' was not declared in this scope

mainwindow.cpp:75: error: 'locator' was not declared in this scope

mainwindow.cpp:76: error: 'IWbemServices' was not declared in this scope

mainwindow.cpp:76: error: 'pSvc' was not declared in this scope

mainwindow.cpp:77: error: 'IWbemClassObject' was not declared in this scope

mainwindow.cpp:77: error: 'object' was not declared in this scope

mainwindow.cpp:79: error: 'COAUTHIDENTITY' was not declared in this scope

mainwindow.cpp:79: error: 'userAcct' was not declared in this scope

mainwindow.cpp:81: error: 'Res' was not declared in this scope

mainwindow.cpp:81: error: 'COINIT_MULTITHREADED' was not declared in this scope

mainwindow.cpp:81: error: 'CoInitializeEx' was not declared in this scope

mainwindow.cpp:83: error: 'NO_ERROR' was not declared in this scope

mainwindow.cpp:92: error: 'RPC_C_AUTHN_LEVEL_DEFAULT' was not declared in this scope
Мне наверное какой то ашник подключить надо или что?


Название: Re: Как программно выключить компьютер
Отправлено: Пантер от Ноябрь 10, 2010, 14:47
#include <qt_windows.h>


Название: Re: Как программно выключить компьютер
Отправлено: iukash от Ноябрь 10, 2010, 14:49
Добавил qt_windows.h ушел целый ряд проблем остались эти
Цитировать
mainwindow.cpp: In member function 'bool MainWindow::Reboot()':

mainwindow.cpp:76: error: 'IWbemLocator' was not declared in this scope

mainwindow.cpp:76: error: 'locator' was not declared in this scope

mainwindow.cpp:77: error: 'IWbemServices' was not declared in this scope

mainwindow.cpp:77: error: 'pSvc' was not declared in this scope

mainwindow.cpp:78: error: 'IWbemClassObject' was not declared in this scope

mainwindow.cpp:78: error: 'object' was not declared in this scope

mainwindow.cpp:80: error: 'COAUTHIDENTITY' was not declared in this scope

mainwindow.cpp:80: error: 'userAcct' was not declared in this scope

mainwindow.cpp:105: error: 'CLSID_WbemLocator' was not declared in this scope

mainwindow.cpp:108: error: 'IID_IWbemLocator' was not declared in this scope

mainwindow.cpp:120: error: '_bstr_t' was not declared in this scope

mainwindow.cpp:139: error: expected type-specifier before 'COAUTHIDENTITY'

mainwindow.cpp:139: error: expected ';' before 'COAUTHIDENTITY'

mainwindow.cpp:177: error: 'IEnumWbemClassObject' was not declared in this scope

mainwindow.cpp:177: error: 'pEnumerator' was not declared in this scope

mainwindow.cpp:180: error: 'WBEM_FLAG_RETURN_IMMEDIATELY' was not declared in this scope

mainwindow.cpp:180: error: 'WBEM_FLAG_FORWARD_ONLY' was not declared in this scope

mainwindow.cpp:215: error: 'System' was not declared in this scope

mainwindow.cpp:218: error: 'WBEM_INFINITE' was not declared in this scope

mainwindow.cpp:249: error: '_com_util' has not been declared

mainwindow.cpp:254: error: '_com_util' has not been declared


Название: Re: Как программно выключить компьютер
Отправлено: stump от Ноябрь 10, 2010, 19:37
Виноват...забыл)))
Код:

#include <windows.h>
#include <comutil.h>

#define _WIN32_DCOM
#include <comdef.h>
#include <Wbemidl.h>

#pragma comment(lib, "wbemuuid.lib")


и wbemuuid.lib к проекту подключи...


Название: Re: Как программно выключить компьютер
Отправлено: iukash от Ноябрь 11, 2010, 15:44
Блин, не работает! У меня Qt + MinGW думаю в этом проблема!