📄 svcprowindow.cpp
字号:
// Copyright E骾n O'Callaghan 2008 - 2008.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "StdAfx.hpp"
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/xpressive/xpressive.hpp>
#include <boost/threadpool.hpp>
#include "SvcProWindow.hpp"
#include "ExportTreeDlg.hpp"
#include "CSSFileDialog.hpp"
#include "nt_service_control_manager.hpp"
#include "nt_service.hpp"
#include "enum_services_sequence.hpp"
void SvcProWindow::DoCreateUI()
{
WTL::CRect rc;
GetClientRect(rc);
h_split_.Create(m_hWnd, rc, NULL, WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
m_hWndClient = h_split_.m_hWnd;
v_split_.Create(h_split_, rc, NULL, WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
tabbed_dialog_.Create(h_split_);
tabbed_dialog_.ShowWindow(SW_SHOW);
h_split_.SetSplitterPanes(v_split_, tabbed_dialog_);
sort_list_.Create(v_split_, rc, NULL,
LVS_REPORT|WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|LVS_SHOWSELALWAYS,LVS_EX_CHECKBOXES);
tree_view_.Create(v_split_, rc, NULL,
LVS_REPORT|WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|LVS_SHOWSELALWAYS);
v_split_.SetSplitterPanes(tree_view_, sort_list_);
MoveWindow(rect_.left, rect_.top, rect_.right-rect_.left, rect_.bottom-rect_.top, false);
v_split_.SetSplitterPos(v_split_position_);
h_split_.SetSplitterPos(h_split_position_);
}
void SvcProWindow::DoCreateReBar()
{
// Check if Common Controls 6.0 are used. If yes, use 32-bit (alpha) images
// for the toolbar and command bar. If not, use the old, 4-bit images.
UINT uResID = IDR_MAINFRAME_OLD;
DWORD dwMajor = 0;
DWORD dwMinor = 0;
HRESULT hRet = ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor);
if(SUCCEEDED(hRet) && dwMajor >= 6)
uResID = IDR_MAINFRAME;
// create command bar window
cmd_bar_.Create(m_hWnd, rcDefault, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE);
cmd_bar_.AttachMenu(GetMenu());
cmd_bar_.LoadImages(uResID);
// remove old menu
SetMenu(NULL);
HWND tool_bar = CreateSimpleToolBarCtrl(m_hWnd, uResID, FALSE, ATL_SIMPLE_TOOLBAR_PANE_STYLE);
CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);
AddSimpleReBarBand(cmd_bar_, NULL, false);
AddSimpleReBarBand(tool_bar, NULL, true);
}
LRESULT SvcProWindow::OnCreate(LPCREATESTRUCT lpcs)
{
DoCreateReBar();
m_hWndStatusBar = status_bar_.Create(*this);
UIAddStatusBar(m_hWndStatusBar);
int panes[] = {ID_DEFAULT_PANE, IDS_SERVICES_TO_APPLY, IDS_BACKUP_CREATED};
status_bar_.SetPanes(panes, 3, false);
DoCreateUI();
iniClass::LoadSettings();
scan_and_load(aux::app.non_roaming_directory());
if (user_save_directory_ != aux::app.non_roaming_directory().string())
scan_and_load(user_save_directory_);
sort_list_.set_overview_mode(true);
update_title();
if (first_run_ && MessageBox(L"Welcome, this appears to be the first time ServiceProfiles has been started. It is recommended that you create a backup file of the current NT Services state so that you can revert back to this state at anytime.\r\n\r\nDo you wish to create such a backup now? You can also make additional backups from the options menu.",
L"ServiceProfiles", MB_YESNO) == IDYES)
{
OnSaveBackup(0,0,0);
}
first_run_ = false;
SetMsgHandled(false);
return 0;
}
void SvcProWindow::VerifyBackupFile()
{
aux::txml_ini service_ini(aux::app.non_roaming_directory()/L"services_backup.xml");
aux::txml_ini_adapter adapter("services_backup", service_ini);
if (!service_ini.load_data())
{
logger.post(new event_type(event_logger::info, L"No existing backup file!"));
nt_service_control_manager_ptr
sc(new nt_service_control_manager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ENUMERATE_SERVICE));
logger.post(new event_type(event_logger::info, L"Building new list..."));
std::vector<nt_service::service_settings> services;
enum_services_sequence ess(sc, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL);
for (enum_services_sequence::const_iterator i = ess.begin(), e = ess.end(); i != e; ++i)
{
try
{
nt_service svc(*i, SERVICE_QUERY_STATUS|SERVICE_QUERY_CONFIG);
services.push_back(nt_service::service_settings(svc));
}
catch(const std::exception& e)
{
aux::wlog() << boost::wformat(L" !! std::exception: %1%") % e.what();
}
}
logger.post(new event_type(event_logger::info, L"List complete."));
std::stringstream xml_data;
{
aux::xml::txml_oarchive oxml(xml_data);
oxml << boost::serialization::make_nvp("services", services);
}
adapter.save_stream_data(xml_data);
service_ini.save_data();
logger.post(new event_type(event_logger::info, L"List saved!"));
return;
}
std::vector<nt_service::service_settings> services;
std::stringstream xml_data;
adapter.load_stream_data(xml_data);
{
aux::xml::txml_iarchive ixml(xml_data);
ixml >> boost::serialization::make_nvp("services", services);
}
logger.post(new event_type(event_logger::info, wformat(L"Loaded backup file, %1% enteries.") % services.size()));
std::sort(services.begin(), services.end());
nt_service_control_manager_ptr
sc(new nt_service_control_manager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ENUMERATE_SERVICE));
enum_services_sequence ess(sc, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL);
for (enum_services_sequence::const_iterator i = ess.begin(), e = ess.end(); i != e; ++i)
{
try
{
nt_service svc(*i, SERVICE_QUERY_STATUS|SERVICE_QUERY_CONFIG);
nt_service::service_settings current_settings(svc);
std::vector<nt_service::service_settings>::iterator ss_i =
std::lower_bound(services.begin(), services.end(), current_settings);
if (ss_i != services.end() && *ss_i == svc)
{
logger.post(new event_type(event_logger::info,
wformat(L"Service %1% found.") % svc.lpServiceName()));
if (!(*ss_i).compare_state(svc))
{
logger.post(new event_type(event_logger::info, L"Settings changed!"));
svc.ApplySettings(*ss_i);
}
}
}
catch(const std::exception& e)
{
aux::wlog() << boost::wformat(L" !! std::exception: %1%") % e.what();
}
}
}
void SvcProWindow::OnFileNew(UINT uCode, int nID, HWND hwndCtrl)
{
OnObserveMode(0,0,0);
new_profile(WTL::CTreeItem());
return;
}
void SvcProWindow::new_profile(WTL::CTreeItem ti_p)
{
WTL::CTreeItem new_file;
size_t i = 0;
sort_list_.set_overview_mode(false);
if (ti_p)
{
i = profiles_.new_profile(L"(New Profile)", ti_p.GetData());
new_file = tree_view_.InsertItem(L"(New Profile)", ti_p, TVI_LAST);
std::set<nt_service::service_settings> service_settings_set;
build_inherted_settings(profiles_.get_profile(i), service_settings_set);
sort_list_.update_with_settings(service_settings_set);
}
else
{
i = profiles_.new_profile(L"(New Profile)");
new_file = tree_view_.InsertItem(L"(New Profile)", TVI_ROOT, TVI_LAST);
}
profiles_.get_profile(i)->set_saved(false);
active_profile_ = profiles_.get_profile(i);
new_file.SetData(i);
new_file.EditLabel();
}
void SvcProWindow::name_changed(size_t i, std::wstring name)
{
if (name != L"")
{
active_profile_ = profiles_.get_profile(i);
profiles_.set_profile_name(i, name);
logger.post(new event_type(event_logger::info,
boost::wformat(L"Profile named %1%") % name));
active_profile_->set_saved(false);
update_title();
}
else
OnObserveMode(0,0,0);
}
void SvcProWindow::OnFileSave(UINT uCode, int nID, HWND hwndCtrl)
{
if (!active_profile_)
{
MessageBox(L"No profile selected!", L"ServiceProfiles", 0);
return;
}
active_profile_->settings() = sort_list_.get_checked_settings();
/* if (!active_profile_->filename())
active_profile_->set_filename(
boost::filesystem::wpath(user_save_directory_) /
(active_profile_->name() + L".spxml"));
*/
profiles_.save_profile(active_profile_);
update_title();
}
void SvcProWindow::OnObserveMode(UINT uCode, int nID, HWND hwndCtrl)
{
if (active_profile_ && !active_profile_->saved() &&
MessageBox(L"Do you want to save the current profile before switching to Overview Mode?",
L"ServiceProfiles", MB_YESNO) == IDYES)
{
OnFileSave(0,0,0);
}
active_profile_.reset();
sort_list_.set_overview_mode(true);
update_title();
}
void SvcProWindow::OnOptionsApply(UINT uCode, int nID, HWND hwndCtrl)
{
if (!active_profile_)
{
MessageBox(L"No profile selected!", L"ServiceProfiles", 0);
return;
}
std::wstring msg;
if (!active_profile_->saved())
msg = L"Are you sure you wish to save and the apply this profile?";
else
msg = L"Are you sure you wish to apply this profile?";
if (MessageBox(msg.c_str(), L"ServiceProfiles", MB_YESNO) == IDYES)
{
if (!active_profile_->saved()) OnFileSave(0,0,0);
UISetText(1, (boost::wformat(L"Applying profile %1%") % active_profile_->name()).str().c_str());
std::set<nt_service::service_settings> service_settings_set;
build_inherted_settings(active_profile_, service_settings_set);
boost::thread(boost::bind(&SvcProWindow::apply_profile_settings, this, service_settings_set));
}
}
void SvcProWindow::OnSaveBackup(UINT, int, HWND)
{
CSSFileDialog dlgOpen(false, NULL, NULL, OFN_HIDEREADONLY,
L"ServiceProfile Backup. (*.spbxml)|*.spbxml|All Files (*.*)|*.*|", m_hWnd);
if (dlgOpen.DoModal() == IDOK)
{
boost::filesystem::wpath filepath = std::wstring(dlgOpen.m_ofn.lpstrFile);
std::wstring filename = filepath.leaf();
if (!boost::algorithm::contains(filename, L"."))
filename += L".spbxml";
boost::thread(boost::bind(&SvcProWindow::save_backup_file, this, (filepath.branch_path() / filename)));
}
}
void SvcProWindow::save_backup_file(boost::filesystem::wpath filename)
{
aux::txml_ini service_ini(filename);
aux::txml_ini_adapter adapter("services_backup", service_ini);
nt_service_control_manager_ptr
sc(new nt_service_control_manager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ENUMERATE_SERVICE));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -