#include <QDir>
#include <QString>
#include <QResource>
#include <QTextCodec>
#include <QApplication>
#include "MainWindow.h"
#ifdef WIN32
#include <windows.h>
#include <WinUser.h>
#include <DbgHelp.h>
#include <Shellapi.h>
#endif
QString gExceptionTitle;
QString gExceptionPrompt;
#ifdef WIN32
//输出崩溃
LONG ApplicationCrashHandler(EXCEPTION_POINTERS* pException)
{
const QString LOG_DIR = QString("./log");
const QString LOG_FILE_SUFFIX = QString(".log");
qFatal("");
QDir dir(LOG_DIR);
if (!dir.exists())
{
dir.mkdir(LOG_DIR);
}
QDateTime current_date_time = QDateTime::currentDateTime();
QString current_date = current_date_time.toString("yyyyMMdd_hhmmss");
QString time = "crash_" + current_date + LOG_FILE_SUFFIX;
EXCEPTION_RECORD* record = pException->ExceptionRecord;
QString errCode(QString::number(record->ExceptionCode, 16));
QString errAddr(QString::number((uint)record->ExceptionAddress, 16));
QString errFlag(QString::number(record->ExceptionFlags, 16));
QString errPara(QString::number(record->NumberParameters, 16));
qFatal("errCode: ", errCode);
qFatal("errAddr: ", errAddr);
qFatal("errFlag: ", errFlag);
qFatal("errPara: ", errPara);
QString fileName = LOG_DIR + "/" + time;
HANDLE fileHandle = CreateFile((LPCWSTR)fileName.utf16(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (fileHandle != INVALID_HANDLE_VALUE)
{
MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
dumpInfo.ExceptionPointers = pException;
dumpInfo.ThreadId = GetCurrentThreadId();
dumpInfo.ClientPointers = TRUE;
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), fileHandle, MiniDumpNormal, &dumpInfo, NULL, NULL);
CloseHandle(fileHandle);
}
else
{
qFatal("hDumpFile == null");
}
qFatal("end");
MsgDialog::Critical(nullptr, gExceptionTitle, gExceptionPrompt);
resetTaskBar();
return EXCEPTION_EXECUTE_HANDLER;
}
#endif
//输出日志
void outputMessage(QtMsgType type, const QMessageLogContext& context, const QString& msg)
{
const QString LOG_DIR = QString("./log");
const QString LOG_FILE_SUFFIX = QString(".log");
static QMutex mutex;
QMutexLocker lock(&mutex);
QString text;
switch (type)
{
case QtDebugMsg: text = QString("Debug:"); break;
case QtWarningMsg: text = QString("Warning:"); break;
case QtCriticalMsg: text = QString("Critical:"); break;
case QtFatalMsg: text = QString("Fatal:"); break;
}
QString context_info = QString("File:(%1) Line:(%2)").arg(QString(context.file)).arg(context.line);
QString current_date_time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
QString current_date = QString("(%1)").arg(current_date_time);
QString message = QString("%1 %2 %3 %4").arg(text).arg(context_info).arg(msg).arg(current_date);
QDir dir(LOG_DIR);
if (!dir.exists())
{
dir.mkdir(LOG_DIR);
}
QString time = "log_" + QDateTime::currentDateTime().toString("yyyyMMdd_hh") + LOG_FILE_SUFFIX;
static QFile file(LOG_DIR + '/' + time);
if (file.open(QIODevice::WriteOnly | QIODevice::Append))
{
QTextStream text_stream(&file);
text_stream << message << "-fx\n";
file.flush();
file.close();
}
}
void showTaskBar(bool show = true)
{
bool isFullScreen = Config::Boolean(FULL_SCREEN_MODE, false);
#ifdef WIN32
HWND hwnd = ::FindWindow(L"Shell_TrayWnd", NULL);
if (hwnd != NULL && ::IsWindow(hwnd))
{
::ShowWindow(hwnd, !isFullScreen || show ? SW_SHOW : SW_HIDE); // 可能会卡死!!!
}
if (!isFullScreen || show)
{
LPARAM lParam = !isFullScreen ? ABS_ALWAYSONTOP : ABS_AUTOHIDE;
APPBARDATA apBar;
memset(&apBar, 0, sizeof(apBar));
apBar.cbSize = sizeof(apBar);
apBar.hWnd = hwnd;
if (apBar.hWnd != NULL)
{
apBar.lParam = lParam;
SHAppBarMessage(ABM_SETSTATE, &apBar); // 设置任务栏是否自动隐藏
}
}
#endif // WIN32
}
int main(int argc, char* argv[])
{
//QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
QApplication::setAttribute(Qt::AA_UseOpenGLES);// 解决浏览器返回遮罩
QApplication instance(argc, argv);
QString path = qApp->applicationDirPath() + "/skin.rcc";
QFileInfo fi(path);
if (fi.isFile())
{
if (QResource::registerResource(path))
{
Q_CLEANUP_RESOURCE(Home); // 卸载资源文件 Home.qrc
FXD << "skin.rcc 加载成功";
}
}
instance.setWindowIcon(QIcon(":/Resources/ic_launcher.ico"));
QApplication::setApplicationVersion(QString("V1.1.2.1"));
QSplashScreen splash(true);
#ifdef _DEBUG
splash.showMessage(QApplication::translate("rollingman", "Please waiting..."), Qt::AlignHCenter | Qt::AlignBottom, Qt::white);
FXD << "QSslSocket=" << QSslSocket::sslLibraryBuildVersionString();
FXD << "OpenSSL支持情况:" << QSslSocket::supportsSsl();
#endif
splash.show();
QTextCodec* codec = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForLocale(codec);
QFile qss(":/Resources/qss/style.qss");
bool open = qss.open(QFile::ReadOnly);
if (open)
{
QByteArray ba = qss.readAll();
qApp->setStyleSheet(ba);
qss.close();
}
//日志
#ifndef _DEBUG
qInstallMessageHandler(outputMessage);
#endif
//qApp->addLibraryPath(QCoreApplication::applicationDirPath());
#ifdef WIN32
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler);
#endif
MainWindow w;
w.show();
#ifdef _DEBUG
qDebug() << "OpenSSL支持情况:" << QSslSocket::supportsSsl();
qDebug() << "QSslSocket 返回运行时SSL库版本号:" << QSslSocket::sslLibraryVersionNumber();
qDebug() << "QSslSocket 返回运行时SSL库版本号:" << QSslSocket::sslLibraryVersionString();
qDebug() << "QSslSocket 返回编译时SSL(静态库)版本号:" << QSslSocket::sslLibraryBuildVersionString();
qDebug() << "QSslSocket 返回编译时SSL(静态库)版本号:" << QSslSocket::sslLibraryBuildVersionNumber();
#endif
QObject::connect(&w, &MainWindow::SignalProgressMsg, &splash, &SplashScreen::messageChanged);
splash.finish(&w);
int result = instance.exec();
FXC << "Desktop has been end." << result;
if (result == 886)
{
FXC << "Desktop will restart...";
QProcess::startDetached(qApp->applicationFilePath(), QStringList());
}
#if 1
//kill自己 主线程结束,并不代表主线程资源被释放,如果子线程引用了主线程的资源,可以继续使用
int pid = qApp->applicationPid();
QString killCmd;
#if defined(Q_OS_MACOS)
killCmd = QString("kill -9 %1").arg(pid);
#else
killCmd = QString("taskkill /pid %1 /f").arg(pid);
#endif
QProcess::startDetached(killCmd);
#endif
return result;
}
qt日志输出
最新推荐文章于 2024-05-03 14:04:14 发布