-
Notifications
You must be signed in to change notification settings - Fork 325
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix get process architecture #3726
Merged
Merged
Changes from 3 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
e35d796
Fix get process architecture
nohwnd 156ccaf
Fix getting process architecture, when it is not the current process
nohwnd 049ebbf
Remove extra class
nohwnd dc0b8ca
One more fallback to x64
nohwnd 287bcba
Apply review comments
nohwnd 5e65fa3
Merge branch 'main' into fix-get-process-architecture
nohwnd 0c2d602
Fix
nohwnd File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
41 changes: 0 additions & 41 deletions
41
src/Microsoft.TestPlatform.Extensions.BlameDataCollector/NativeMethodsHelper.cs
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -23,37 +23,69 @@ public string GetCurrentProcessLocation() | |||||
=> Path.GetDirectoryName(GetCurrentProcessFileName()); | ||||||
|
||||||
/// <inheritdoc/> | ||||||
public IntPtr GetProcessHandle(int processId) | ||||||
=> Process.GetProcessById(processId).Handle; | ||||||
public IntPtr GetProcessHandle(int processId) => | ||||||
processId == _currentProcess.Id | ||||||
? _currentProcess.Handle | ||||||
: Process.GetProcessById(processId).Handle; | ||||||
|
||||||
/// <inheritdoc/> | ||||||
public PlatformArchitecture GetCurrentProcessArchitecture() | ||||||
=> _currentProcessArchitecture ??= GetProcessArchitecture(Process.GetCurrentProcess().Id); | ||||||
|
||||||
{ | ||||||
_currentProcessArchitecture ??= GetProcessArchitecture(_currentProcess.Id); | ||||||
return _currentProcessArchitecture.Value; | ||||||
} | ||||||
|
||||||
public PlatformArchitecture GetProcessArchitecture(int processId) | ||||||
=> IntPtr.Size == 8 | ||||||
? IsArm64(processId) | ||||||
? PlatformArchitecture.ARM64 | ||||||
: PlatformArchitecture.X64 | ||||||
: PlatformArchitecture.X86; | ||||||
|
||||||
private static bool IsArm64(int processId) | ||||||
{ | ||||||
if (_currentProcess.Id == processId) | ||||||
{ | ||||||
// If we already cached the current process architecture, no need to figure it out again. | ||||||
if (_currentProcessArchitecture != null) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added. |
||||||
{ | ||||||
return _currentProcessArchitecture.Value; | ||||||
} | ||||||
|
||||||
// When this is current process, we can just check if IntPointer size to get if we are 64-bit or 32-bit. | ||||||
// When it is 32-bit we can just return, if it is 64-bit we need to clarify if x64 or arm64. | ||||||
if (IntPtr.Size == 4) | ||||||
{ | ||||||
return PlatformArchitecture.X86; | ||||||
} | ||||||
} | ||||||
|
||||||
// If the current process is 64-bit, or this is any remote process, we need to query it via native api. | ||||||
var process = processId == _currentProcess.Id ? _currentProcess : Process.GetProcessById(processId); | ||||||
try | ||||||
{ | ||||||
var process = Process.GetProcessById(processId); | ||||||
if (!NativeMethods.IsWow64Process2(process.Handle, out ushort processMachine, out ushort nativeMachine)) | ||||||
{ | ||||||
throw new Win32Exception(); | ||||||
} | ||||||
|
||||||
// If processMachine is IMAGE_FILE_MACHINE_UNKNOWN mean that we're not running using WOW64 x86 emulation. | ||||||
if (processMachine != NativeMethods.IMAGE_FILE_MACHINE_UNKNOWN) | ||||||
{ | ||||||
// The process is running using WOW64, which suggests it is 32-bit (or any of the other machines, that we cannot | ||||||
// handle, so we just assume x86). | ||||||
return PlatformArchitecture.X86; | ||||||
} | ||||||
|
||||||
// If processMachine is IMAGE_FILE_MACHINE_UNKNOWN mean that we're not running using WOW64 emulation. | ||||||
// If nativeMachine is IMAGE_FILE_MACHINE_ARM64 mean that we're running on ARM64 architecture device. | ||||||
if (processMachine == NativeMethods.IMAGE_FILE_MACHINE_UNKNOWN && nativeMachine == NativeMethods.IMAGE_FILE_MACHINE_ARM64) | ||||||
{ | ||||||
// To distinguish between ARM64 and x64 emulated on ARM64 we check the PE header of the current running executable. | ||||||
return IsArm64Executable(process.MainModule.FileName); | ||||||
if (IsArm64Executable(process.MainModule.FileName)) | ||||||
{ | ||||||
return PlatformArchitecture.ARM64; | ||||||
} | ||||||
else | ||||||
{ | ||||||
return PlatformArchitecture.X64; | ||||||
} | ||||||
} | ||||||
else | ||||||
{ | ||||||
return PlatformArchitecture.X64; | ||||||
} | ||||||
} | ||||||
catch | ||||||
|
@@ -64,9 +96,33 @@ private static bool IsArm64(int processId) | |||||
// we loaded runner version of Microsoft.TestPlatform.PlatformAbstractions but newer version Microsoft.TestPlatform.ObjectModel(the one close | ||||||
// to the test container) and the old PlatformAbstractions doesn't contain the methods expected by the new ObjectModel throwing | ||||||
// a MissedMethodException. | ||||||
} | ||||||
|
||||||
return false; | ||||||
try | ||||||
{ | ||||||
if (!Environment.Is64BitOperatingSystem) | ||||||
{ | ||||||
// When we know this is not 64-bit operating system, then all processes are running as 32-bit, both | ||||||
// the current process and other processes. | ||||||
return PlatformArchitecture.X86; | ||||||
} | ||||||
|
||||||
var isWow64Process = NativeMethods.IsWow64Process(process.Handle, out var isWow64); | ||||||
if (!isWow64Process) | ||||||
{ | ||||||
// Do nothing we cannot log errors here. | ||||||
} | ||||||
Evangelink marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
// The process is running using WOW64, which suggests it is 32-bit (or any of the other machines, that we cannot | ||||||
// handle, so we just assume x86). If it is not wow, we assume x64, because we failed the call to more advanced api | ||||||
// that can tell us if this is arm64, so we are probably on older version of OS which is x64. | ||||||
// We could call PlatformArchitecture.Architecture, but that uses the same api that we just failed to invoke. | ||||||
return isWow64 ? PlatformArchitecture.X86 : PlatformArchitecture.X64; | ||||||
} | ||||||
catch | ||||||
{ | ||||||
// Do nothing we cannot log errors here. | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
private static bool IsArm64Executable(string path) | ||||||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can add
CallingConvention = CallingConvention.Winapi
and the return annotation also aboveThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added.