C++ (VC2010) Помогите преобразовать консольное приложение в скрытое приложение Windows?

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

Например, в VC2010 я сделал два изменения в свойствах проекта, описанных здесь:

преобразовать консольное приложение в приложение Windows

и изменил Main на WinMain, но, конечно, получил сообщения об ошибках от компилятора.

На других страницах я также попытался создать консольное приложение, затем в мастере приложений Win32 и изменить тип приложения на приложение Windows, но я не могу понять, что делать дальше. Я попытался изменить int Main на int CALLBACK WinMain, но, конечно, это тоже не работает.

Есть ли кто-нибудь, кто может помочь новичку в этом? Вот что, я думаю, является важной частью моего кода EDIT: полный код для тех, кто интересуется, для чего он нужен, здесь:

https://www.dropbox.com/s/1h8x1k2zv0lc5d1/vPasteCPlus.txt?dl=0

#include <stdafx.h>
#include <windows.h>
#include <iostream>
#include <fstream>
#include <codecvt> // for wstring_convert
#include <locale>  // for codecvt_byname
using namespace std;

// helper to get path to this application
string ExePath() {
char buffer[MAX_PATH];
GetModuleFileNameA( NULL, buffer, MAX_PATH );
string::size_type pos = string( buffer ).find_last_of( "\\/" );
return string( buffer ).substr( 0, pos);
}

int main(int argc, char* argv[])
{
    // get the command-line argument if any, and do various things
} 

Опять же, извинения за этот вопрос для начинающих. Единственный опыт, который я имею с C++, - это написание консольных приложений, и любые советы будут с благодарностью приняты.

2 ответа

Решение

Итак, вы открыли Visual Studio. И у тебя есть Solution Explorer (Если не, View -> Solution Explorer).

Прежде всего, чтобы сделать приложение Windows, вы должны изменить точку входа с main() (Стандарт C++) в Windows WinMain(), Смотрите MSDN для более подробного описания. Итак, вы меняете main() к следующему (копирование-вставка из документации):

int CALLBACK WinMain(
  _In_ HINSTANCE hInstance,
  _In_ HINSTANCE hPrevInstance,
  _In_ LPSTR     lpCmdLine,
  _In_ int       nCmdShow)
{
    return 0;
}

Конечно, вы должны включить <Windows.h> потому что Windows предоставляет собственный API для работы с системой (например, LPSTR тип). Короче говоря, вы сделали все, что нужно компилятору для компиляции вашей программы. И вы можете построить свое решение (Build -> Build Solution)... это приведет к linker ошибка:

error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup

Опять же, компилятор сделал все, что вы хотите, и компилирует ваш исходный файл в .obj, но, потому что ваш проект настроен для консольного приложения, linker нужна стандартная точка входа для консольного приложения - main и он не может найти (разрешить) его в нашем случае, потому что мы изменили main на WinMain. Чтобы сделать компоновщика счастливым, вы должны сказать это:

  • Щелкните правой кнопкой мыши на проекте внутри Solution Explorer
  • Затем нажмите на Properties: Свойства обозревателя решений
  • Идти к Configuration Properties -> Linker -> System и установить SubSystem в Windows: Конфигурация подсистемы компоновщика

Попробуйте создать приложение еще раз и вуаля - у вас уже нет ошибки компоновщика, потому что ваш компоновщик теперь знает, что ему нужно создать приложение Windows, и нашел точку входа Windows: WinMain()!

Об этом:

// get the command-line argument if any, and do various things

ты должен использовать lpCmdLine параметр WinMain(), Но будьте осторожны, если вы запускаете свою программу (например, so.exe), например:

so.exe arg1 arg2

lpCmdLine является arg1 arg2 строка. Есть много вещей, которые вы можете сделать, чтобы получить arg1 а также arg2 как массив, как в main () argvargc), но вы можете изучить:

  • wWinMain
  • CommandLineToArgvW
  • GetCommandLine

и относительные вещи (такие как wchar_t в Windows)

Если это проект Visual Studio (как <stdafx.h> настоятельно указывает) тогда:

  • Установите для подсистемы Windows в настройках компоновщика.
  • Установите точку входа в mainCRTStartup (который называет стандарт main).

Но вы уверены, что хотите этого?

Звучит больше, что вы хотите, чтобы служба Windows?

Другие вопросы по тегам