イベントログをC++でとりあえず出したい

Visual C++でイベントログを出したかったんですが、まっさらな状態からてっとり早くC++で実装する例がパっと見つけられなくて試行錯誤したので記します。以下の方法は.NET Frameworkを利用したものです。

#環境
Visual Studio 2019(16.11.3) Windows10
※ワークロードは少なくとも**.NETデスクトップ開発**　と **C++によるデスクトップ開発** が適用されている状態

#手順
**1.Visual Studio2019にC ++ / CLIサポートをインストール**
[Microsoft公式ドキュメント](https://docs.microsoft.com/en-us/cpp/dotnet/dotnet-programming-with-cpp-cli-visual-cpp?view=msvc-160)
"Visual Studioインストーラーを開き、[スタート]メニューをと探しVisual Studioのインストーラ。インストールされているバージョンのVisualStudioの横にある[変更]ボタンを選択します。[個々のコンポーネント]タブを選択します。[コンパイラ、ビルドツール、およびランタイム]セクションまで下にスクロールし、v142ビルドツールのC ++ / CLIサポート（最新）を選択します。[変更]を選択して必要なファイルをダウンロードし、VisualStudioを更新します。"

自分の環境にはまずこれがなかったので個別コンポーネントから追加でインストールしました

**2.プロジェクトの新規作成と設定**
Visual Studioを起動し、"新しいプロジェクトの作成"->"コンソールアプリ"("Hello World!"出力するだけのやつ)を選びます。プロジェクト名は任意です。
「共通言語ランタイム サポート(/clr)」を選ぶ
![project_setting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681503/a6d3137b-82de-434b-08e7-255da75fe8ce.png)

**3.サンプルコードをとりあえずコピペ**
プロジェクトのメインソースファイル(プロジェクト名.cpp)に、
Microsoft公式の[イベントログサンプルコード(リンク先ページ下の方)](https://docs.microsoft.com/ja-jp/troubleshoot/cpp/write-entry-to-event-log)をとりあえずコピペ

**4.C++/CLI 構文の基本**
この状態だと演算子の記述について、インテリセンスが赤波線でエラー表示してくるかもしれません。
回避の為、Microsoft公式の[C++/CLI プログラムのドキュメント](https://docs.microsoft.com/ja-jp/cpp/dotnet/walkthrough-compiling-a-cpp-program-that-targets-the-clr-in-visual-studio?view=msvc-160)を確認します。

**インスタンスの変数は^をつけ、インスタンス生成にはgcnewを用いる**　とあります。
そこで、3のコピペしたサンプルコードに適宜変更を加えます。
以下のようなコードにしました。

```C++:プロジェクト名.cpp
#include <stdio.h>
#using <system.dll>
#using <mscorlib.dll>
#include <iostream>

using namespace System;
using namespace System::Diagnostics;
int main()
{
    String^ sSource;
    String^ sLog;
    String^ sEvent;
    sSource = gcnew String("dotNET Sample App1");
    sLog = gcnew String("MyTest01");
    sEvent = gcnew String("Sample Event1");
    
    try
    {
        if (!EventLog::SourceExists(sSource))
            EventLog::CreateEventSource(sSource, sLog);
        EventLog::WriteEntry(sSource, sEvent);
        EventLog::WriteEntry(sSource, sEvent,
            EventLogEntryType::Warning, 234);
        Console::WriteLine("EventLog Succeeded!");
    }
    catch(...)
    {
        Console::WriteLine("An error occurred.");
    }
    std::cin.get();
    return 0;
}
```

**5.コンパイルエラー回避**
コンパイルすると以下エラーが出ると思います
"フェーズの名前参照は、C++/CLI または C++/CX ではサポートされていません。/Zc:twoPhase- を使用してください"
これを回避する為、
**プロパティページで[C/C++]→[言語]の準拠モードが"はい" (/permissive-)になっているので、"いいえ"にします。**
![project_setting2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681503/3422314d-3b96-b9da-01fa-0bdeaff27403.png)

**6.実行時セキュリティエラー回避**
上記設定変更でビルドに成功するようになりました。自分の環境では以下パスにexeが生成されました。
C:\Users\ユーザー名\source\repos\プロジェクト名\x64\Debug

このexeをコマンドラインから起動してみます。すると以下エラーが表示されるかもしれません。
"System.Security.SecurityException: ソースが見つかりませんでしたが、いくつかまたはすべてのログを検索できませんでした。アクセス不可能なログ: Security"

これは実行権限の問題なので以下によって回避できそうです
**・管理者で起動したコマンドプロンプトから実行する**
or
・ログオンユーザーアカウントにイベントログのアクセス許可権限を与えるよう設定変更する

簡易的に今回は、
コマンプロンプトを右クリック"管理者として実行"から起動し、exeを再度実行したら成功しました。
イベントビュワー->カスタムビュー->管理イベント　を見てみると、該当ログが出力されています。
![EventViewer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681503/d6f68d3b-ab98-2373-02ec-6f19ef1e84e9.png)

今回は以上です。
テキスト出力以外でとりあえずログを取りたい場合に利用できていいですね!!