调用Windows的SendMessageW函数从GO语言中永远不会返回。

huangapple go评论131阅读模式
英文:

Calling Windows SendMessageW from GOlang never returns

问题

尝试编写一个非常简单的用于关闭 Windows 显示器的 GO 程序。代码如下:

  1. //go:build windows
  2. // +build windows
  3. package main
  4. import (
  5. log "github.com/sirupsen/logrus"
  6. "golang.org/x/sys/windows"
  7. )
  8. func main() {
  9. user32DLL := windows.NewLazyDLL("user32.dll")
  10. procSendMsg := user32DLL.NewProc("SendMessageW")
  11. a, b, err := procSendMsg.Call(0xFFFF, 0x0112, 0xF170, 2)
  12. if err != nil {
  13. log.Errorf("Error returned from SendMsg: %v", err)
  14. }
  15. log.Infof("a = %v, b = %v:", a, b)
  16. }

该程序确实可以工作(即关闭显示器),但是在 procSendMsg.Call() 后没有返回,没有错误,并且我看不到 ab 的输出。我必须使用 Ctrl-C 来退出程序。

显然,我在调用 user32.dll 函数方面做错了什么...这是我第一次尝试使用 GO 编写 Windows 程序。

我做错了什么?

[提示:我从这个 PowerShell 脚本中得到了灵感:

  1. (Add-Type -MemberDefinition "[DllImport(""user32.dll"")]`npublic static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);" -Name "Win32SendMessage" -Namespace Win32Functions -PassThru)::SendMessage(0xffff, 0x0112, 0xF170, 2)
  2. ]
  3. 谢谢你的反馈
  4. <details>
  5. <summary>英文:</summary>
  6. Trying to write a very simple GO program for Windows that turns off the monitor. The code looks like this:
  7. //go:build windows
  8. // +build windows
  9. package main
  10. import (
  11. log &quot;github.com/sirupsen/logrus&quot;
  12. &quot;golang.org/x/sys/windows&quot;
  13. )
  14. func main() {
  15. user32DLL := windows.NewLazyDLL(&quot;user32.dll&quot;)
  16. procSendMsg := user32DLL.NewProc(&quot;SendMessageW&quot;)
  17. a, b, err := procSendMsg.Call(0xFFFF, 0x0112, 0xF170, 2)
  18. if err != nil {
  19. log.Errorf(&quot;Error returned from SendMsg: %v&quot;, err)
  20. }
  21. log.Infof(&quot;a = %v, b = %v:&quot;, a, b)
  22. }
  23. The program does work (IE&gt; the monitor turns off), but never returns from the procSendMsg.Call() -- no errors, and I never see the output of &#39;a&#39; and &#39;b&#39;. I have to Ctrl-C to get out of the program.
  24. Obviously I&#39;m doing something wrong w.r.t. calling the user32.dll function...this IS my first attempt at writing a Windows program with GO.
  25. What am I doing wrong?
  26. [FYI: I got the idea from this PowerShell script:
  27. (Add-Type -MemberDefinition &quot;[DllImport(&quot;&quot;user32.dll&quot;&quot;)]`npublic static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);&quot; -Name &quot;Win32SendMessage&quot; -Namespace Win32Functions -PassThru)::SendMessage(0xffff, 0x0112, 0xF170, 2)
  28. ]
  29. Thanks for your feedback!!
  30. </details>
  31. # 答案1
  32. **得分**: 1
  33. FYI这是工作版本
  34. //go:build windows
  35. // +build windows
  36. package main
  37. //
  38. // turnOffMonitor -- 关闭Windows上的显示器信号相比使用'scrnsave.scr /s'只是屏幕变黑这是更好的省电方式
  39. //
  40. // John D. Allen
  41. // 2022年9月
  42. //
  43. import (
  44. "strings"
  45. log "github.com/sirupsen/logrus"
  46. "golang.org/x/sys/windows"
  47. )
  48. func main() {
  49. user32DLL := windows.NewLazyDLL("user32.dll")
  50. procPostMsg := user32DLL.NewProc("PostMessageW")
  51. _, _, err := procPostMsg.Call(0xFFFF, 0x0112, 0xF170, 2)
  52. //
  53. // 当我以没有SYSTEM权限的用户运行时我会收到拒绝访问的错误...但出于某种原因它仍然可以工作
  54. if err != nil && !strings.Contains(err.Error(), "Access is denied.") {
  55. log.Errorf("从PostMsg()返回的错误:%v", err)
  56. }
  57. }
  58. <details>
  59. <summary>英文:</summary>
  60. FYI: Here is the working version.
  61. //go:build windows
  62. // +build windows
  63. package main
  64. //
  65. // turnOffMonitor -- Shuts down the signal to the monitor on Windows. A better power saver
  66. // over using &#39;scrnsave.scr /s&#39; to just blank the screen.
  67. //
  68. // John D. Allen
  69. // September, 2022
  70. //
  71. import (
  72. &quot;strings&quot;
  73. log &quot;github.com/sirupsen/logrus&quot;
  74. &quot;golang.org/x/sys/windows&quot;
  75. )
  76. func main() {
  77. user32DLL := windows.NewLazyDLL(&quot;user32.dll&quot;)
  78. procPostMsg := user32DLL.NewProc(&quot;PostMessageW&quot;)
  79. _, _, err := procPostMsg.Call(0xFFFF, 0x0112, 0xF170, 2)
  80. //
  81. // I get a &quot;Access is denied.&quot; error when I run this from a user that does
  82. // not have SYSTEM rights...but it still works anyway for some reason.
  83. if err != nil &amp;&amp; !strings.Contains(err.Error(), &quot;Access is denied.&quot;) {
  84. log.Errorf(&quot;Error returned from PostMsg(): %v&quot;, err)
  85. }
  86. }
  87. </details>

huangapple
  • 本文由 发表于 2022年9月8日 22:26:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/73650720.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定