• Qt界面添加拖拽功能

    ·

    发布于

    修改于

    重载两个虚函数

    void dragEnterEvent(QDragEnterEvent *event) override;
    void dropEvent(QDropEvent *event) override;

    设置允许接收拖拽事件并且实现拖拽获取文件路径功能

    #include <QMimeData>
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        this->setAcceptDrops(true);
    }
    
    void MainWindow::dragEnterEvent(QDragEnterEvent *event)
    {
        if (event->mimeData()->hasUrls())
        {
            event->acceptProposedAction();
        }
        else
        {
            event->ignore();
        }
    }
    
    void MainWindow::dropEvent(QDropEvent *event)
    {
        const QMimeData* mimeData = event->mimeData();
        if (mimeData->hasUrls())
        {
            QList<QUrl>urlList = mimeData->urls();
            QString fileName = urlList.at(0).toLocalFile();
            if (!fileName.isEmpty())
            {
                ui->PathLineEdit->setText(fileName);
            }
        }
    }

  • EXE服务进程的生命周期

    ·

    发布于

    修改于

    SERVICE_TABLE_ENTRY	service_table[2];									
    service_table[0].lpServiceName = L"TestService";						
    service_table[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
    service_table[1].lpServiceName = NULL;					
    service_table[1].lpServiceProc = NULL;
    
    StartServiceCtrlDispatcherW(service_table);	

    StartServiceCtrlDispatcher函数会一直阻塞直到使用SetServiceStatus通知SCM本服务已关闭,也就是说只要不通知SCM本服务已关闭,就算ServiceMain返回,该服务进程也会一直存在,原因是主线程阻塞在StartServiceCtrlDispatcher中。


  • 减小PE文件体积

    ·

    发布于

    修改于

    在VC6的时候,减小PE程序的最有效手段就是让程序链接到msvcrt.lib,这样可以消除大量的C库内联函数。但是在现在的VS版本下,只链接msvcrt.lib往往无法编译,经常会有很多C函数找不到。都是自己写的代码还好,可以手动剔除,但是在引入第三方库的时候就难受了。实际上微软更改了CRT,现在只需要同时链接以下3个库就可以生成体积很小,且移植性很好的PE程序(测试了Win7 Starter 32bit和2008r2,都没问题)。

    1. ucrt.lib
    2. libvcruntime.lib
    3. msvcrt.lib

    更具体的内容在https://docs.microsoft.com/zh-cn/cpp/c-runtime-library/crt-library-features?view=msvc-160

    为防止链接挂掉,留一分PDF版本。


  • 一个API搞定创建多级目录

    ·

    发布于

    修改于

    分享一个NB函数,有了它就不需要递归调用CreateDirectory创建多级目录了。相比于SHCreateDirectoryEx创建多级目录,好处不言自明。

    BOOL IMAGEAPI MakeSureDirectoryPathExists(
      PCSTR DirPath
    );

    https://docs.microsoft.com/en-us/windows/win32/api/dbghelp/nf-dbghelp-makesuredirectorypathexists


  • 优雅的重启IIS及相关服务

    ·

    发布于

    修改于

    程序流程如下:

    1. 记录下正在运行的IIS相关服务(这样可以避免在步骤3启动原本服务器上并未开启的服务)
    2. 停止上述服务
    3. 开启上述服务

    可以在步骤2和步骤3之间做一些事情。

    (更多…)


  • GetTempFileName注意事项

    ·

    发布于

    修改于

    调用GetTempFileName获取临时文件名的时候,GetTempFileName函数内部会自动创建这个文件。如果是调用MoveFile将文件移动到这个位置就要注意了,因为MoveFile的目的路径已经存在文件了,移动会失败。解决方法可是先DeleteFile删除文件再MoveFile移动文件,或者使用直接MoveFileEx并指定MOVEFILE_REPLACE_EXISTING参数。


  • base64工具小程序

    ·

    发布于

    修改于

    bin下载: base64.zip
    (更多…)


  • detours demo

    ·

    发布于

    修改于

    #include <Windows.h>
    #include <iostream>
    #include "detours/include/detours.h"
    
    #ifdef _WIN64
    #pragma comment(lib,"detours/lib.X64/detours.lib")
    #else
    #pragma comment(lib,"detours/lib.X86/detours.lib")
    #endif
    INT
    WINAPI
    MsgBox(
        _In_opt_ HWND hWnd,
        _In_opt_ LPCSTR lpText,
        _In_opt_ LPCSTR lpCaption,
        _In_ UINT uType)
    {
        return MessageBoxW(NULL, L"被HOOK了", L"", 0);
    }
    PVOID fpRegisterModule;
    bool Hook(bool restore)
    {
    
        if (restore == false)
            DetourRestoreAfterWith();
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        LONG result;
        if (restore)
            result = DetourDetach(reinterpret_cast<void**>(&fpRegisterModule), MsgBox);
        else
            result = DetourAttach(reinterpret_cast<void**>(&fpRegisterModule), MsgBox);
        DetourTransactionCommit();
        return true;
    }
    
    int main(int argc, char* argv[])
    {
        HMODULE hMod = LoadLibraryA("user32.dll");
        if (hMod == NULL)
        {
            return false;
        }
        fpRegisterModule = GetProcAddress(hMod, "MessageBoxA");
        if (fpRegisterModule == nullptr)
            return false;
        Hook(false);
        MessageBoxA(NULL, "没被HOOK", "没被HOOK", 0);
        Hook(true);
        MessageBoxA(NULL, "没被HOOK", "没被HOOK", 0);
        return 1;
    }

     


  • 使用iisreset.exe的COM接口操作IIS服务

    ·

    发布于

    修改于

    我在实际情况中发现使用关闭Windows服务的方式重启IIS是有一定概率失败的,很可能是由超时时间导致的。使用COM组件的方式重启IIS就没有这个问题,iisreset.exe使用的就是这个COM接口。

    启动、停止Windows服务

    #include <windows.h>
    #include <iisrsta.h>
    const IID IID_IIisServiceControl =
    { 0x0E8FB8620, 0x588F, 0x11D2,
        { 0x9D, 0x61, 0x00, 0xC0, 0x4F, 0x79, 0xC5, 0xFE } };
    
    const GUID CLSID_IisServiceControl =
    { 0x0E8FB8621, 0x588F, 0x11D2,
        { 0x9D, 0x61, 0x00, 0xC0, 0x4F, 0x79, 0xC5, 0xFE } };
    
    int main(int argc, char* argv[])
    {
        HRESULT				result;
        int					rc = -1;
        IIisServiceControl*	IisSrvCtrl = nullptr;
        
        result = CoInitializeEx(0, 0);
        if (result != S_OK)
            return 1;
        do
        {
            result = CoCreateInstance(CLSID_IisServiceControl, 
                                      nullptr, 
                                      CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER | CLSCTX_INPROC_SERVER, 
                                      IID_IIisServiceControl, 
                                      (LPVOID*)&IisSrvCtrl
            );
            if (result != S_OK)
            {
                rc = 2;
                break;
            }
            //如果IIS服务本身就是关闭状态,调用Stop函数返回的也是S_OK
            result = IisSrvCtrl->Stop(60 * 1000, TRUE);
            if (result != S_OK)
            {
                MessageBoxA(NULL, "关闭服务失败", "", 0);
                rc = 3;
                break;
            }
            //
            MessageBoxA(NULL, "成功关闭IIS服务", "", 0);
            result = IisSrvCtrl->Start(60 * 1000);
            if (S_OK != result)
            {
                MessageBoxA(NULL, "启动服务失败", "", 0);
                rc = 4;
                break;
            }
            rc = 0;
        } while (0);
        CoUninitialize();
        return rc;
    }

     


  • 今年打算好好学学这些东西

    ·

    发布于

    修改于

    1. CMake
    2. Visual Studio Code
    3. Qt
    4. Node.js
    5. Electron
    6. Go
    7. C#
    8. .NET Core
    9. WPF
    10. PowerShell
    11. LLVM

最新