Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
0961a07f
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
0961a07f
编写于
5月 21, 2016
作者:
D
Dustin Campbell
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add debug output for SendKeys
上级
80848dcf
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
218 addition
and
7 deletion
+218
-7
src/VisualStudio/TestUtilities/IntegrationHelper.cs
src/VisualStudio/TestUtilities/IntegrationHelper.cs
+202
-7
src/VisualStudio/TestUtilities/Interop/User32.cs
src/VisualStudio/TestUtilities/Interop/User32.cs
+16
-0
未找到文件。
src/VisualStudio/TestUtilities/IntegrationHelper.cs
浏览文件 @
0961a07f
...
...
@@ -14,6 +14,7 @@
using
Microsoft.VisualStudio
;
using
Microsoft.VisualStudio.OLE.Interop
;
using
Microsoft.Win32
;
using
Roslyn.Utilities
;
using
Roslyn.VisualStudio.Test.Utilities.Interop
;
using
Process
=
System
.
Diagnostics
.
Process
;
...
...
@@ -168,7 +169,8 @@ public static IEnumerable<IntPtr> GetTopLevelWindows()
{
var
topLevelWindows
=
new
List
<
IntPtr
>();
var
enumFunc
=
new
User32
.
WNDENUMPROC
((
hWnd
,
lParam
)
=>
{
var
enumFunc
=
new
User32
.
WNDENUMPROC
((
hWnd
,
lParam
)
=>
{
topLevelWindows
.
Add
(
hWnd
);
return
true
;
});
...
...
@@ -187,7 +189,7 @@ public static IEnumerable<IntPtr> GetTopLevelWindows()
/// <summary>Kills the specified process if it is not <c>null</c> and has not already exited.</summary>
public
static
void
KillProcess
(
Process
process
)
{
if
(
(
process
!=
null
)
&&
(!
process
.
HasExited
)
)
if
(
process
!=
null
&&
!
process
.
HasExited
)
{
process
.
Kill
();
}
...
...
@@ -223,7 +225,8 @@ public static void RetryRpcCall(Action action)
public
static
T
RetryRpcCall
<
T
>(
Func
<
T
>
action
)
{
T
returnValue
=
default
(
T
);
RetryRpcCall
(()
=>
{
RetryRpcCall
(()
=>
{
returnValue
=
action
();
});
return
returnValue
;
...
...
@@ -249,7 +252,7 @@ public static void SetForegroundWindow(IntPtr window)
threadInputsAttached
=
AttachThreadInput
(
currentThreadId
,
activeThreadId
);
// Make the window a top-most window so it will appear above any existing top-most windows
User32
.
SetWindowPos
(
window
,
(
IntPtr
)
(
User32
.
HWND_TOPMOST
)
,
0
,
0
,
0
,
0
,
(
User32
.
SWP_NOSIZE
|
User32
.
SWP_NOMOVE
));
User32
.
SetWindowPos
(
window
,
(
IntPtr
)
User32
.
HWND_TOPMOST
,
0
,
0
,
0
,
0
,
(
User32
.
SWP_NOSIZE
|
User32
.
SWP_NOMOVE
));
// Move the window into the foreground as it may not have been achieved by the 'SetWindowPos' call
var
success
=
User32
.
SetForegroundWindow
(
window
);
...
...
@@ -266,7 +269,7 @@ public static void SetForegroundWindow(IntPtr window)
User32
.
SetFocus
(
window
);
// Remove the 'Top-Most' qualification from the window
User32
.
SetWindowPos
(
window
,
(
IntPtr
)
(
User32
.
HWND_NOTOPMOST
)
,
0
,
0
,
0
,
0
,
(
User32
.
SWP_NOSIZE
|
User32
.
SWP_NOMOVE
));
User32
.
SetWindowPos
(
window
,
(
IntPtr
)
User32
.
HWND_NOTOPMOST
,
0
,
0
,
0
,
0
,
(
User32
.
SWP_NOSIZE
|
User32
.
SWP_NOMOVE
));
}
finally
{
...
...
@@ -278,9 +281,13 @@ public static void SetForegroundWindow(IntPtr window)
}
}
public
static
void
SendInput
(
User32
.
INPUT
[]
input
)
public
static
void
SendInput
(
User32
.
INPUT
[]
input
s
)
{
var
eventsInserted
=
User32
.
SendInput
((
uint
)(
input
.
Length
),
input
,
User32
.
SizeOf_INPUT
);
// NOTE: This assumes that Visual Studio is the active foreground window.
LogKeyboardInputs
(
inputs
);
var
eventsInserted
=
User32
.
SendInput
((
uint
)
inputs
.
Length
,
inputs
,
User32
.
SizeOf_INPUT
);
if
(
eventsInserted
==
0
)
{
...
...
@@ -289,6 +296,194 @@ public static void SendInput(User32.INPUT[] input)
}
}
[
Conditional
(
"DEBUG"
)]
private
static
void
LogKeyboardInputs
(
User32
.
INPUT
[]
inputs
)
{
foreach
(
var
input
in
inputs
)
{
switch
(
input
.
Type
)
{
case
User32
.
INPUT_KEYBOARD
:
LogKeyboardInput
(
input
.
ki
);
break
;
case
User32
.
INPUT_MOUSE
:
Debug
.
WriteLine
(
"UNEXPECTED: Encountered mouse input"
);
break
;
case
User32
.
INPUT_HARDWARE
:
Debug
.
WriteLine
(
"UNEXPECTED: Encountered hardware input"
);
break
;
default
:
Debug
.
WriteLine
(
$"ERROR: Encountered illegal input type:
{
input
.
Type
}
"
);
break
;
}
}
}
[
Conditional
(
"DEBUG"
)]
private
static
void
LogKeyboardInput
(
User32
.
KEYBDINPUT
input
)
{
var
isExtendedKey
=
(
input
.
dwFlags
&
User32
.
KEYEVENTF_EXTENDEDKEY
)
!=
0
;
var
isKeyUp
=
(
input
.
dwFlags
&
User32
.
KEYEVENTF_KEYUP
)
!=
0
;
var
isUnicode
=
(
input
.
dwFlags
&
User32
.
KEYEVENTF_UNICODE
)
!=
0
;
var
isScanCode
=
(
input
.
dwFlags
&
User32
.
KEYEVENTF_SCANCODE
)
!=
0
;
if
(
isUnicode
&&
input
.
wVk
!=
0
)
{
Debug
.
WriteLine
(
"UNEXPECTED: if KEYEVENTF_UNICODE flag is specified then wVk must be 0."
);
return
;
}
var
builder
=
SharedPools
.
Default
<
StringBuilder
>().
AllocateAndClear
();
builder
.
Append
(
"Send Key: "
);
ushort
ch
;
if
(
isUnicode
||
isScanCode
)
{
ch
=
input
.
wScan
;
}
else
{
ch
=
(
ushort
)(
User32
.
MapVirtualKey
(
input
.
wVk
,
User32
.
MAPVK_VK_TO_CHAR
)
&
0x0000ffff
);
}
// Append code and printable character
builder
.
Append
(
ch
.
ToString
(
"x4"
));
builder
.
Append
(
' '
);
AppendPrintableChar
((
char
)
ch
,
builder
);
if
(!
isUnicode
&&
!
isScanCode
)
{
AppendVirtualKey
(
input
.
wVk
,
builder
);
}
// Append flags
if
(
input
.
dwFlags
==
0
)
{
builder
.
Append
(
"[none]"
);
}
else
{
builder
.
Append
(
'['
);
if
(
isExtendedKey
)
{
AppendFlag
(
"extended"
,
builder
);
}
if
(
isKeyUp
)
{
AppendFlag
(
"key up"
,
builder
);
}
if
(
isUnicode
)
{
AppendFlag
(
"unicode"
,
builder
);
}
if
(
isScanCode
)
{
AppendFlag
(
"scan code"
,
builder
);
}
builder
.
Append
(
']'
);
}
Debug
.
WriteLine
(
builder
.
ToString
());
SharedPools
.
Default
<
StringBuilder
>().
ClearAndFree
(
builder
);
}
private
static
void
AppendPrintableChar
(
char
ch
,
StringBuilder
builder
)
{
string
text
=
GetPrintableCharText
(
ch
);
if
(
text
!=
null
)
{
builder
.
Append
(
"'"
);
builder
.
Append
(
text
);
builder
.
Append
(
"' "
);
}
}
private
static
string
GetPrintableCharText
(
char
ch
)
{
switch
(
ch
)
{
case
'\r'
:
return
@"\r"
;
case
'\n'
:
return
@"\n"
;
case
'\t'
:
return
@"\t"
;
case
'\f'
:
return
@"\f"
;
case
'\v'
:
return
@"\v"
;
default
:
return
!
char
.
IsControl
(
ch
)
?
new
string
(
ch
,
1
)
:
null
;
}
}
private
static
void
AppendVirtualKey
(
ushort
virtualKey
,
StringBuilder
builder
)
{
switch
(
virtualKey
)
{
case
User32
.
VK_CONTROL
:
builder
.
Append
(
"(VK_CONTROL) "
);
break
;
case
User32
.
VK_DELETE
:
builder
.
Append
(
"(VK_DELETE) "
);
break
;
case
User32
.
VK_DOWN
:
builder
.
Append
(
"(VK_DOWN) "
);
break
;
case
User32
.
VK_END
:
builder
.
Append
(
"(VK_END) "
);
break
;
case
User32
.
VK_HOME
:
builder
.
Append
(
"(VK_HOME) "
);
break
;
case
User32
.
VK_INSERT
:
builder
.
Append
(
"(VK_INSERT) "
);
break
;
case
User32
.
VK_LEFT
:
builder
.
Append
(
"(VK_LEFT) "
);
break
;
case
User32
.
VK_MENU
:
builder
.
Append
(
"(VK_MENU) "
);
break
;
case
User32
.
VK_NEXT
:
builder
.
Append
(
"(VK_NEXT) "
);
break
;
case
User32
.
VK_PRIOR
:
builder
.
Append
(
"(VK_PRIOR) "
);
break
;
case
User32
.
VK_RIGHT
:
builder
.
Append
(
"(VK_RIGHT) "
);
break
;
case
User32
.
VK_SHIFT
:
builder
.
Append
(
"(VK_SHIFT) "
);
break
;
case
User32
.
VK_UP
:
builder
.
Append
(
"(VK_UP) "
);
break
;
}
}
[
Conditional
(
"DEBUG"
)]
private
static
void
AppendFlag
(
string
flagText
,
StringBuilder
builder
)
{
if
(
builder
.
Length
>
0
&&
builder
[
builder
.
Length
-
1
]
!=
'['
)
{
builder
.
Append
(
", "
);
}
builder
.
Append
(
flagText
);
}
public
static
bool
TryDeleteDirectoryRecursively
(
string
path
)
{
try
...
...
src/VisualStudio/TestUtilities/Interop/User32.cs
浏览文件 @
0961a07f
...
...
@@ -233,5 +233,21 @@ public struct MOUSEINPUT
public
static
extern
short
VkKeyScan
(
[
In
]
char
ch
);
[
DllImport
(
"User32.dll"
,
CallingConvention
=
CallingConvention
.
Winapi
,
EntryPoint
=
"GetKeyNameTextW"
,
PreserveSig
=
true
,
SetLastError
=
true
)]
public
static
extern
int
GetKeyNameText
(
[
In
]
long
lParam
,
[
Out
,
MarshalAs
(
UnmanagedType
.
LPTStr
)]
StringBuilder
lpString
,
[
In
]
int
cchSize
);
[
DllImport
(
"User32.dll"
,
CallingConvention
=
CallingConvention
.
Winapi
,
EntryPoint
=
"MapVirtualKeyW"
,
PreserveSig
=
true
,
SetLastError
=
false
)]
public
static
extern
uint
MapVirtualKey
(
[
In
]
uint
uCode
,
[
In
]
uint
uMapType
);
public
const
uint
MAPVK_VK_TO_VSC
=
0
;
public
const
uint
MAPVK_VSC_TO_VK
=
1
;
public
const
uint
MAPVK_VK_TO_CHAR
=
2
;
public
const
uint
MAPVK_VSC_TO_KV_EX
=
3
;
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录