From 5ec6721f1b441d7b9b6b65aa5e7c41330d6de1ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20St=C3=BCrmer?= <michael.stuermer@schaeffler.com>
Date: Wed, 10 Feb 2016 14:37:33 +0100
Subject: [PATCH 1/2] prepared C# support

 - added CSharp module
 - added documentation of new properties
 - added first CSharp test
 - added minor adjustments to some classes
---
 Help/manual/cmake-properties.7.rst                 |   6 +
 .../VS_COPY_LOCAL_SATELLITE_ASSEMBLIES.rst         |   4 +
 Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst    |   4 +
 Help/prop_tgt/VS_DOTNET_REFERENCES.rst             |   2 +
 Help/prop_tgt/VS_DOTNET_REFERENCE_.rst             |  15 ++
 Help/prop_tgt/VS_REFERENCES_PRIVATE.rst            |   4 +
 Help/prop_tgt/VS_USER_PROPS_CSHARP.rst             |   6 +
 Help/prop_tgt/VS_USER_PROPS_CXX.rst                |   6 +
 Modules/CMakeCSharpCompiler.cmake.in               |  12 ++
 Modules/CMakeCSharpInformation.cmake               | 155 ++++++++++++++
 Modules/CMakeDetermineCSharpCompiler.cmake         | 199 ++++++++++++++++++
 Modules/CMakeTestCSharpCompiler.cmake              |  62 ++++++
 Source/cmGlobalVisualStudio71Generator.cxx         |   7 +-
 Source/cmGlobalVisualStudioGenerator.cxx           |  35 ++++
 Source/cmGlobalVisualStudioGenerator.h             |   3 +
 Source/cmSourceFile.h                              |   1 +
 Source/cmVSCSharpFlagTable.h                       | 223 +++++++++++++++++++++
 Source/cmVisualStudioGeneratorOptions.cxx          |  28 ++-
 Source/cmVisualStudioGeneratorOptions.h            |   3 +-
 Tests/CSharp/CMakeLists.txt                        |  14 ++
 Tests/CSharp/CSharp.cs                             |  12 ++
 Tests/CSharp/Properties/AssemblyInfo.cs            |  36 ++++
 22 files changed, 833 insertions(+), 4 deletions(-)
 create mode 100644 Help/prop_tgt/VS_COPY_LOCAL_SATELLITE_ASSEMBLIES.rst
 create mode 100644 Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst
 create mode 100644 Help/prop_tgt/VS_DOTNET_REFERENCE_.rst
 create mode 100644 Help/prop_tgt/VS_REFERENCES_PRIVATE.rst
 create mode 100644 Help/prop_tgt/VS_USER_PROPS_CSHARP.rst
 create mode 100644 Help/prop_tgt/VS_USER_PROPS_CXX.rst
 create mode 100644 Modules/CMakeCSharpCompiler.cmake.in
 create mode 100644 Modules/CMakeCSharpInformation.cmake
 create mode 100644 Modules/CMakeDetermineCSharpCompiler.cmake
 create mode 100644 Modules/CMakeTestCSharpCompiler.cmake
 create mode 100644 Source/cmVSCSharpFlagTable.h
 create mode 100644 Tests/CSharp/CMakeLists.txt
 create mode 100644 Tests/CSharp/CSharp.cs
 create mode 100644 Tests/CSharp/Properties/AssemblyInfo.cs

diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index a41d484..b2b13dd 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -255,7 +255,10 @@ Properties on Targets
    /prop_tgt/TYPE
    /prop_tgt/VERSION
    /prop_tgt/VISIBILITY_INLINES_HIDDEN
+   /prop_tgt/VS_COPY_LOCAL_SATELLITE_ASSEMBLIES
+   /prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY
    /prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION
+   /prop_tgt/VS_DOTNET_REFERENCE_
    /prop_tgt/VS_DOTNET_REFERENCES
    /prop_tgt/VS_DOTNET_TARGET_FRAMEWORK_VERSION
    /prop_tgt/VS_GLOBAL_KEYWORD
@@ -266,10 +269,13 @@ Properties on Targets
    /prop_tgt/VS_IOT_STARTUP_TASK
    /prop_tgt/VS_KEYWORD
    /prop_tgt/VS_MOBILE_EXTENSIONS_VERSION
+   /prop_tgt/VS_REFERENCES_PRIVATE
    /prop_tgt/VS_SCC_AUXPATH
    /prop_tgt/VS_SCC_LOCALPATH
    /prop_tgt/VS_SCC_PROJECTNAME
    /prop_tgt/VS_SCC_PROVIDER
+   /prop_tgt/VS_USER_PROPS_CSHARP
+   /prop_tgt/VS_USER_PROPS_CXX
    /prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
    /prop_tgt/VS_WINRT_COMPONENT
    /prop_tgt/VS_WINRT_EXTENSIONS
diff --git a/Help/prop_tgt/VS_COPY_LOCAL_SATELLITE_ASSEMBLIES.rst b/Help/prop_tgt/VS_COPY_LOCAL_SATELLITE_ASSEMBLIES.rst
new file mode 100644
index 0000000..d722ede
--- /dev/null
+++ b/Help/prop_tgt/VS_COPY_LOCAL_SATELLITE_ASSEMBLIES.rst
@@ -0,0 +1,4 @@
+VS_COPY_LOCAL_SATELLITE_ASSEMBLIES
+----------------------------------
+
+Sets the ``<CopyLocalSatelliteAssemblies>`` property for all references in a CSharp target. Per default it is not defined. Possible values are ``false`` and ``true``. If the property is not set, Visual Studio defaults to ``true``.
diff --git a/Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst b/Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst
new file mode 100644
index 0000000..7e94000
--- /dev/null
+++ b/Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst
@@ -0,0 +1,4 @@
+VS_DEBUGGER_WORKING_DIRECTORY
+-----------------------------
+
+Sets the local debugger working directory for Visual Studio C++ targets. This is defined in ``<LocalDebuggerWorkingDirectory>`` in the Visual Studio project file.
diff --git a/Help/prop_tgt/VS_DOTNET_REFERENCES.rst b/Help/prop_tgt/VS_DOTNET_REFERENCES.rst
index a661ad9..31bfb39 100644
--- a/Help/prop_tgt/VS_DOTNET_REFERENCES.rst
+++ b/Help/prop_tgt/VS_DOTNET_REFERENCES.rst
@@ -5,3 +5,5 @@ Visual Studio managed project .NET references
 
 Adds one or more semicolon-delimited .NET references to a generated
 Visual Studio project.  For example, "System;System.Windows.Forms".
+
+See also :prop_tgt:`VS_DOTNET_REFERENCE_*`
diff --git a/Help/prop_tgt/VS_DOTNET_REFERENCE_.rst b/Help/prop_tgt/VS_DOTNET_REFERENCE_.rst
new file mode 100644
index 0000000..e761aa5
--- /dev/null
+++ b/Help/prop_tgt/VS_DOTNET_REFERENCE_.rst
@@ -0,0 +1,15 @@
+VS_DOTNET_REFERENCE_*
+---------------------
+
+Adds a hint-reference with name ``*`` to the target. The hint path is set to the value of the property.
+
+Example:
+
+.. code-block:: cmake
+
+  set_target_properties(target PROPERTIES
+    VS_DOTNET_REFERENCE_AssemblyName "C:\\path\\to\\assebly.dll")
+
+This will add a reference with name ``AssemblyName`` and filename ``C:\\path\\to\\assebly.dll`` to target.
+    
+See also :prop_tgt:`VS_DOTNET_REFERENCES`
diff --git a/Help/prop_tgt/VS_REFERENCES_PRIVATE.rst b/Help/prop_tgt/VS_REFERENCES_PRIVATE.rst
new file mode 100644
index 0000000..e83f476
--- /dev/null
+++ b/Help/prop_tgt/VS_REFERENCES_PRIVATE.rst
@@ -0,0 +1,4 @@
+VS_REFERENCES_PRIVATE
+---------------------
+
+Sets the ``<Private>`` property for references in CSharp targets. Possible values are ``True`` and ``False``. If the property is not set, Visual Studio defaults to ``True``.
diff --git a/Help/prop_tgt/VS_USER_PROPS_CSHARP.rst b/Help/prop_tgt/VS_USER_PROPS_CSHARP.rst
new file mode 100644
index 0000000..824c08e
--- /dev/null
+++ b/Help/prop_tgt/VS_USER_PROPS_CSHARP.rst
@@ -0,0 +1,6 @@
+VS_USER_PROPS_CSHARP
+--------------------
+
+Sets the user props file to be included in the visual studio C# project file. The standard path is not defined.
+
+The ``*.user.props`` files can be used for Visual Studio wide configuration which is independent from cmake. 
diff --git a/Help/prop_tgt/VS_USER_PROPS_CXX.rst b/Help/prop_tgt/VS_USER_PROPS_CXX.rst
new file mode 100644
index 0000000..5612ca8
--- /dev/null
+++ b/Help/prop_tgt/VS_USER_PROPS_CXX.rst
@@ -0,0 +1,6 @@
+VS_USER_PROPS_CXX
+-----------------
+
+Sets the user props file to be included in the visual studio C++ project file. The standard path is ``$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props``, which is in most cases the same as ``%LOCALAPPDATA%\\Microsoft\\MSBuild\\v4.0\\Microsoft.Cpp.Win32.user.props`` or ``%LOCALAPPDATA%\\Microsoft\\MSBuild\\v4.0\\Microsoft.Cpp.x64.user.props``.
+
+The ``*.user.props`` files can be used for Visual Studio wide configuration which is independent from cmake. 
diff --git a/Modules/CMakeCSharpCompiler.cmake.in b/Modules/CMakeCSharpCompiler.cmake.in
new file mode 100644
index 0000000..1d4f429
--- /dev/null
+++ b/Modules/CMakeCSharpCompiler.cmake.in
@@ -0,0 +1,12 @@
+set(CMAKE_CSharp_COMPILER "@CMAKE_CSharp_COMPILER@")
+set(CMAKE_CSharp_COMPILER_ID "@CMAKE_CSharp_COMPILER_ID@")
+set(CMAKE_CSharp_COMPILER_VERSION "@CMAKE_CSharp_COMPILER_VERSION@")
+set(CMAKE_CSharp_FRAMEWORK_VERSION "@CMAKE_CSharp_FRAMEWORK_VERSION@")
+
+set(CMAKE_CSharp_COMPILER_WORKS "@CMAKE_CSharp_COMPILER_WORKS@")
+
+set(CMAKE_CSharp_COMPILER_ENV_VAR "CSharp")
+
+set(CMAKE_CSharp_COMPILER_ID_RUN "@CMAKE_CSharp_COMPILER_ID_RUN@")
+set(CMAKE_CSharp_IGNORE_EXTENSIONS "inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC")
+set(CMAKE_CSharp_SOURCE_FILE_EXTENSIONS "cs")
diff --git a/Modules/CMakeCSharpInformation.cmake b/Modules/CMakeCSharpInformation.cmake
new file mode 100644
index 0000000..5a85a1c
--- /dev/null
+++ b/Modules/CMakeCSharpInformation.cmake
@@ -0,0 +1,155 @@
+
+#=============================================================================
+# Copyright 2004-2011 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+# This file sets the basic flags for the C# language in CMake.
+# It also loads the available platform file for the system-compiler
+# if it exists.
+#
+# Additional references can be found here:
+#   .NET SDK 1.1: http://www.microsoft.com/downloads/details.aspx?FamilyID=9b3a2ca6-3647-4070-9f41-a333c6b9181d&displaylang=en
+#   .NET SDK 2.0: http://www.microsoft.com/downloads/details.aspx?FamilyID=fe6f2099-b7b4-4f47-a244-c96d69c35dec&displaylang=en
+#   .NET SDK 3.5: http://www.microsoft.com/downloads/details.aspx?familyid=333325fd-ae52-4e35-b531-508d977d32a6&displaylang=en
+#   C# Compiler options: http://msdn.microsoft.com/en-us/library/2fdbz5xd(v=VS.71).aspx
+#
+
+set(CMAKE_BASE_NAME)
+get_filename_component(CMAKE_BASE_NAME "${CMAKE_CSharp_COMPILER}" NAME_WE)
+
+###########################################################
+# SET _INIT FLAGS HERE!!!
+###########################################################
+set(CMAKE_BUILD_TYPE_INIT Debug)
+
+set(CMAKE_CSharp_FLAGS_INIT "/define:TRACE /langversion:3 /nowin32manifest")
+set(CMAKE_CSharp_FLAGS_DEBUG_INIT "/debug:full /optimize- /warn:3 /errorreport:prompt /define:DEBUG")
+set(CMAKE_CSharp_FLAGS_RELEASE_INIT "/debug:none /optimize  /warn:1  /errorreport:queue")
+set(CMAKE_CSharp_FLAGS_RELWITHDEBINFO_INIT "/debug:full /optimize-")
+set(CMAKE_CSharp_FLAGS_MINSIZEREL_INIT "/debug:none /optimize")
+set(CMAKE_CSharp_LINKER_SUPPORTS_PDB ON)
+
+set(CMAKE_CSharp_STANDARD_LIBRARIES_INIT "System")
+
+if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+  set(CMAKE_CSharp_FLAGS_INIT "/platform:x86 ${CMAKE_CSharp_FLAGS_INIT}")
+else()
+  set(CMAKE_CSharp_FLAGS_INIT "/platform:x64 ${CMAKE_CSharp_FLAGS_INIT}")
+endif()
+
+# This should be included before the _INIT variables are
+# used to initialize the cache.  Since the rule variables
+# have if blocks on them, users can still define them here.
+# But, it should still be after the platform file so changes can
+# be made to those values.
+
+# for most systems a module is the same as a shared library
+# so unless the variable CMAKE_MODULE_EXISTS is set just
+# copy the values from the LIBRARY variables
+if(NOT CMAKE_MODULE_EXISTS)
+  set(CMAKE_SHARED_MODULE_CSharp_FLAGS ${CMAKE_SHARED_LIBRARY_CSharp_FLAGS})
+  set(CMAKE_SHARED_MODULE_CREATE_CSharp_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_CSharp_FLAGS})
+endif()
+
+# add the flags to the cache based
+# on the initial values computed in the platform/*.cmake files
+# use _INIT variables so that this only happens the first time
+# and you can set these flags in the cmake cache
+set(CMAKE_CSharp_FLAGS_INIT "$ENV{CSharpFLAGS} ${CMAKE_CSharp_FLAGS_INIT}")
+# avoid just having a space as the initial value for the cache
+if(CMAKE_CSharp_FLAGS_INIT STREQUAL " ")
+  set(CMAKE_CSharp_FLAGS_INIT)
+endif()
+set (CMAKE_CSharp_FLAGS "${CMAKE_CSharp_FLAGS_INIT}" CACHE STRING
+     "Flags used by the C# compiler during all build types.")
+
+if(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
+  set (CMAKE_CSharp_FLAGS_DEBUG "${CMAKE_CSharp_FLAGS_DEBUG_INIT}" CACHE STRING
+     "Flags used by the C# compiler during debug builds.")
+  set (CMAKE_CSharp_FLAGS_MINSIZEREL "${CMAKE_CSharp_FLAGS_MINSIZEREL_INIT}" CACHE STRING
+     "Flags used by the C# compiler during release builds for minimum size.")
+  set (CMAKE_CSharp_FLAGS_RELEASE "${CMAKE_CSharp_FLAGS_RELEASE_INIT}" CACHE STRING
+     "Flags used by the C# compiler during release builds.")
+  set (CMAKE_CSharp_FLAGS_RELWITHDEBINFO "${CMAKE_CSharp_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING
+     "Flags used by the C# compiler during release builds with debug info.")
+endif()
+
+if(CMAKE_CSharp_STANDARD_LIBRARIES_INIT)
+  set(CMAKE_CSharp_STANDARD_LIBRARIES "${CMAKE_CSharp_STANDARD_LIBRARIES_INIT}"
+    CACHE STRING "Libraries linked by default with all C# applications.")
+  mark_as_advanced(CMAKE_CSharp_STANDARD_LIBRARIES)
+endif()
+
+# set missing flags (if they do not exist). This is needed in the
+# unlikely case that you have only C# and no C/C++ targets in your
+# project.
+if(NOT EXISTS CMAKE_SHARED_LINKER_FLAGS)
+    set(CMAKE_SHARED_LINKER_FLAGS "" CACHE STRING "" FORCE)
+endif()
+if(NOT EXISTS CMAKE_SHARED_LINKER_FLAGS_DEBUG)
+    set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "" CACHE STRING "" FORCE)
+endif()
+if(NOT EXISTS CMAKE_SHARED_LINKER_FLAGS_RELEASE)
+    set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "" CACHE STRING "" FORCE)
+endif()
+if(NOT EXISTS CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL)
+    set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "" CACHE STRING "" FORCE)
+endif()
+if(NOT EXISTS CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO)
+    set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "" CACHE STRING "" FORCE)
+endif()
+
+if(NOT EXISTS CMAKE_EXE_LINKER_FLAGS)
+    set(CMAKE_EXE_LINKER_FLAGS "" CACHE STRING "" FORCE)
+endif()
+if(NOT EXISTS CMAKE_EXE_LINKER_FLAGS_DEBUG)
+    set(CMAKE_EXE_LINKER_FLAGS_DEBUG "" CACHE STRING "" FORCE)
+endif()
+if(NOT EXISTS CMAKE_EXE_LINKER_FLAGS_RELEASE)
+    set(CMAKE_EXE_LINKER_FLAGS_RELEASE "" CACHE STRING "" FORCE)
+endif()
+if(NOT EXISTS CMAKE_EXE_LINKER_FLAGS_MINSIZEREL)
+    set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "" CACHE STRING "" FORCE)
+endif()
+if(NOT EXISTS CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO)
+    set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "" CACHE STRING "" FORCE)
+endif()
+
+# variables supplied by the generator at use time
+# <TARGET>
+# <TARGET_BASE> the target without the suffix
+# <OBJECTS>
+# <OBJECT>
+# <LINK_LIBRARIES>
+# <FLAGS>
+# <LINK_FLAGS>
+
+# CSharp compiler information
+# <CMAKE_CSharp_COMPILER>
+# <CMAKE_SHARED_LIBRARY_CREATE_CSharp_FLAGS>
+# <CMAKE_CSharp_SHARED_MODULE_CREATE_FLAGS>
+# <CMAKE_CSharp_LINK_FLAGS>
+
+set(CMAKE_CSharp_CREATE_SHARED_LIBRARY "CSharp_NO_CREATE_SHARED_LIBRARY")
+set(CMAKE_CSharp_CREATE_SHARED_MODULE "CSharp_NO_CREATE_SHARED_MODULE")
+set(CMAKE_CSharp_LINK_EXECUTABLE "CSharp_NO_LINK_EXECUTABLE")
+
+mark_as_advanced(
+    CMAKE_CSharp_FLAGS
+    CMAKE_CSharp_FLAGS_RELEASE
+    CMAKE_CSharp_FLAGS_RELWITHDEBINFO
+    CMAKE_CSharp_FLAGS_MINSIZEREL
+    CMAKE_CSharp_FLAGS_DEBUG
+    )
+
+set(CMAKE_CSharp_USE_RESPONSE_FILE_FOR_OBJECTS 1)
+set(CMAKE_CSharp_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeDetermineCSharpCompiler.cmake b/Modules/CMakeDetermineCSharpCompiler.cmake
new file mode 100644
index 0000000..82a30df
--- /dev/null
+++ b/Modules/CMakeDetermineCSharpCompiler.cmake
@@ -0,0 +1,199 @@
+
+#=============================================================================
+# Copyright 2002-2009 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+# determine the compiler to use for C# programs
+# NOTE, a generator may set CMAKE_CSharp_COMPILER before
+# loading this file to force a compiler.
+# use environment variable CSharp first if defined by user, next use
+# the cmake variable CMAKE_GENERATOR_CSharp which can be defined by a generator
+# as a default compiler
+#
+# Sets the following variables:
+#   CMAKE_CSharp_COMPILER
+#   CMAKE_CSharp_COMPILER_ID
+#   CMAKE_CSharp_COMPILER_VERSION
+#   CMAKE_CSharp_FRAMEWORK_VERSION
+#   CMAKE_CSharp_COMPILER_ENV_VAR
+#
+# Additional references can be found here:
+#   .NET SDK 1.1: http://www.microsoft.com/downloads/details.aspx?FamilyID=9b3a2ca6-3647-4070-9f41-a333c6b9181d&displaylang=en
+#   .NET SDK 2.0: http://www.microsoft.com/downloads/details.aspx?FamilyID=fe6f2099-b7b4-4f47-a244-c96d69c35dec&displaylang=en
+#   .NET SDK 3.5: http://www.microsoft.com/downloads/details.aspx?familyid=333325fd-ae52-4e35-b531-508d977d32a6&displaylang=en
+#   C# Compiler options: http://msdn.microsoft.com/en-us/library/2fdbz5xd(v=VS.71).aspx
+#
+
+function(FIND_csc_EXE search_path result)
+  # Search for .NET versions
+  file(TO_CMAKE_PATH ${search_path} search_path)
+  file(GLOB_RECURSE csc_executables "${search_path}/csc.exe")
+  set(${result} ${csc_executables} PARENT_SCOPE)
+endfunction()
+
+function(get_compiler_and_framework_version program result_compiler result_framework)
+  set(compiler_version)
+  set(framework_version)
+  execute_process(COMMAND ${program}
+	OUTPUT_VARIABLE output)
+  string(REPLACE "\n" ";" output ${output})
+  foreach(line ${output})
+	string(TOUPPER ${line} line)
+    string(REGEX REPLACE "^.*COMPILER.*VERSION[^.0-9]*([.0-9]+).*$" "\\1" current_compiler_version "${line}")
+	if(${line} STREQUAL ${current_compiler_version})
+		string(REGEX REPLACE "^.*FRAMEWORK[^.0-9]*([.0-9]+).*$" "\\1" current_framework_version "${line}")
+	endif()
+	if(current_compiler_version AND NOT "x${line}" STREQUAL "x${current_compiler_version}")
+		set(compiler_version ${current_compiler_version})
+	endif()
+ 	if(current_framework_version AND NOT "x${line}" STREQUAL "x${current_framework_version}")
+		set(framework_version ${current_framework_version})
+	endif()
+  endforeach()
+  string(TOUPPER ${program} program)
+  if("${program}" MATCHES "64")
+    set(compiler_version "${compiler_version}_X64")
+  endif()
+  set(${result_compiler} ${compiler_version} PARENT_SCOPE)
+  set(${result_framework} ${framework_version} PARENT_SCOPE)
+endfunction()
+
+function(get_installed_dotnet_frameworks)
+  # skipping framework detection for now ...
+  return()
+  message(".NET framework detection ...")
+  set(FRAMEWORK_REGISTRY_KEY_0 "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP")
+  set(FRAMEWORK_REGISTRY_KEY_1 "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full")
+  execute_process(COMMAND reg query "${FRAMEWORK_REGISTRY_KEY_0}"
+    OUTPUT_VARIABLE output)
+  message("FRAMEWORKS:${output}")
+  execute_process(COMMAND reg query "${FRAMEWORK_REGISTRY_KEY_1}"
+    OUTPUT_VARIABLE output)
+  message("FRAMEWORKS:${output}")
+  message("... done")
+endfunction()
+
+set(CSharp_ERROR_MESSAGE
+  "====================== CMake C# support! ======================\n"
+  "\n"
+  "This is the Module for C# support within CMake.\n"
+  "Currently only Microsoft Visual Studio 2010/2012/2013/2015 (no ARM!)\n"
+  "Generators are supported.\n"
+  "\n"
+  "==============================================================="
+  )
+
+set(alwaysShowMessage OFF)
+  
+if(NOT WIN32 OR
+   NOT ${CMAKE_GENERATOR} MATCHES "Visual Studio" OR
+   ( NOT ${CMAKE_GENERATOR} MATCHES "2010" AND 
+     NOT ${CMAKE_GENERATOR} MATCHES "2012" AND 
+     NOT ${CMAKE_GENERATOR} MATCHES "2013" AND 
+     NOT ${CMAKE_GENERATOR} MATCHES "2015") )
+   message(FATAL_ERROR ${CSharp_ERROR_MESSAGE})
+endif()
+
+if(alwaysShowMessage)
+  message(STATUS ${CSharp_ERROR_MESSAGE})
+endif()
+
+if(NOT CMAKE_CSharp_COMPILER_NAMES)
+  set(CMAKE_CSharp_COMPILER_NAMES csc)
+endif()
+
+if(NOT ${CMAKE_GENERATOR} MATCHES "Visual Studio")
+  # Get all csc.exe from installed frameworks
+  set(csharp_dotnet_framework_dir86 "$ENV{windir}/Microsoft.NET/Framework")
+  set(csharp_dotnet_framework_dir64 "$ENV{windir}/Microsoft.NET/Framework64")
+  FIND_csc_EXE(${csharp_dotnet_framework_dir86} csc_executables1)
+  FIND_csc_EXE(${csharp_dotnet_framework_dir64} csc_executables2)
+endif()
+
+# get all csc.exe from MSBuild (which was most likely installed along with visual studio)
+if($ENV{PROCESSOR_ARCHITECTURE} STREQUAL "AMD64")
+  set(programfilesx86 "ProgramFiles(x86)")
+  if(DEFINED "ENV{${programfilesx86}}")
+    set(msbuild_install_dir "$ENV{${programfilesx86}}/MSBuild")
+  endif()
+else()
+  set(msbuild_install_dir "$ENV{ProgramFiles}/MSBuild")
+endif()
+FIND_csc_EXE(${msbuild_install_dir} csc_executables3)
+set(csc_executables "${csc_executables1};${csc_executables2};${csc_executables3}")
+
+# if we are using Visual Studio projects, remove csc.exe of the 
+# currently not selected bitness
+if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
+  if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+    #message("c# 32bit")
+    foreach(entry ${csc_executables})
+      if(${entry} MATCHES "64")
+        list(REMOVE_ITEM csc_executables ${entry})
+      endif()
+    endforeach()
+  else()
+    #message("c# 64bit")
+    foreach(entry ${csc_executables})
+      if(NOT ${entry} MATCHES "64")
+        list(REMOVE_ITEM csc_executables ${entry})
+      endif()
+    endforeach()
+  endif()
+endif()
+
+# get available C# compiler versions
+unset(CMAKE_CSharp_COMPILER_VERSIONS)
+foreach(csc_executable ${csc_executables})
+  get_compiler_and_framework_version("${csc_executable}" compiler_version framework_version)
+  if(framework_version)
+    set(versionString "${compiler_version}_DOTNET${framework_version}")
+  else()
+    set(versionString "${compiler_version}")
+  endif()
+  set(CMAKE_CSharp_COMPILER_${versionString} "${csc_executable}" CACHE STRING "" FORCE)
+  set(CMAKE_CSharp_COMPILER_${versionString}_ID "${compiler_version}" CACHE STRING "" FORCE)
+  set(CMAKE_CSharp_COMPILER_${versionString}_FW "${framework_version}" CACHE STRING "" FORCE)
+  # Create a list of supported compiler versions
+  if(NOT DEFINED CMAKE_CSharp_COMPILER_VERSIONS)
+    set(CMAKE_CSharp_COMPILER_VERSIONS "${versionString}" CACHE STRING "Available C# .NET compiler versions" FORCE)
+  else()
+    set(CMAKE_CSharp_COMPILER_VERSIONS "${CMAKE_CSharp_COMPILER_VERSIONS};${versionString}" CACHE STRING "" FORCE)
+  endif()
+endforeach()
+mark_as_advanced(CMAKE_CSharp_COMPILER_VERSIONS)
+
+# select first found C# compiler (propably not the best solution, but does not matter 
+# when using Visual Studio Generator)
+list(GET CMAKE_CSharp_COMPILER_VERSIONS 0 current_CSharp_version)
+set(CMAKE_CSharp_COMPILER_ID ${current_CSharp_version} CACHE STRING "C# .NET compiler version")
+set_property(CACHE CMAKE_CSharp_COMPILER_ID PROPERTY STRINGS ${CMAKE_CSharp_COMPILER_VERSIONS})
+set(CMAKE_CSharp_COMPILER_ID_RUN 1)
+mark_as_advanced(CMAKE_CSharp_COMPILER_ID)
+
+set(CMAKE_CSharp_COMPILER "${CMAKE_CSharp_COMPILER_${CMAKE_CSharp_COMPILER_ID}}")
+mark_as_advanced(CMAKE_CSharp_COMPILER)
+
+set(CMAKE_CSharp_COMPILER_VERSION "${CMAKE_CSharp_COMPILER_${CMAKE_CSharp_COMPILER_ID}_ID}")
+set(CMAKE_CSharp_FRAMEWORK_VERSION "${CMAKE_CSharp_COMPILER_${CMAKE_CSharp_COMPILER_ID}_FW}")
+
+message(STATUS "The C# compiler identification is ${CMAKE_CSharp_COMPILER_ID}")
+
+# configure all variables set in this file
+configure_file(${CMAKE_ROOT}/Modules/CMakeCSharpCompiler.cmake.in
+  ${CMAKE_PLATFORM_INFO_DIR}/CMakeCSharpCompiler.cmake
+  @ONLY
+  )
+
+get_installed_dotnet_frameworks()
+  
+set(CMAKE_CSharp_COMPILER_ENV_VAR "CSharp")
diff --git a/Modules/CMakeTestCSharpCompiler.cmake b/Modules/CMakeTestCSharpCompiler.cmake
new file mode 100644
index 0000000..94f2580
--- /dev/null
+++ b/Modules/CMakeTestCSharpCompiler.cmake
@@ -0,0 +1,62 @@
+
+if(CMAKE_CSharp_COMPILER_FORCED)
+  # The compiler configuration was forced by the user.
+  # Assume the user has configured all compiler information.
+  set(CMAKE_CSharp_COMPILER_WORKS TRUE)
+  return()
+endif()
+
+include(CMakeTestCompilerCommon)
+
+unset(CMAKE_CSharp_COMPILER_WORKS CACHE)
+
+set(test_compile_file "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCSharpCompiler.cs")
+
+# This file is used by EnableLanguage in cmGlobalGenerator to
+# determine that that selected C# compiler can actually compile
+# and link the most basic of programs. If not, a fatal error
+# is set and cmake stops processing commands and will not generate
+# any makefiles or projects.
+if(NOT CMAKE_CSharp_COMPILER_WORKS)
+  PrintTestCompilerStatus("C#" "")
+  file(WRITE "${test_compile_file}"
+    "namespace Test {"
+    "   public class CSharp {"
+    "       static void Main(string[] args) {}"
+    "   }"
+    "}"
+    )
+  try_compile(CMAKE_CSharp_COMPILER_WORKS ${CMAKE_BINARY_DIR} "${test_compile_file}"
+    OUTPUT_VARIABLE __CMAKE_CSharp_COMPILER_OUTPUT
+    COPY_FILE "C:/Users/stuermic/git/cmake_build/x64_14/Tests/CSharp")
+  # Move result from cache to normal variable.
+  set(CMAKE_CSharp_COMPILER_WORKS ${CMAKE_CSharp_COMPILER_WORKS})
+  unset(CMAKE_CSharp_COMPILER_WORKS CACHE)
+  set(CSharp_TEST_WAS_RUN 1)
+endif()
+
+if(NOT CMAKE_CSharp_COMPILER_WORKS)
+  PrintTestCompilerStatus("C#" " -- broken")
+  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+    "Determining if the C# compiler works failed with "
+    "the following output:\n${__CMAKE_CSharp_COMPILER_OUTPUT}\n\n")
+  message(FATAL_ERROR "The C# compiler \"${CMAKE_CSharp_COMPILER}\" "
+    "is not able to compile a simple test program.\nIt fails "
+    "with the following output:\n ${__CMAKE_CSharp_COMPILER_OUTPUT}\n\n"
+    "CMake will not be able to correctly generate this project.")
+else()
+  if(CSharp_TEST_WAS_RUN)
+    PrintTestCompilerStatus("C#" " -- works")
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+      "Determining if the C# compiler works passed with "
+      "the following output:\n${__CMAKE_CSharp_COMPILER_OUTPUT}\n\n")
+  endif()
+
+  # Re-configure to save learned information.
+  configure_file(
+    ${CMAKE_ROOT}/Modules/CMakeCSharpCompiler.cmake.in
+    ${CMAKE_PLATFORM_INFO_DIR}/CMakeCSharpCompiler.cmake
+    @ONLY
+    )
+  include(${CMAKE_PLATFORM_INFO_DIR}/CMakeCSharpCompiler.cmake)
+endif()
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index 8227b82..8c7adf5 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -163,7 +163,12 @@ cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
     ext = ".vfproj";
     project = "Project(\"{6989167D-11E4-40FE-8C1A-2192A86A7E90}\") = \"";
     }
-  const char* targetExt = t->GetProperty("GENERATOR_FILE_NAME_EXT");
+  if (this->TargetIsCSharpOnly(t))
+    {
+    ext = ".csproj";
+    project = "Project(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"";
+    }
+  const char* targetExt = t->Target->GetProperty("GENERATOR_FILE_NAME_EXT");
   if(targetExt)
     {
     ext = targetExt;
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 6a1aa29..026f42a 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -853,6 +853,41 @@ cmGlobalVisualStudioGenerator::TargetIsFortranOnly(cmGeneratorTarget const* gt)
   return false;
 }
 
+bool
+cmGlobalVisualStudioGenerator::TargetIsCSharpOnly(cmGeneratorTarget const* target)
+{
+    if (target->GetType() > cmState::OBJECT_LIBRARY)
+      {
+      return false;
+      }
+
+  // check to see if this is a C# build
+  // Issue diagnostic if the source files depend on the config.
+  std::vector<cmSourceFile*> sources;
+  if (!target->GetConfigCommonSourceFiles(sources))
+    {
+    return false;
+    }
+  std::set<std::string> languages;
+  for (std::vector<cmSourceFile*>::const_iterator i = sources.begin();
+      i != sources.end(); i++)
+    {
+    std::string langugage = (*i)->GetLanguage();
+    if (!langugage.empty())
+      {
+      languages.insert(langugage);
+      }
+    }
+  if (languages.size() == 1)
+    {
+    if (*languages.begin() == "CSharp")
+      {
+      return true;
+      }
+    }
+  return false;
+}
+
 //----------------------------------------------------------------------------
 bool
 cmGlobalVisualStudioGenerator::TargetCompare
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index f827f26..9881b1f 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -75,6 +75,9 @@ public:
   // return true if target is fortran only
   bool TargetIsFortranOnly(const cmGeneratorTarget *gt);
 
+  // return true if target is C# only
+  static bool TargetIsCSharpOnly(cmGeneratorTarget const* t);
+
   /** Get the top-level registry key for this VS version.  */
   std::string GetRegistryBase();
 
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index 1433b54..0c02693 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -90,6 +90,7 @@ public:
 
   // Get the properties
   cmPropertyMap &GetProperties() { return this->Properties; }
+  const cmPropertyMap &GetProperties() const { return this->Properties; }
 
   /**
    * Check whether the given source file location could refer to this
diff --git a/Source/cmVSCSharpFlagTable.h b/Source/cmVSCSharpFlagTable.h
new file mode 100644
index 0000000..ad4ee0e
--- /dev/null
+++ b/Source/cmVSCSharpFlagTable.h
@@ -0,0 +1,223 @@
+// this was initially copied from cmVS12CLFlagTable.h
+
+static cmVS7FlagTable cmVSCSharpFlagTable[] =
+{
+  {"ProjectName", "out:",
+   "", "", cmIDEFlagTable::UserValueRequired },
+
+  {"OutputType", "target:exe",             
+   "", "Exe", 0},
+  {"OutputType", "target:winexe",          
+   "", "Winexe", 0}, 
+  {"OutputType", "target:library",         
+    "", "Library", 0},
+  {"OutputType", "target:module",          
+   "", "Module", 0},
+
+  {"DocumentationFile", "doc", 
+   "", "", cmIDEFlagTable::UserValueRequired },
+
+  {"Platform", "platform:x86", 
+   "", "x86", 0},
+  {"Platform", "platform:Itanium", 
+   "", "Itanium", 0},
+  {"Platform", "platform:x64", 
+   "", "x64", 0},
+  {"Platform", "platform:arm", 
+   "", "arm", 0},
+  {"Platform", "platform:anycpu32bitpreferred", 
+   "", "anycpu32bitpreferred", 0},
+  {"Platform", "platform:anycpu",        
+   "", "anycpu", 0},
+
+#if 0
+  {"", "recurse", 
+   "", "", 0},
+#endif
+
+  {"References", "reference:", 
+   "mit alias",  "", 0},
+  {"References", "reference:", 
+   "dateiliste", "", 0},
+  {"AddModules", "addmodule:", 
+   "", "", cmIDEFlagTable::SemicolonAppendable},
+  {"", "link", "", "", 0},
+
+
+  {"Win32Resource", "win32res", 
+   "", "", cmIDEFlagTable::UserValueRequired },
+  {"ApplicationIcon", "win32icon", 
+   "", "", cmIDEFlagTable::UserValueRequired },
+
+  {"Win32Manifest", "win32manifest:", 
+   "", "true", 0},
+
+  {"NoWin32Manifest", "nowin32manifest", 
+   "", "true", 0},
+
+#if 0
+  {"", "resource", "", "", 0},
+  {"", "linkresource", "", "", 0},
+  {"", "linkres", "", "", 0},
+#endif
+
+  {"DefineDebug", "debug", 
+   "", "true", cmIDEFlagTable::Continue},
+
+  {"DebugSymbols", "debug", 
+   "", "true", 0},
+  {"DebugSymbols", "debug-", 
+   "", "false", 0},
+  {"DebugSymbols", "debug+", 
+   "", "true", 0},
+
+  {"DebugType", "debug:none", 
+   "", "none", 0},
+  {"DebugType", "debug:full", 
+   "", "full", 0},
+  {"DebugType", "debug:pdbonly", 
+   "", "pdbonly", 0},
+
+  {"Optimize", "optimize", 
+   "", "true", 0},
+  {"Optimize", "optimize-", 
+   "", "false", 0},
+  {"Optimize", "optimize+", 
+   "", "true", 0},
+
+  {"WarningsAsErrors", "warnaserror", 
+   "", "", 0},
+  {"WarningsAsErrors", "warnaserror-", 
+   "", "", 0},
+  {"WarningsAsErrors", "warnaserror+", 
+   "", "", 0},
+
+  {"WarningLevel", "warn:0", 
+   "", "0", 0},
+  {"WarningLevel", "warn:1", 
+   "", "1", 0},
+  {"WarningLevel", "warn:2", 
+   "", "2", 0},
+  {"WarningLevel", "warn:3", 
+   "", "3", 0},
+  {"WarningLevel", "warn:4", 
+   "", "4", 0},
+  {"DisabledWarnings", "nowarn", 
+   "", "", 0},
+
+  {"CheckForOverflowUnderflow", "checked", 
+   "", "true", 0},
+  {"CheckForOverflowUnderflow", "checked-", 
+   "", "false", 0},
+  {"CheckForOverflowUnderflow", "checked+", 
+   "", "true", 0},
+
+  {"AllowUnsafeBlocks", "unsafe", 
+   "", "true", 0},
+  {"AllowUnsafeBlocks", "unsafe-", 
+   "", "false", 0},
+  {"AllowUnsafeBlocks", "unsafe+", 
+   "", "true", 0},
+
+  {"DefineConstants", "define:", 
+   "", "", cmIDEFlagTable::SemicolonAppendable | cmIDEFlagTable::UserValue },
+
+  {"LangVersion", "langversion:ISO-1",
+   "", "ISO-1", 0 },
+  {"LangVersion", "langversion:ISO-2",
+   "", "ISO-2", 0 },
+  {"LangVersion", "langversion:3",
+   "", "3", 0 },
+  {"LangVersion", "langversion:4",
+   "", "4", 0 },
+  {"LangVersion", "langversion:5",
+   "", "5", 0 },
+  {"LangVersion", "langversion:default",
+   "", "default", 0 },
+
+  {"DelaySign", "delaysign", 
+   "", "true", 0},
+  {"DelaySign", "delaysign-", 
+   "", "false", 0},
+  {"DelaySign", "delaysign+", 
+   "", "true", 0},
+
+  {"AssemblyOriginatorKeyFile", "keyfile", 
+   "", "", 0},
+
+  {"KeyContainerName", "keycontainer", "", "", 0},
+
+#if 0
+  {"", "highentropyva", "", "", 0},
+  {"", "highentropyva-", "", "", 0},
+  {"", "highentropyva+", "", "", 0},
+  { "", "help", "", "", 0 },
+#endif
+
+  {"NoLogo", "nologo", 
+   "", "", 0},
+
+  {"NoConfig", "noconfig", 
+   "", "true", 0},
+
+  {"BaseAddress", "baseaddress:", 
+   "", "", 0},
+
+#if 0
+  {"", "bugreport:", 
+   "", "", 0},
+#endif
+
+  {"CodePage", "codepage", 
+   "", "", 0},
+
+  {"Utf8Output", "utf8output", 
+   "", "", 0},
+
+  {"MainEntryPoint", "main:", 
+   "", "", 0},
+
+  {"GenerateFullPaths", "fullpaths", 
+   "", "true", 0},
+
+  {"FileAlignment", "filealign", 
+   "", "", 0},
+
+  {"PdbFile", "pdb:", 
+   "", "", 0},
+
+#if 0
+  {"", "errorendlocation", "", "", 0},
+  {"", "preferreduilang", "", "", 0},
+#endif
+
+  {"NoStandardLib", "nostdlib", 
+   "", "true", 0},
+  {"NoStandardLib", "nostdlib-", 
+   "", "false", 0},
+  {"NoStandardLib", "nostdlib+", 
+   "", "true", 0},
+
+  {"SubsystemVersion", "subsystemversion", 
+   "", "", 0},
+
+  {"AdditionalLibPaths", "lib:", 
+   "", "", 0},
+
+  {"ErrorReport", "errorreport:none",
+   "Do Not Send Report", "none", 0 },
+  {"ErrorReport", "errorreport:prompt",
+   "Prompt Immediately", "prompt", 0 },
+  {"ErrorReport", "errorreport:queue",
+   "Queue For Next Login", "queue", 0 },
+  {"ErrorReport", "errorreport:send",
+   "Send Automatically", "send", 0 },
+
+#if 0
+  {"", "appconfig", "", "", 0},
+  { "ModuleAssemblyName", "moduleassemblyname",
+  "", "", 0 },
+#endif
+
+  {0, 0, 0, 0, 0},
+};
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index bd4eb69..26a8bf0 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -87,7 +87,7 @@ void cmVisualStudioGeneratorOptions::AddTable(cmVS7FlagTable const* table)
 }
 
 //----------------------------------------------------------------------------
-void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault()
+void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault(int indent)
 {
   // Exception handling is on by default because the platform file has
   // "/EHsc" in the flags.  Normally, that will override this
@@ -109,6 +109,10 @@ void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault()
       // and space over for the closing </ExceptionHandling> as the default
       // value
       this->FlagMap["ExceptionHandling"] = "\n      ";
+      for (int i = 0; i < indent; ++i)
+        {
+        this->FlagMap["ExceptionHandling"].at(0).append("  ");
+        }
       break;
     default:
       this->FlagMap["ExceptionHandling"] = "0";
@@ -138,7 +142,22 @@ void cmVisualStudioGeneratorOptions::SetVerboseMakefile(bool verbose)
 
 bool cmVisualStudioGeneratorOptions::IsDebug() const
 {
-  return this->FlagMap.find("DebugInformationFormat") != this->FlagMap.end();
+  if (this->FlagMap.find("DebugInformationFormat") != this->FlagMap.end())
+    {
+    return true;
+    }
+  std::map<std::string, FlagValue >::const_iterator i = this->FlagMap.find("DebugType");
+  if (i != this->FlagMap.end())
+    {
+    if (i->second.size() == 1)
+      {
+      if (i->second[0] != "none")
+        {
+        return true;
+        }
+      }
+    }
+  return false;
 }
 
 //----------------------------------------------------------------------------
@@ -147,6 +166,11 @@ bool cmVisualStudioGeneratorOptions::IsWinRt() const
   return this->FlagMap.find("CompileAsWinRT") != this->FlagMap.end();
 }
 
+bool cmVisualStudioGeneratorOptions::IsManaged() const
+{
+  return this->FlagMap.find("CompileAsManaged") != this->FlagMap.end();
+}
+
 //----------------------------------------------------------------------------
 bool cmVisualStudioGeneratorOptions::UsingUnicode() const
 {
diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h
index 0179134..847989e 100644
--- a/Source/cmVisualStudioGeneratorOptions.h
+++ b/Source/cmVisualStudioGeneratorOptions.h
@@ -50,7 +50,7 @@ public:
   void ParseFinish();
 
   // Fix the ExceptionHandling option to default to off.
-  void FixExceptionHandlingDefault();
+  void FixExceptionHandlingDefault(int indent = 3);
 
   // Store options for verbose builds.
   void SetVerboseMakefile(bool verbose);
@@ -61,6 +61,7 @@ public:
 
   bool IsDebug() const;
   bool IsWinRt() const;
+  bool IsManaged() const;
   // Write options to output.
   void OutputPreprocessorDefinitions(std::ostream& fout,
                                      const char* prefix,
diff --git a/Tests/CSharp/CMakeLists.txt b/Tests/CSharp/CMakeLists.txt
new file mode 100644
index 0000000..ad6a6c6
--- /dev/null
+++ b/Tests/CSharp/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.3)
+project(CSharp CSharp)
+
+add_executable(CSharp
+	CSharp.cs
+	)
+
+set_target_properties(CSharp
+	PROPERTIES
+	VS_GLOBAL_KEYWORD "Win32Proj"
+	VS_DOTNET_REFERENCES "System;System.Core;System.Data;System.Xml"
+	VS_GLOBAL_ROOTNAMESPACE "CSharp"
+	VS_DOTNET_TARGET_FRAMEWORK_VERSION "v4.5"
+	)
diff --git a/Tests/CSharp/CSharp.cs b/Tests/CSharp/CSharp.cs
new file mode 100644
index 0000000..4fe2752
--- /dev/null
+++ b/Tests/CSharp/CSharp.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace CSharp
+{
+    public class CSharpApp
+    {
+        static void Main(string[] args)
+        {
+            System.Console.WriteLine("hello world");
+        }
+    }
+}
diff --git a/Tests/CSharp/Properties/AssemblyInfo.cs b/Tests/CSharp/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..5fed6ff
--- /dev/null
+++ b/Tests/CSharp/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+﻿using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden 
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die mit einer Assembly verknüpft sind.
+[assembly: AssemblyTitle("ClassLibrary2")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("ClassLibrary2")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar 
+// für COM-Komponenten.  Wenn Sie auf einen Typ in dieser Assembly von 
+// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
+[assembly: Guid("315789da-2b99-40d4-8590-99cb14d8e2e5")]
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+//      Hauptversion
+//      Nebenversion 
+//      Buildnummer
+//      Revision
+//
+// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern 
+// übernehmen, indem Sie "*" eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
-- 
2.7.0.windows.1

