【问题标题】:C++ launching program without console opening无需打开控制台的 C++ 启动程序
【发布时间】:2012-10-05 13:18:08
【问题描述】:

我一直在开发一个应用程序来设置基于我在这里找到的另一个应用程序的桌面背景:http://www.optimumx.com/downloads.html#SetWallpaper。我们的想法是每 10 分钟将背景设置为墙纸,因此它使用命令“SetWallpaper.exe /D:S Wallpaper.jpg”启动 SetWallpaper.exe,但是当我启动我的应用程序时,它会创建一个控制台窗口t 自动关闭,当我手动关闭它时,它会杀死 exe。

#include <windows.h>
int main() {
int i = 1;
int j = 3;
// refresh = time until refresh in minutes
int refresh = 10;
// 1000 milliseconds = 1 second
int second = 1000;
int minute = 60;
int time = second * minute * refresh;
while (i < j) {
system("cmd /c start /b SetWallpaper.exe /D:S Wallpaper.jpg");
Sleep(time);
}
return 0;
}

我尝试使用 MinGW Msys 附带的“sleep.exe”,但这会为每个团队创建一个新进程,最终占用所有进程。

提前致谢!

【问题讨论】:

    标签: c++ console wallpaper


    【解决方案1】:

    您遇到的第一个问题是您将程序创建为带有main 方法的控制台应用程序。相反,将其创建为带有WinMain 入口点的Win32 Project。这将直接调用而不创建控制台窗口。

    编辑: Ferruccio 的回答解决了第二个问题,因为您正在从您的应用程序中调用另一个控制台应用程序,这也将导致创建一个控制台窗口。

    【讨论】:

    • 我真的是 C++ 新手,所以当你说要使用 WinMain 入口点时,我应该将 'int main() {' 更改为 'int WinMain() {' 还是什么?谢谢!
    • 这是在 Visual Studio 中创建新项目时的选项之一。你不能只改变主签名,它就神奇地变成了一个 Win32 应用程序。
    • 我不使用 Visual Studio - 我使用的是 Eclipse CDT
    • 这是不正确的。启动程序是 Windows 应用程序还是控制台应用程序都没有关系。重要的是正在启动的程序是控制台应用程序。
    • @Ferruccio 我没发现system()!尽管实际上两者都很重要,但该程序必须是 Win32 程序才能在不创建控制台窗口的情况下调用 SystemParametersInfo
    【解决方案2】:

    你正在努力解决它。在程序中更改 Windows 壁纸相当简单:

    #include <windows.h>
    
    SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (PVOID) "path/to/wallpaper.jpg", SPIF_UPDATEINIFILE);
    

    无论如何,如果您坚持启动外部程序来执行此操作。使用CreateProcess。通过将dwCreationFlags 参数设置为CREATE_NO_WINDOW,它能够在没有可见窗口的情况下启动控制台模式应用程序。

    【讨论】:

    • 添加此代码并编译后,我现在收到错误:“程序太大而无法放入内存”。我尝试删除代码并重新编译,但仍然出现相同的错误。你知道如何解决这个问题吗?
    • 我设法修复了“程序太大而无法放入内存”错误,但是当我尝试使用您的代码编译我的程序时,它会抛出错误:“initializing argument 3 of 'BOOL SystemParametersInfoA(UINT , UINT, PVOID, UINT)' [-fpermissive]" 我的代码是 "SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, "Wallpaper.jpg", SPIF_UPDATEINIFILE);"
    • 我的错误。第三个参数需要转换为 PVOID。
    【解决方案3】:

    ShowWindow设置为false,最后不要忘记FreeConsole

    #include <windows.h>
    
    
    int main(void)
    {
    
       ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false);
    
       // put your code here
    
       system("cmd /c start /b SetWallpaper.exe /D:S Wallpaper.jpg");
    
       FreeConsole();
    
       return 0;
    }
    

    正如 Ferruccio 所说,您可以使用 SetTimerSystemParametersInfo 定期触发更改。

    #define STRICT 1 
    #include <windows.h>
    #include <iostream.h>
    
    VOID CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime) 
    {
    
      LPWSTR wallpaper_file = L"C:\\Wallpapers\\wallpaper.png";
      int return_value = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, wallpaper_file, SPIF_UPDATEINIFILE);
    
    
      cout << "Programmatically change the desktop wallpaper periodically: " << dwTime << '\n';
      cout.flush();
    }
    
    int main(int argc, char *argv[], char *envp[]) 
    {
        int Counter=0;
        MSG Msg;
    
        UINT TimerId = SetTimer(NULL, 0, 2000, &TimerProc); //2000 milliseconds = change every 2 seconds
    
        cout << "TimerId: " << TimerId << '\n';
       if (!TimerId)
        return 16;
    
       while (GetMessage(&Msg, NULL, 0, 0)) 
       {
            ++Counter;
            if (Msg.message == WM_TIMER)
            cout << "Counter: " << Counter << "; timer message\n";
            else
            cout << "Counter: " << Counter << "; message: " << Msg.message << '\n';
            DispatchMessage(&Msg);
        }
    
       KillTimer(NULL, TimerId);
    return 0;
    }
    

    【讨论】:

    • 关于这种ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false); 方法,窗口是否仍然存在但隐藏了?还是 Windows 真的会杀死它?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-30
    • 1970-01-01
    相关资源
    最近更新 更多