C++
VisualStudio
VisualC++
VisualStudio2017

Visual Studio 2017 Update 3 以降で Win32 プロジェクトが作成できなくなった時の対処法

はじめに

Visual Studio 2017 Update 2 以前は、C/C++のプログラミングの学習や、Win32 API を用いたデスクトップアプリの作成を行う際、「新しいプロジェクト」ダイアログで「Win32 プロジェクト」もしくは「Win32 コンソール アプリケーション」を選択してプロジェクトを作成します。

Screenshot_20170824-183231.png

作成したいプロジェクトを選択して、プロジェクトの名前と保存場所を指定して「OK」をクリックすると「Win32 アプリケーション ウィザード」が表示され、空のプロジェクトの作成ができるようになっていました。

Screenshot_20170824-184042.png

しかし最新の Visual Studio 2017 Update 3 以降では、新しいプロジェクトの一覧に「Windows デスクトップ」が追加され、代わりに今まであった Win32 の項目がなくなっています。そのため、今までの方法でプロジェクトを作成することはできなくなっています。

Screenshot_20170824-192806_1.png

一方「Windows コンソールアプリケーション」と「Windows デスクトップアプリケーション」では、いずれもアプリケーション設定が行えるウィザードが一切表示されず、複数のソースコードが追加された状態 (空のプロジェクトではない状態) でプロジェクトが作成されてしまいます。

Screenshot_20170824-195337.png

そこで本記事では、Visual Studio 2017 Update 3 以降で、Win32 プロジェクトと同等のプロジェクトを作成する方法を紹介します。

新しく追加された「Windows デスクトップ ウィザード」を使用

最初に、「新しいプロジェクト」ダイアログで [Visual C++] → [Windows デスクトップ] の順に選択して、その中の「Windows デスクトップ ウィザード」を選択します。

Screenshot_20170824-204251.png

次に、プロジェクトの名前と保存場所を指定して「OK」をクリックします。すると「Windows デスクトップ プロジェクト」というダイアログが現れます。見た目こそ新しいものの、設定できる項目は従来の「Win32 アプリケーション ウィザード」と同じです。

Screenshot_20170824-204641.png

最後に「アプリケーションの種類(T)」を選択して「空のプロジェクト(E)」にチェックを入れ「プリコンパイル済みヘッダー(P)」のチェックを外し「OK」をクリックします。これで、プロジェクトの作成は完了です。

Screenshot_20170824-211111.png

なお、Visual Studio 2017 のリリースノートでは、Win32 プロジェクトの扱いが変わったことが記載されています。

Visual Studio 2017 version 15.3 Release Notes
https://www.visualstudio.com/en-us/news/releasenotes/vs2017-relnotes#a-idclanguageservices-a-c-language-services

"Win32 projects are under the Windows Desktop category in the New Project dialog."
訳「Win32 プロジェクトは、新しいプロジェクトダイアログの Windows デスクトップカテゴリーの下層にあります。」

まさか、マイナーアップデートでプロジェクトの仕様を変更するとは……

追記

2017年10月10日のアップデートで「Windows デスクトップ プロジェクト」ダイアログに「セキュリティ開発ライフサイクル (SDL) チェック(C)」という項目が追加されました。

Screenshot_20171012-174100.png

これは、C言語の scanf() fscanf() wcstombs() など、バッファオーバーランなどの致命的なバグを引き起こす可能性がある関数の使用を制限する Microsoft 独自の機能で、Visual Studio ではプロジェクト作成時にデフォルトで有効に設定されています。
試しに scanf() を含んだソースファイルをコンパイルしようとすると、scanf() が安全でない関数であることから、コンパイルが中断されたことが確認できます。

Screenshot_20171012-172428.png

"scanf: This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details."
訳「scanf: この関数もしくは変数は安全ではないかもしれません。代わりに scanf_s の使用を検討してください。(関数や変数の) 廃止を無効にする際は _CRT_SECURE_NO_WARNINGS を使用してください。詳細はオンラインヘルプをご覧ください。」

「エラー一覧」に書いてある通り、scanf() の代わりに scanf_s() を使うか、#include <stdio.h> の前に #define _CRT_SECURE_NO_WARNINGS という特殊なマクロを記述することで回避できます。

Screenshot_20171012-173733.png

「セキュリティ開発ライフサイクル (SDL) チェック」のチェックを外してプロジェクトを作成することで、使用が制限された関数が「エラー」から「警告」に格下げされ、コンパイルが中断されることなくビルドされます。

Screenshot_20171012-174415.png

Screenshot_20171012-175330.png

ここまでするなら、おとなしく scanf_s() を使った方が良いような……