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 () argv
(с argc
), но вы можете изучить:
wWinMain
CommandLineToArgvW
GetCommandLine
и относительные вещи (такие как wchar_t в Windows)
Если это проект Visual Studio (как <stdafx.h>
настоятельно указывает) тогда:
- Установите для подсистемы Windows в настройках компоновщика.
- Установите точку входа в
mainCRTStartup
(который называет стандартmain
).
Но вы уверены, что хотите этого?
Звучит больше, что вы хотите, чтобы служба Windows?