diff --git a/src/Tasks.UnitTests/ComReference_Tests.cs b/src/Tasks.UnitTests/ComReference_Tests.cs index aa2ca18dd77..0ad723e95d7 100644 --- a/src/Tasks.UnitTests/ComReference_Tests.cs +++ b/src/Tasks.UnitTests/ComReference_Tests.cs @@ -45,6 +45,8 @@ public void TestStripTypeLibNumber() return; // "COM is only found on Windows" } + Assert.Equal(null, ComReference.StripTypeLibNumberFromPath(null, new FileExists(FileExistsMock))); + Assert.Equal("", ComReference.StripTypeLibNumberFromPath("", new FileExists(FileExistsMock))); Assert.Equal(@"C:\test\typelib1.dll", ComReference.StripTypeLibNumberFromPath(@"C:\test\typelib1.dll", new FileExists(FileExistsMock))); Assert.Equal(@"C:\test\typelib2\2.dll", ComReference.StripTypeLibNumberFromPath(@"C:\test\typelib2\2.dll", new FileExists(FileExistsMock))); Assert.Equal(@"C:\test\typelib3.\3dll", ComReference.StripTypeLibNumberFromPath(@"C:\test\typelib3.\3dll", new FileExists(FileExistsMock))); diff --git a/src/Tasks/ComReference.cs b/src/Tasks/ComReference.cs index cdd53ef96d5..0ee182faf1d 100644 --- a/src/Tasks/ComReference.cs +++ b/src/Tasks/ComReference.cs @@ -386,18 +386,7 @@ internal static string StripTypeLibNumberFromPath(string typeLibPath, FileExists { try { - var sb = new StringBuilder(NativeMethodsShared.MAX_PATH); - System.Runtime.InteropServices.HandleRef handleRef = new System.Runtime.InteropServices.HandleRef(sb, libraryHandle); - int len = NativeMethodsShared.GetModuleFileName(handleRef, sb, sb.Capacity); - if ((len != 0) && - ((uint)Marshal.GetLastWin32Error() != NativeMethodsShared.ERROR_INSUFFICIENT_BUFFER)) - { - typeLibPath = sb.ToString(); - } - else - { - typeLibPath = ""; - } + typeLibPath = GetModuleFileName(libraryHandle); } finally { @@ -413,6 +402,26 @@ internal static string StripTypeLibNumberFromPath(string typeLibPath, FileExists return typeLibPath; } + private static string GetModuleFileName(IntPtr handle) + { + bool success = false; + var buffer = new StringBuilder(); + + // Try increased buffer sizes if on longpath-enabled Windows + for (int bufferSize = NativeMethodsShared.MAX_PATH; !success && bufferSize <= NativeMethodsShared.MaxPath; bufferSize *= 2) + { + buffer.EnsureCapacity(bufferSize); + + var handleRef = new System.Runtime.InteropServices.HandleRef(buffer, handle); + int pathLength = NativeMethodsShared.GetModuleFileName(handleRef, buffer, buffer.Capacity); + + bool isBufferTooSmall = ((uint)Marshal.GetLastWin32Error() == NativeMethodsShared.ERROR_INSUFFICIENT_BUFFER); + success = pathLength != 0 && !isBufferTooSmall; + } + + return success ? buffer.ToString() : string.Empty; + } + /// /// Gets the type lib path for given type lib attributes(reused almost verbatim from vsdesigner utils code) /// NOTE: If there's a typelib number at the end of the path, does NOT strip it.