diff --git a/scripts/build.ps1 b/scripts/build.ps1
index d952b31b2d..06abdc5168 100644
--- a/scripts/build.ps1
+++ b/scripts/build.ps1
@@ -197,6 +197,7 @@ function Publish-Package
$fullCLRPackageDir = Get-FullCLRPackageDirectory
$coreCLRPackageDir = Get-CoreCLRPackageDirectory
$coreCLR20PackageDir = Get-CoreCLR20PackageDirectory
+ $coreCLR20TestHostPackageDir = Get-CoreCLR20TestHostPackageDirectory
$packageProject = Join-Path $env:TP_PACKAGE_PROJ_DIR "package\package.csproj"
$testHostProject = Join-Path $env:TP_ROOT_DIR "src\testhost\testhost.csproj"
$testHostx86Project = Join-Path $env:TP_ROOT_DIR "src\testhost.x86\testhost.x86.csproj"
@@ -254,6 +255,12 @@ function Publish-Package
Copy-Item $platformAbstractionNetFull\* $fullCLRPackageDir -Force
Copy-Item $platformAbstractionNetCore\* $coreCLR20PackageDir -Force
+ # Publish msdia
+ $comComponentsDirectory = Join-Path $env:TP_PACKAGES_DIR "Microsoft.Internal.Dia\14.0.0\contentFiles\any\any\ComComponents"
+ Copy-Item -Recurse $comComponentsDirectory\* $testhostCorePackageDir -Force
+ Copy-Item -Recurse $comComponentsDirectory\* $testhostFullPackageDir -Force
+ Copy-Item -Recurse $comComponentsDirectory\* $coreCLR20TestHostPackageDir -Force
+
# Copy over the logger assemblies to the Extensions folder.
$extensions_Dir = "Extensions"
$fullCLRExtensionsDir = Join-Path $fullCLRPackageDir $extensions_Dir
@@ -329,7 +336,7 @@ function Create-VsixPackage
Copy-Item -Recurse $legacyDir\* $packageDir -Force
# Copy COM Components and their manifests over
- $comComponentsDirectory = Join-Path $env:TP_PACKAGES_DIR "Microsoft.Internal.Dia\14.0.0\contentFiles\any\any"
+ $comComponentsDirectory = Join-Path $env:TP_PACKAGES_DIR "Microsoft.Internal.Dia\14.0.0\contentFiles\any\any\ComComponents"
Copy-Item -Recurse $comComponentsDirectory\* $testhostPackageDir -Force
$fileToCopy = Join-Path $env:TP_PACKAGE_PROJ_DIR "ThirdPartyNotices.txt"
@@ -467,6 +474,11 @@ function Get-CoreCLR20PackageDirectory
return $(Join-Path $env:TP_OUT_DIR "$TPB_Configuration\$TPB_TargetFrameworkCore20")
}
+function Get-CoreCLR20TestHostPackageDirectory
+{
+ return $(Join-Path $env:TP_OUT_DIR "$TPB_Configuration\$TPB_TargetFrameworkCore20\TestHost")
+}
+
function Start-Timer
{
return [System.Diagnostics.Stopwatch]::StartNew()
diff --git a/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj b/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj
index 7c4df9207f..0dd4178a65 100644
--- a/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj
+++ b/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj
@@ -13,9 +13,6 @@
-
- 14.0.0
-
diff --git a/src/Microsoft.TestPlatform.ObjectModel/Navigation/DiaSession.cs b/src/Microsoft.TestPlatform.ObjectModel/Navigation/DiaSession.cs
index 2160572d74..acbc9ea663 100644
--- a/src/Microsoft.TestPlatform.ObjectModel/Navigation/DiaSession.cs
+++ b/src/Microsoft.TestPlatform.ObjectModel/Navigation/DiaSession.cs
@@ -94,7 +94,6 @@ public INavigationData GetNavigationDataForMethod(string declaringTypeName, stri
private static ISymbolReader GetSymbolReader(string binaryPath)
{
-#if NET451
var pdbFilePath = Path.ChangeExtension(binaryPath, ".pdb");
using (var stream = new FileHelper().GetStream(pdbFilePath, FileMode.Open, FileAccess.Read))
{
@@ -105,10 +104,6 @@ private static ISymbolReader GetSymbolReader(string binaryPath)
return new FullSymbolReader();
}
-#else
- // We don't support full PDB files with .net core
- return new PortableSymbolReader();
-#endif
}
}
}
\ No newline at end of file
diff --git a/src/Microsoft.TestPlatform.ObjectModel/Navigation/FullSymbolReader.cs b/src/Microsoft.TestPlatform.ObjectModel/Navigation/FullSymbolReader.cs
index 4394ab1932..5121ae1b6a 100644
--- a/src/Microsoft.TestPlatform.ObjectModel/Navigation/FullSymbolReader.cs
+++ b/src/Microsoft.TestPlatform.ObjectModel/Navigation/FullSymbolReader.cs
@@ -3,20 +3,16 @@
namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Navigation
{
-#if NET451
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
- using System.Reflection;
using System.Runtime.InteropServices;
- using Dia;
-
///
/// To get method's file name, startline and endline from desktop assembly file.
///
- internal class FullSymbolReader : ISymbolReader
+ internal class FullSymbolReader : ISymbolReader
{
///
/// To check isDisposed
@@ -35,15 +31,10 @@ internal class FullSymbolReader : ISymbolReader
/// Holds method symbols for all types in the source.
/// Methods in different types can have same name, hence seprated dicitionary is created for each type.
/// Bug: Method overrides in same type are not handled (not a regression)
+ /// ToDo(Solution): Use method token along with as identifier, this will always give unique method.The adapters would need to send this token to us to correct the behavior.
///
private Dictionary> methodSymbols = new Dictionary>();
- ///
- /// Manifest files for Reg Free Com. This is essentially put in place for the msdia dependency.
- ///
- private const string ManifestFileNameX86 = "TestPlatform.ObjectModel.x86.manifest";
- private const string ManifestFileNameX64 = "TestPlatform.ObjectModel.manifest";
-
///
/// dispose caches
///
@@ -67,24 +58,17 @@ public void Dispose()
///
public void CacheSymbols(string binaryPath, string searchPath)
{
- using (var activationContext = new RegistryFreeActivationContext(this.GetManifestFileForRegFreeCom()))
+ try
{
- // Activating and Deactivating the context here itself since deactivating context from a different thread would throw an SEH exception.
- // We do not need the activation context post this point since the DIASession COM object is created here only.
- try
+ if(OpenSession(binaryPath, searchPath))
{
- activationContext.ActivateContext();
-
- this.source = new DiaSource();
- this.source.loadDataForExe(binaryPath, searchPath, null);
- this.source.openSession(out this.session);
this.PopulateCacheForTypeAndMethodSymbols();
}
- catch (COMException)
- {
- this.Dispose();
- throw;
- }
+ }
+ catch (COMException)
+ {
+ this.Dispose();
+ throw;
}
}
@@ -128,6 +112,58 @@ public INavigationData GetNavigationData(string declaringTypeName, string method
return navigationData;
}
+ private bool OpenSession(string filename, string searchPath)
+ {
+ try
+ {
+ // Activate the DIA data source COM object
+ this.source = DiaSourceObject.GetDiaSourceObject();
+
+ if (this.source == null)
+ {
+ return false;
+ }
+
+ // UWP(App model) scenario
+ if (!Path.IsPathRooted(filename))
+ {
+ // Big Big hack, talk to UWP deployement team as to how to fix this.
+ // Do not check this PR till this is resolved
+ filename = Path.Combine(Directory.GetCurrentDirectory(), "entrypoint", filename);
+ if (string.IsNullOrEmpty(searchPath))
+ {
+ searchPath = Directory.GetCurrentDirectory();
+ }
+ }
+
+ // Load the data for the executable
+ int hResult = this.source.LoadDataForExe(filename, searchPath, IntPtr.Zero);
+ if (HResult.Failed(hResult))
+ {
+ throw new COMException(string.Format(Resources.Resources.FailedToCreateDiaSession, hResult));
+ }
+
+ // Open the session and return it
+ if (HResult.Failed(this.source.OpenSession(out this.session)))
+ {
+ return false;
+ }
+ }
+ catch (COMException)
+ {
+ throw;
+ }
+ finally
+ {
+ if (this.source != null)
+ {
+ Marshal.FinalReleaseComObject(this.source);
+ }
+ }
+
+ return true;
+ }
+
private DiaNavigationData GetSymbolNavigationData(IDiaSymbol symbol)
{
ValidateArg.NotNull(symbol, "symbol");
@@ -138,14 +174,29 @@ private DiaNavigationData GetSymbolNavigationData(IDiaSymbol symbol)
try
{
- this.session.findLinesByAddr(symbol.addressSection, symbol.addressOffset, (uint)symbol.length, out lines);
+ // Get the address section
+ if (HResult.Failed(symbol.GetAddressSection(out uint section)))
+ {
+ return navigationData;
+ }
- uint celt;
- IDiaLineNumber lineNumber;
+ // Get the address offset
+ if (HResult.Failed(symbol.GetAddressOffset(out uint offset)))
+ {
+ return navigationData;
+ }
+
+ // Get the length of the symbol
+ if (HResult.Failed(symbol.GetLength(out long length)))
+ {
+ return navigationData;
+ }
+
+ this.session.FindLinesByAddress(section, offset, (uint)length, out lines);
while (true)
{
- lines.Next(1, out lineNumber, out celt);
+ lines.GetNext(1, out IDiaLineNumber lineNumber, out uint celt);
if (celt != 1)
{
@@ -155,19 +206,27 @@ private DiaNavigationData GetSymbolNavigationData(IDiaSymbol symbol)
IDiaSourceFile sourceFile = null;
try
{
- sourceFile = lineNumber.sourceFile;
+ lineNumber.GetSourceFile(out sourceFile);
+
+ // Get startline
+ lineNumber.GetLineNumber(out uint startLine);
+ // Get endline
+ lineNumber.GetLineNumberEnd(out uint endLine);
+
// The magic hex constant below works around weird data reported from GetSequencePoints.
// The constant comes from ILDASM's source code, which performs essentially the same test.
const uint Magic = 0xFEEFEE;
- if (lineNumber.lineNumber >= Magic || lineNumber.lineNumberEnd >= Magic)
+ if (startLine >= Magic || endLine >= Magic)
{
continue;
}
- navigationData.FileName = sourceFile.fileName;
- navigationData.MinLineNumber = Math.Min(navigationData.MinLineNumber, (int)lineNumber.lineNumber);
- navigationData.MaxLineNumber = Math.Max(navigationData.MaxLineNumber, (int)lineNumber.lineNumberEnd);
+ sourceFile.GetFilename(out string srcFileName);
+
+ navigationData.FileName = srcFileName;
+ navigationData.MinLineNumber = Math.Min(navigationData.MinLineNumber, (int)startLine);
+ navigationData.MaxLineNumber = Math.Max(navigationData.MaxLineNumber, (int)endLine);
}
finally
{
@@ -190,36 +249,33 @@ private void PopulateCacheForTypeAndMethodSymbols()
IDiaSymbol global = null;
try
{
- global = this.session.globalScope;
- global.findChildren(SymTagEnum.SymTagCompiland, null, 0, out enumTypeSymbols);
- uint celtTypeSymbol;
- IDiaSymbol typeSymbol = null;
+ this.session.GetGlobalScope(out global);
+ global.FindChildren(SymTagEnum.SymTagCompiland, null, 0, out enumTypeSymbols);
// NOTE::
// If foreach loop is used instead of Enumerator iterator, for some reason it leaves
// the reference to pdb active, which prevents pdb from being rebuilt (in VS IDE scenario).
- enumTypeSymbols.Next(1, out typeSymbol, out celtTypeSymbol);
- while (celtTypeSymbol == 1 && null != typeSymbol)
+ enumTypeSymbols.GetNext(1, out IDiaSymbol typeSymbol, out uint celtTypeSymbol);
+ while (celtTypeSymbol == 1 && typeSymbol != null)
{
- this.typeSymbols[typeSymbol.name] = typeSymbol;
+ typeSymbol.GetName(out string name);
+ this.typeSymbols[name] = typeSymbol;
IDiaEnumSymbols enumMethodSymbols = null;
try
{
Dictionary methodSymbolsForType = new Dictionary();
- typeSymbol.findChildren(SymTagEnum.SymTagFunction, null, 0, out enumMethodSymbols);
-
- uint celtMethodSymbol;
- IDiaSymbol methodSymbol = null;
+ typeSymbol.FindChildren(SymTagEnum.SymTagFunction, null, 0, out enumMethodSymbols);
- enumMethodSymbols.Next(1, out methodSymbol, out celtMethodSymbol);
- while (celtMethodSymbol == 1 && null != methodSymbol)
+ enumMethodSymbols.GetNext(1, out IDiaSymbol methodSymbol, out uint celtMethodSymbol);
+ while (celtMethodSymbol == 1 && methodSymbol != null)
{
- UpdateMethodSymbolCache(methodSymbol.name, methodSymbol, methodSymbolsForType);
- enumMethodSymbols.Next(1, out methodSymbol, out celtMethodSymbol);
+ methodSymbol.GetName(out string methodName);
+ UpdateMethodSymbolCache(methodName, methodSymbol, methodSymbolsForType);
+ enumMethodSymbols.GetNext(1, out methodSymbol, out celtMethodSymbol);
}
- this.methodSymbols[typeSymbol.name] = methodSymbolsForType;
+ this.methodSymbols[name] = methodSymbolsForType;
}
catch (Exception ex)
{
@@ -228,7 +284,7 @@ private void PopulateCacheForTypeAndMethodSymbols()
EqtTrace.Error(
"Ignoring the exception while iterating method symbols:{0} for type:{1}",
ex,
- typeSymbol.name);
+ name);
}
}
finally
@@ -236,7 +292,7 @@ private void PopulateCacheForTypeAndMethodSymbols()
ReleaseComObject(ref enumMethodSymbols);
}
- enumTypeSymbols.Next(1, out typeSymbol, out celtTypeSymbol);
+ enumTypeSymbols.GetNext(1, out typeSymbol, out celtTypeSymbol);
}
}
catch (Exception ex)
@@ -261,8 +317,6 @@ private IDiaSymbol GetTypeSymbol(string typeName, SymTagEnum symTag)
IDiaSymbol typeSymbol = null;
IDiaSymbol global = null;
- uint celt;
-
try
{
typeName = typeName.Replace('+', '.');
@@ -271,10 +325,10 @@ private IDiaSymbol GetTypeSymbol(string typeName, SymTagEnum symTag)
return this.typeSymbols[typeName];
}
- global = this.session.globalScope;
- global.findChildren(symTag, typeName, 0, out enumSymbols);
+ this.session.GetGlobalScope(out global);
+ global.FindChildren(symTag, typeName, 0, out enumSymbols);
- enumSymbols.Next(1, out typeSymbol, out celt);
+ enumSymbols.GetNext(1, out typeSymbol, out uint celt);
#if DEBUG
if (typeSymbol == null)
@@ -282,20 +336,19 @@ private IDiaSymbol GetTypeSymbol(string typeName, SymTagEnum symTag)
IDiaEnumSymbols enumAllSymbols = null;
try
{
- global.findChildren(symTag, null, 0, out enumAllSymbols);
+ global.FindChildren(symTag, null, 0, out enumAllSymbols);
List children = new List();
- IDiaSymbol childSymbol = null;
- uint fetchedCount = 0;
while (true)
{
- enumAllSymbols.Next(1, out childSymbol, out fetchedCount);
+ enumAllSymbols.GetNext(1, out IDiaSymbol childSymbol, out uint fetchedCount);
if (fetchedCount == 0 || childSymbol == null)
{
break;
}
- children.Add(childSymbol.name);
+ childSymbol.GetName(out string childSymbolName);
+ children.Add(childSymbolName);
ReleaseComObject(ref childSymbol);
}
@@ -315,7 +368,7 @@ private IDiaSymbol GetTypeSymbol(string typeName, SymTagEnum symTag)
ReleaseComObject(ref global);
}
- if (null != typeSymbol)
+ if (typeSymbol != null)
{
this.typeSymbols[typeName] = typeSymbol;
}
@@ -334,26 +387,24 @@ private IDiaSymbol GetMethodSymbol(IDiaSymbol typeSymbol, string methodName)
try
{
-
- if (this.methodSymbols.ContainsKey(typeSymbol.name))
+ typeSymbol.GetName(out string symbolName);
+ if (this.methodSymbols.ContainsKey(symbolName))
{
- methodSymbolsForType = this.methodSymbols[typeSymbol.name];
+ methodSymbolsForType = this.methodSymbols[symbolName];
if (methodSymbolsForType.ContainsKey(methodName))
{
return methodSymbolsForType[methodName];
}
-
}
else
{
methodSymbolsForType = new Dictionary();
- this.methodSymbols[typeSymbol.name] = methodSymbolsForType;
+ this.methodSymbols[symbolName] = methodSymbolsForType;
}
- typeSymbol.findChildren(SymTagEnum.SymTagFunction, methodName, 0, out enumSymbols);
+ typeSymbol.FindChildren(SymTagEnum.SymTagFunction, methodName, 0, out enumSymbols);
- uint celtFetched;
- enumSymbols.Next(1, out methodSymbol, out celtFetched);
+ enumSymbols.GetNext(1, out methodSymbol, out uint celtFetched);
#if DEBUG
if (methodSymbol == null)
@@ -361,20 +412,19 @@ private IDiaSymbol GetMethodSymbol(IDiaSymbol typeSymbol, string methodName)
IDiaEnumSymbols enumAllSymbols = null;
try
{
- typeSymbol.findChildren(SymTagEnum.SymTagFunction, null, 0, out enumAllSymbols);
+ typeSymbol.FindChildren(SymTagEnum.SymTagFunction, null, 0, out enumAllSymbols);
List children = new List();
- IDiaSymbol childSymbol = null;
- uint fetchedCount = 0;
while (true)
{
- enumAllSymbols.Next(1, out childSymbol, out fetchedCount);
+ enumAllSymbols.GetNext(1, out IDiaSymbol childSymbol, out uint fetchedCount);
if (fetchedCount == 0 || childSymbol == null)
{
break;
}
- children.Add(childSymbol.name);
+ childSymbol.GetName(out string childSymbolName);
+ children.Add(childSymbolName);
ReleaseComObject(ref childSymbol);
}
@@ -393,7 +443,7 @@ private IDiaSymbol GetMethodSymbol(IDiaSymbol typeSymbol, string methodName)
ReleaseComObject(ref enumSymbols);
}
- if (null != methodSymbol)
+ if (methodSymbol != null)
{
methodSymbolsForType[methodName] = methodSymbol;
}
@@ -412,8 +462,7 @@ private static void UpdateMethodSymbolCache(string methodName, IDiaSymbol method
// #827589, In case a type has overloaded methods, then there could be a method already in the
// cache which should be disposed.
- IDiaSymbol oldSymbol;
- if (methodSymbolCache.TryGetValue(methodName, out oldSymbol))
+ if (methodSymbolCache.TryGetValue(methodName, out IDiaSymbol oldSymbol))
{
ReleaseComObject(ref oldSymbol);
}
@@ -431,32 +480,8 @@ private static void ReleaseComObject(ref T obj)
}
}
- private string GetManifestFileForRegFreeCom()
- {
- var currentDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
- var manifestFieName = string.Empty;
- if (IntPtr.Size == 4)
- {
- manifestFieName = ManifestFileNameX86;
- }
- else if (IntPtr.Size == 8)
- {
- manifestFieName = ManifestFileNameX64;
- }
-
- var manifestFile = Path.Combine(currentDirectory, manifestFieName);
-
- if (!File.Exists(manifestFile))
- {
- throw new TestPlatformException(string.Format("Could not find the manifest file {0} for Registry free Com registration.", manifestFile));
- }
-
- return manifestFile;
- }
-
private void Dispose(bool disposing)
{
-
if (!this.isDisposed)
{
if (disposing)
@@ -490,5 +515,4 @@ private void Dispose(bool disposing)
}
}
}
-#endif
}
diff --git a/src/Microsoft.TestPlatform.ObjectModel/Navigation/NativeMethods.cs b/src/Microsoft.TestPlatform.ObjectModel/Navigation/NativeMethods.cs
new file mode 100644
index 0000000000..d207641584
--- /dev/null
+++ b/src/Microsoft.TestPlatform.ObjectModel/Navigation/NativeMethods.cs
@@ -0,0 +1,650 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+// ReSharper disable StyleCop.SA1602
+namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Navigation
+{
+ using System;
+ using System.IO;
+ using System.Reflection;
+ using System.Runtime.InteropServices;
+ using PlatformAbstractions;
+ internal static class HResult
+ {
+ public static bool Failed(int hr)
+ {
+ return hr < 0;
+ }
+
+ public static bool Succeeded(int hr)
+ {
+ return !Failed(hr);
+ }
+ }
+
+ ///
+ /// Some GUID constants we use to instantiate COM objects.
+ ///
+ internal static class Guids
+ {
+ internal static Guid CLSID_DiaSource = new Guid("79F1BB5F-B66E-48E5-B6A9-1545C323CA3D");
+ }
+
+ ///
+ /// DIA's IDiaEnumLineNumbers used for enumerating a symbol's line numbers.
+ ///
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("FE30E878-54AC-44f1-81BA-39DE940F6052")]
+ internal interface IDiaEnumLineNumbers
+ {
+ int Stub1();
+
+ [PreserveSig]
+ int GetCount(out uint count);
+
+ [PreserveSig]
+ int GetItem(uint index, out IDiaLineNumber line);
+
+ [PreserveSig]
+ int GetNext(uint celt, out IDiaLineNumber rgelt, out uint pceltFetched);
+
+ int Stub5();
+
+ int Stub6();
+
+ int Stub7();
+ }
+
+ ///
+ /// DIA's IDiaLineNumber used for retrieving line information.
+ ///
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("B388EB14-BE4D-421d-A8A1-6CF7AB057086")]
+ internal interface IDiaLineNumber
+ {
+ int Stub1();
+
+ [PreserveSig]
+ int GetSourceFile(out IDiaSourceFile file);
+
+ [PreserveSig]
+ int GetLineNumber(out uint line);
+
+ [PreserveSig]
+ int GetLineNumberEnd(out uint line);
+
+ [PreserveSig]
+ int GetColumnNumber(out uint line);
+
+ int Stub6();
+
+ int Stub7();
+
+ int Stub8();
+
+ int Stub9();
+
+ int Stub10();
+
+ int Stub11();
+
+ int Stub12();
+
+ int Stub13();
+
+ int Stub14();
+ }
+
+ ///
+ /// DIA's IDiaSession used for locating symbols.
+ ///
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("2F609EE1-D1C8-4E24-8288-3326BADCD211")]
+ internal interface IDiaSession
+ {
+ int Stub1();
+
+ int Stub2();
+
+ [PreserveSig]
+ int GetGlobalScope(out IDiaSymbol diaSymbol);
+
+ int Stub4();
+
+ int Stub5();
+
+ int Stub6();
+
+ int Stub7();
+
+ int Stub8();
+
+ int Stub9();
+
+ int Stub10();
+
+ int Stub11();
+
+ int Stub12();
+
+ int Stub13();
+
+ [PreserveSig]
+ int FindSymbolByToken(uint token, SymTagEnum tag, out IDiaSymbol symbol);
+
+ int Stub15();
+
+ int Stub16();
+
+ int Stub17();
+
+ int Stub18();
+
+ int Stub19();
+
+ int Stub20();
+
+ int Stub21();
+
+ [PreserveSig]
+ int FindLinesByAddress(uint section, uint offset, uint length, out IDiaEnumLineNumbers enumerator);
+
+ int Stub23();
+
+ int Stub24();
+
+ int Stub25();
+
+ int Stub26();
+
+ int Stub27();
+ }
+
+ ///
+ /// DIA's IDiaSourceFile used for getting source filenames.
+ ///
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("A2EF5353-F5A8-4eb3-90D2-CB526ACB3CDD")]
+ internal interface IDiaSourceFile
+ {
+ int Stub1();
+
+ [PreserveSig]
+ int GetFilename([MarshalAs(UnmanagedType.BStr)] out string filename);
+
+ int Stub3();
+
+ int Stub4();
+
+ int Stub5();
+ }
+
+ ///
+ /// Represents the DIA symbol tags.
+ ///
+ internal enum SymTagEnum : uint
+ {
+ SymTagNull,
+ SymTagExe,
+ SymTagCompiland,
+ SymTagCompilandDetails,
+ SymTagCompilandEnv,
+ SymTagFunction,
+ SymTagBlock,
+ SymTagData,
+ SymTagAnnotation,
+ SymTagLabel,
+ SymTagPublicSymbol,
+ SymTagUDT,
+ SymTagEnum,
+ SymTagFunctionType,
+ SymTagPointerType,
+ SymTagArrayType,
+ SymTagBaseType,
+ SymTagTypedef,
+ SymTagBaseClass,
+ SymTagFriend,
+ SymTagFunctionArgType,
+ SymTagFuncDebugStart,
+ SymTagFuncDebugEnd,
+ SymTagUsingNamespace,
+ SymTagVTableShape,
+ SymTagVTable,
+ SymTagCustom,
+ SymTagThunk,
+ SymTagCustomType,
+ SymTagManagedType,
+ SymTagDimension
+ }
+
+ ///
+ /// DIA's IDiaSymbol used for getting the address of function symbols.
+ ///
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("cb787b2f-bd6c-4635-ba52-933126bd2dcd")]
+ internal interface IDiaSymbol
+ {
+ int Stub1();
+
+ [PreserveSig]
+ int GetSymTag(out SymTagEnum tag);
+
+ int GetName(out string name);
+
+ int Stub4();
+
+ int Stub5();
+
+ int Stub6();
+
+ int Stub7();
+
+ int Stub8();
+
+ [PreserveSig]
+ int GetAddressSection(out uint section);
+
+ [PreserveSig]
+ int GetAddressOffset(out uint offset);
+
+ int Stub11();
+
+ int Stub12();
+
+ int Stub13();
+
+ int Stub14();
+
+ [PreserveSig]
+ int GetLength(out long length);
+
+ int Stub16();
+
+ int Stub17();
+
+ int Stub18();
+
+ int Stub19();
+
+ int Stub20();
+
+ int Stub21();
+
+ int Stub22();
+
+ int Stub23();
+
+ int Stub24();
+
+ int Stub25();
+
+ int Stub26();
+
+ int Stub27();
+
+ int Stub28();
+
+ int Stub29();
+
+ int Stub30();
+
+ int Stub31();
+
+ int Stub32();
+
+ int Stub33();
+
+ int Stub34();
+
+ int Stub35();
+
+ int Stub36();
+
+ int Stub37();
+
+ int Stub38();
+
+ int Stub39();
+
+ int Stub40();
+
+ int Stub41();
+
+ int Stub42();
+
+ int Stub43();
+
+ int Stub44();
+
+ int Stub45();
+
+ int Stub46();
+
+ int Stub47();
+
+ int Stub48();
+
+ int Stub49();
+
+ int Stub50();
+
+ int Stub51();
+
+ int Stub52();
+
+ int Stub53();
+
+ int Stub54();
+
+ int Stub55();
+
+ int Stub56();
+
+ int Stub57();
+
+ int Stub58();
+
+ int Stub59();
+
+ int Stub60();
+
+ int Stub61();
+
+ int Stub62();
+
+ int Stub63();
+
+ int Stub64();
+
+ int Stub65();
+
+ int Stub66();
+
+ int Stub67();
+
+ int Stub68();
+
+ int Stub69();
+
+ int Stub70();
+
+ int Stub71();
+
+ int Stub72();
+
+ int Stub73();
+
+ int Stub74();
+
+ int Stub75();
+
+ int Stub76();
+
+ int Stub77();
+
+ int Stub78();
+
+ int Stub79();
+
+ int Stub80();
+
+ int Stub81();
+
+ int Stub82();
+
+ [PreserveSig]
+ int FindChildren(SymTagEnum tag, string str, int flags, out IDiaEnumSymbols symbol);
+
+ int Stub84();
+
+ int Stub85();
+
+ int Stub86();
+
+ int Stub87();
+
+ int Stub88();
+
+ int Stub89();
+
+ int Stub90();
+
+ int Stub91();
+
+ int Stub92();
+
+ int Stub93();
+
+ int Stub94();
+
+ int Stub95();
+
+ int Stub96();
+
+ int Stub97();
+
+ int Stub98();
+
+ int Stub99();
+
+ int Stub100();
+
+ int Stub101();
+
+ int Stub102();
+
+ int Stub103();
+
+ int Stub104();
+
+ int Stub105();
+
+ int Stub106();
+
+ int Stub107();
+
+ int Stub108();
+
+ int Stub109();
+
+ int Stub110();
+
+ int Stub111();
+
+ int Stub112();
+
+ int Stub113();
+
+ int Stub114();
+
+ int Stub115();
+
+ int Stub116();
+
+ int Stub117();
+
+ int Stub118();
+
+ int Stub119();
+
+ int Stub120();
+
+ int Stub121();
+
+ int Stub122();
+
+ int Stub123();
+
+ int Stub124();
+
+ int Stub125();
+
+ int Stub126();
+
+ int Stub127();
+
+ int Stub128();
+
+ int Stub129();
+
+ int Stub130();
+
+ int Stub131();
+
+ int Stub132();
+
+ int Stub133();
+
+ int Stub134();
+
+ int Stub135();
+
+ int Stub136();
+
+ int Stub137();
+
+ int Stub138();
+
+ int Stub139();
+
+ int Stub140();
+
+ int Stub141();
+
+ int Stub142();
+
+ int Stub143();
+
+ int Stub144();
+
+ int Stub145();
+
+ int Stub146();
+
+ int Stub147();
+
+ int Stub148();
+
+ int Stub149();
+
+ int Stub150();
+
+ int Stub151();
+
+ int Stub152();
+
+ int Stub153();
+
+ int Stub154();
+
+ int Stub155();
+ }
+
+ // The definition for DiaSource COM object is present InternalApis\vctools\inc\dia2.h
+ // The GUID here must match what is present in dia2.h
+ [ComImport, CoClass(typeof(DiaSourceClass)), Guid("79F1BB5F-B66E-48E5-B6A9-1545C323CA3D")]
+ internal interface DiaSource : IDiaDataSource
+ {
+ }
+
+ // The definition for DiaSourceClass COM object is present InternalApis\vctools\inc\dia2.h
+ // The GUID here must match what is present in dia2.h
+ [ComImport, ClassInterface((short)0), Guid("E6756135-1E65-4D17-8576-610761398C3C")]
+ internal class DiaSourceClass
+ {
+ }
+
+ internal static class DiaSourceObject
+ {
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, int dwFlags);
+
+ public static IDiaDataSource GetDiaSourceObject()
+ {
+ var currentDirectory = new ProcessHelper().GetCurrentProcessLocation();
+
+ IntPtr modHandle = IntPtr.Zero;
+ if (IntPtr.Size == 8)
+ {
+ modHandle = LoadLibraryEx(Path.Combine(currentDirectory, "x64\\msdia140.dll"), IntPtr.Zero, 0);
+ }
+ else
+ {
+ modHandle = LoadLibraryEx(Path.Combine(currentDirectory, "x86\\msdia140.dll"), IntPtr.Zero, 0);
+ }
+
+ if(modHandle == IntPtr.Zero)
+ {
+ throw new COMException(string.Format(Resources.Resources.FailedToLoadMsDia));
+ }
+
+ var diaSourceClassGuid = new Guid("{E6756135-1E65-4D17-8576-610761398C3C}");
+ var comClassFactory = (IClassFactory)DllGetClassObject(diaSourceClassGuid, new Guid("00000001-0000-0000-C000-000000000046"));
+
+ Guid iDataDataSourceGuid = new Guid("79F1BB5F-B66E-48E5-B6A9-1545C323CA3D");
+ comClassFactory.CreateInstance(null, ref iDataDataSourceGuid, out object comObject);
+ return (comObject as IDiaDataSource);
+ }
+
+ #region private
+
+ [ComImport, ComVisible(false), Guid("00000001-0000-0000-C000-000000000046"),
+ InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ private interface IClassFactory
+ {
+ void CreateInstance(
+ [MarshalAs(UnmanagedType.Interface)] object aggregator,
+ ref Guid refiid,
+ [MarshalAs(UnmanagedType.Interface)] out object createdObject);
+
+ void LockServer(bool incrementRefCount);
+ }
+
+ [return: MarshalAs(UnmanagedType.Interface)]
+ [DllImport("msdia140.dll", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
+ internal static extern object DllGetClassObject(
+ [In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
+ [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);
+
+ #endregion
+ }
+
+ ///
+ /// DIA's IDiaDataSource used for opening symbols.
+ ///
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("79F1BB5F-B66E-48E5-B6A9-1545C323CA3D")]
+ internal interface IDiaDataSource
+ {
+ int Stub1();
+
+ int Stub2();
+
+ int Stub3();
+
+ [PreserveSig]
+ int LoadDataForExe(
+ [MarshalAs(UnmanagedType.LPWStr)] string executable,
+ [MarshalAs(UnmanagedType.LPWStr)] string searchPath,
+ IntPtr callback);
+
+ int Stub5();
+
+ [PreserveSig]
+ int OpenSession(out IDiaSession session);
+ }
+
+ [ComImport, Guid("CAB72C48-443B-48F5-9B0B-42F0820AB29A"), InterfaceType(1)]
+ internal interface IDiaEnumSymbols
+ {
+ int Stub1();
+
+ [PreserveSig]
+ int GetCount(out uint count);
+
+ [PreserveSig]
+ int GetItem(uint index, out IDiaSymbol symbol);
+
+ int GetNext(uint index, out IDiaSymbol symbol, out uint pceltFetched);
+
+ int Stub5();
+
+ int Stub6();
+
+ int Stub7();
+ }
+}
diff --git a/src/Microsoft.TestPlatform.ObjectModel/Resources/Resources.Designer.cs b/src/Microsoft.TestPlatform.ObjectModel/Resources/Resources.Designer.cs
index d266d82eb3..d729dffa26 100644
--- a/src/Microsoft.TestPlatform.ObjectModel/Resources/Resources.Designer.cs
+++ b/src/Microsoft.TestPlatform.ObjectModel/Resources/Resources.Designer.cs
@@ -621,5 +621,27 @@ internal static string UnexpectedTypeOfProperty {
return ResourceManager.GetString("UnexpectedTypeOfProperty", resourceCulture);
}
}
+
+ ///
+ /// Looks up a localized string similar to The test property type '{0}' of property '{1}' is not supported. Use one of the supported property type (primitive types, uri, string, string[]) and try again. .
+ ///
+ internal static string FailedToLoadMsDia
+ {
+ get
+ {
+ return ResourceManager.GetString("FailedToLoadMsDia", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The test property type '{0}' of property '{1}' is not supported. Use one of the supported property type (primitive types, uri, string, string[]) and try again. .
+ ///
+ internal static string FailedToCreateDiaSession
+ {
+ get
+ {
+ return ResourceManager.GetString("FailedToCreateDiaSession", resourceCulture);
+ }
+ }
}
}
diff --git a/src/Microsoft.TestPlatform.ObjectModel/Resources/Resources.resx b/src/Microsoft.TestPlatform.ObjectModel/Resources/Resources.resx
index 5fc03daba9..35f3531d7b 100644
--- a/src/Microsoft.TestPlatform.ObjectModel/Resources/Resources.resx
+++ b/src/Microsoft.TestPlatform.ObjectModel/Resources/Resources.resx
@@ -329,4 +329,10 @@
The test property type '{0}' of property '{1}' is not supported. Use one of the supported property type (primitive types, uri, string, string[]) and try again.
+
+ Failed to Create msdia Session COM HResult '{0}'.
+
+
+ Failed to load msdia
+
\ No newline at end of file
diff --git a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/Resources.cs.xlf b/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/Resources.cs.xlf
index ffa819b7ad..748572c3d8 100644
--- a/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/Resources.cs.xlf
+++ b/src/Microsoft.TestPlatform.ObjectModel/Resources/xlf/Resources.cs.xlf
@@ -587,6 +587,16 @@
fuzzyMatch="15" wordcount="7" adjWordcount="5.95" curWordcount="5.95"
+
+ Failed to Create msdia Session COM HResult '{0}'.
+ Failed to Create msdia Session COM HResult '{0}'.
+
+
+
+ Failed to load msdia
+ Failed to load msdia
+
+