lxn / win Goto Github PK
View Code? Open in Web Editor NEWA Windows API wrapper package for the Go Programming Language
License: Other
A Windows API wrapper package for the Go Programming Language
License: Other
Hi,
Was actually looking for a mail address, but seeing I couldn't find one I thought I'd file an issue instead. Anyway, I've been investigating this Performance Counters thing under Windows, to see if that's a viable option to find out data like CPU usage, memory usage, disk IO and whatnot, except in Go.
Seeing you've got way more experience in the Windows API, I thought I'd ask this to you before pursuing this quest: do you think it's a viable option to create a wrapper around the pdh.dll
in Go?
There's some example C code here on its usage.
Got any ideas, obstacles beforehand etc.?
Kevin
I am trying to add the PdhParseCounterPath function (as documented here https://msdn.microsoft.com/en-us/library/windows/desktop/aa372657(v=vs.85).aspx ) into pdh.go, but I am a bit unsure of how to do so. Wondering if any of the contributors could offer a little help? Here is what I've added:
type PDH_COUNTER_PATH_ELEMENTS struct {
szMachineName string
szObjectName string
szInstanceName string
szParentInstance string
dwInstanceIndex uintptr
szCounterName string
}
var (
// Library
libpdhDll *syscall.DLL
// Functions
pdh_AddCounterW *syscall.Proc
pdh_AddEnglishCounterW *syscall.Proc
pdh_CloseQuery *syscall.Proc
pdh_CollectQueryData *syscall.Proc
pdh_GetFormattedCounterValue *syscall.Proc
pdh_GetFormattedCounterArrayW *syscall.Proc
pdh_OpenQuery *syscall.Proc
pdh_ValidatePathW *syscall.Proc
pdh_ParseCounterPathW *syscall.Proc // added this
)
func init() {
// Library
libpdhDll = syscall.MustLoadDLL("pdh.dll")
// Functions
pdh_AddCounterW = libpdhDll.MustFindProc("PdhAddCounterW")
pdh_AddEnglishCounterW, _ = libpdhDll.FindProc("PdhAddEnglishCounterW") // XXX: only supported on versions > Vista.
pdh_CloseQuery = libpdhDll.MustFindProc("PdhCloseQuery")
pdh_CollectQueryData = libpdhDll.MustFindProc("PdhCollectQueryData")
pdh_GetFormattedCounterValue = libpdhDll.MustFindProc("PdhGetFormattedCounterValue")
pdh_GetFormattedCounterArrayW = libpdhDll.MustFindProc("PdhGetFormattedCounterArrayW")
pdh_OpenQuery = libpdhDll.MustFindProc("PdhOpenQuery")
pdh_ValidatePathW = libpdhDll.MustFindProc("PdhValidatePathW")
pdh_ParseCounterPathW = libpdhDll.MustFindProc("PdhParseCounterPathW") // added this
}
func PdhParseCounterPath(szFullPathBuffer string, pCounterPathElements *PDH_COUNTER_PATH_ELEMENTS) uint32 {
ptxt, _ := syscall.UTF16PtrFromString(szFullPathBuffer)
var test uint32
ret, _, _ := pdh_ParseCounterPathW.Call(
uintptr(unsafe.Pointer(ptxt)), // I think this is correct
uintptr(unsafe.Pointer(pCounterPathElements)), // not sure what to do here
uintptr(unsafe.Pointer(&test)), // not sure what to do here
0) // I think this is correct
return uint32(ret)
}
Hi there,
I get a hwnd from FindWindow but the EnumChildWindows callback doesn't print anything. Am I using it wrong? Thanks.
func main() {
var hw win.HWND
var windowName = "window"
hw = win.FindWindow(nil, syscall.StringToUTF16Ptr(windowName))
spew.Dump(hw)
win.EnumChildWindows(hw, syscall.NewCallback(printme), 0)
}
func printme(HWND uintptr, LPARAM uintptr) { //HWND hwnd, LPARAM lParam
spew.Dump(HWND)
}
Apparently this was never tested before merging.
x, _ := walk.NewMainWindow()
x.Accessibility().SetName("THIS IS A TEST TEST TEST")
x.Show()
x.Run()
This fails because syscall.Syscall9(obj.LpVtbl.SetHwndPropStr
in this repo probably needs more arguments for the calling convention on 32-bit.
@rozmansi - please fix.
Is there any documentation? If not, it'd be great to have some documentation.
Is keybd_event() renamed or is there no way to do it?
func keys() {
for {
time.Sleep(1 * time.Millisecond)
for KEY := 0; KEY <= 256; KEY++ {
Val, _, _ := procGetKeyState.Call(uintptr(KEY))
if int(Val) == -32767 {
switch KEY {
case 0x30:
tmp += "0"
case 0x31:
tmp += "1"
case 0x32:
tmp += "2"
}
}
}
}
}
how to catch keystrokes ? tmp empty. GetAsyncKeyState missing?
I get all the child window handle through enumeration(EnumChildWindows) . How do I get the class name of each child window according to the handle?
i want to know how to use this function.THX
The parameters of Syscall method in syscall package of golang are defined as such:
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
but in the project the parameters are indeed passed as such:
func RegCloseKey(hKey HKEY) int32 {
ret, _, _ := syscall.Syscall(regCloseKey, 1,
uintptr(hKey),
0,
0)
return int32(ret)
}
I do not quite understand why we can do that?
Almost full library for Windows synchronizations.
Hi! Using lxn/win for go-sciter. I get a panic when trying to compile simple examples for go-sciter. I'm on Windows 10, and I use GoLand IDE.
panic: The specified procedure could not be found.
goroutine 1 [running]:
github.com/lxn/win.MustGetProcAddress(0x7ff9c5670000, 0x4f34c5, 0xe, 0x7ff9c568fef0)
C:/[mypath]/src/github.com/lxn/win/win.go:57 +0x7d
github.com/lxn/win.init.1()
C:/[mypath]/src/github.com/lxn/win/comctl32.go:253 +0x191
github.com/lxn/win.init()
<autogenerated>:1 +0x5e
github.com/sciter-sdk/go-sciter.init()
<autogenerated>:1 +0x66
main.init()
<autogenerated>:1 +0x50
Hi,
It seems like https://msdn.microsoft.com/en-us/library/dd145091(v=vs.85).aspx (SetTextAlign) is missing from the gdi32 stuff.
Can I make a PR to add it ?
Best,
How do I set the spacing between Splitter?
And the spacing of their child controls?
Recently I experienced a crash in my lxn/walk based program on two different machines running Windows 10.
Exception 0xc0000005 0x0 0xc042135d20 0x7ffc2cba3f76
PC=0x7ffc2cba3f76
signal arrived during external code execution
syscall.Syscall6(0x7ffc2cba3f50, 0x4, 0xc042135d18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
/home/vagrant/go/src/runtime/syscall_windows.go:174 +0x69
github.com/lxn/win.GetMessage(0xc042135d18, 0x0, 0x0, 0xc000000001)
/home/vagrant/channels-server-win64/.go/src/github.com/lxn/win/user32.go:2202 +0x8d
github.com/lxn/walk.(*FormBase).Run(0xc0424dc000, 0xebf9f0)
/home/vagrant/channels-server-win64/.go/src/github.com/lxn/walk/form.go:368 +0xe8
main.runMenu(0x0, 0x0)
...
rax 0x0
rbx 0xc042135d18
rcx 0x7ffc2c3c1144
rdi 0x3c6000
rsi 0xc042135c98
rbp 0xc042135c48
rsp 0x200fcb0
r8 0x200fca8
r9 0xc042135c48
r10 0x0
r11 0x246
r12 0xc04223e2c0
r13 0x1
r14 0xc04223e2c8
r15 0x4
rip 0x7ffc2cba3f76
rflags 0x10246
cs 0x33
fs 0x53
gs 0x2b
Exception 0xc0000005 0x0 0xc0424bbd20 0x7ffc17a93f76
PC=0x7ffc17a93f76
signal arrived during external code execution
syscall.Syscall6(0x7ffc17a93f50, 0x4, 0xc0424bbd18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, ...)
/home/vagrant/go/src/runtime/syscall_windows.go:174 +0x69
github.com/lxn/win.GetMessage(0xc0424bbd18, 0x0, 0x0, 0xc000000001)
/home/vagrant/channels-server-win64/.go/src/github.com/lxn/win/user32.go:2202 +0x8d
github.com/lxn/walk.(*FormBase).Run(0xc04265a000, 0xea8250)
/home/vagrant/channels-server-win64/.go/src/github.com/lxn/walk/form.go:368 +0xe8
main.runMenu(0x0, 0x0)
...
rax 0x0
rbx 0xc0424bbd18
rcx 0x7ffc14711144
rdi 0x3a7000
rsi 0xc0424bbc98
rbp 0xc0424bbc48
rsp 0x1fcfcb0
r8 0x1fcfca8
r9 0xc0424bbc48
r10 0x0
r11 0x246
r12 0xc0422466e0
r13 0x1
r14 0xc0422466e8
r15 0x4
rip 0x7ffc17a93f76
rflags 0x10246
cs 0x33
fs 0x53
gs 0x2b
why it return TTM_ADDTOOL failed when I SendMessage to system
I am working on building a pdh exporter for prometheus. Currently when my application initiates it calls the win.PdhValidatePath() function approximately 3000 times. Most of the calls succeed, however, some fail inconsistently.
I've discovered that the errors that are occurring are the following:
For all pdh counters that result in the errors above, if I try to collect them individually then no errors occur. The errors only occur when large amounts of pdh counters are using the PdhValidatePath() function. I do not have the PdhValidatePath() function inside of a Go routine, so concurrency should not be the problem here.
Any ideas on how to fix this? One solution I found online that wasn't officially answered suggested using the PdhValidatePathEx function rather than PdhValidatePath.
Thought I'd ask here before going down that path in case I am doing something wrong. If you want to see my code, it can be seen here.
The InsertMenu function has not been added.
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-insertmenuw
hwnd := win.FindWindow(nil, syscall.StringToUTF16Ptr("someApp"))
// I want to kill hwnd, how?
Is it possible to disable parts of the wrapper for components that don't ship with Server Core installations of Windows, such as the opengl32 component?
See influxdata/telegraf#1763 for a reason why this could be useful.
// here: findWindow *windows.LazyProc
findWindowEx *windows.LazyProc
// here: findWindow = libuser32.NewProc("FindWindowW")
findWindowEx = libuser32.NewProc("FindWindowExW")
//here: func FindWindow(lpClassName, lpWindowName *uint16) HWND {
// add by rhinosharp team
func FindWindowEx(hWndParent HWND, hWndChild HWND, lpClassName, lpWindowName *uint16) HWND {
ret, _, _ := syscall.Syscall6(findWindowEx.Addr(), 4,
uintptr(hWndParent),
uintptr(hWndChild),
uintptr(unsafe.Pointer(lpClassName)),
intptr(unsafe.Pointer(lpWindowName)),
0,
0)
return HWND(ret)
}
sapi.h binds all the Microsoft speech APIs. It would be great to have that wrapped in this library as well.
https://github.com/lxn/win/blob/master/shobj_386.go and oleaut32_386.go probably should have:
// +build windows
#python pseudocode
hQuery = win32pdh.OpenQuery()
hCounter = win32pdh.AddCounter(hQuery, "\System\Processes")
win32pdh.CollectQueryData(hQuery)
win32pdh.CollectQueryData(hQuery)
_, val = win32pdh.GetFormattedCounterValue(hCounter, win32pdh.PDH_FMT_DOUBLE)
print val
Code above will get processes count of windows. which usually in my system is around 60
but with pdh.go
version I always get meaningless data. here is my code:
// +build windows
package main
import (
"fmt"
"github.com/kr/pretty"
"github.com/lxn/win"
)
func main() {
var handle win.PDH_HQUERY
var counterHandle win.PDH_HCOUNTER
ret := win.PdhOpenQuery(0, 0, &handle)
ret = win.PdhAddEnglishCounter(handle, "\\System\\Processes", 0, &counterHandle)
var derp win.PDH_FMT_COUNTERVALUE_DOUBLE
ret = win.PdhCollectQueryData(handle)
var lpdwType *uint32
fmt.Printf("Collect return code is %x\n", ret) // return code will be PDH_CSTATUS_INVALID_DATA
ret = win.PdhGetFormattedCounterValueDouble(counterHandle, lpdwType, &derp)
pretty.Println(derp)
ret = win.PdhCollectQueryData(handle)
fmt.Printf("Collect return code is %x\n", ret) // return code will be ERROR_SUCCESS
ret = win.PdhGetFormattedCounterValueDouble(counterHandle, lpdwType, &derp)
pretty.Println(derp)
}
after some dig on this. I found out a solution: pass in a c struct instead of go struct
here is the code:
/*
typedef struct _PDH_FMT_COUNTERVALUE_DOUBLE
{
int CStatus;
double DoubleValue;
}PDH_FMT_COUNTERVALUE_DOUBLE;
*/
import "C"
func main(){
// ...
var pValue C.PDH_FMT_COUNTERVALUE_DOUBLE
r1, r2, err = syscall.Syscall6(uintptr(PdhGetFormattedCounterValue), 4,
uintptr(phCounter),
uintptr(PDH_FMT_DOUBLE),
uintptr(lpdwType),
uintptr(unsafe.Pointer(&pValue)),
0, 0)
fmt.Println(r1, r2, err)
fmt.Println(lpdwType, pValue, pValue.DoubleValue)
pretty.Println(pValue)
}
I checked these counters they all give me correct data
// path := syscall.StringToUTF16Ptr("\\System\\Processes")
// path := syscall.StringToUTF16Ptr("\\LogicalDisk(C:)\\% Free Space")
// path := syscall.StringToUTF16Ptr("\\Memory\\% Committed Bytes In Use")
path := syscall.StringToUTF16Ptr("\\Memory\\Available MBytes")
when i run go get github.com/lxn/win
appears after a while
package github.com/lxn/win : build constraints exckude all Go files in /root/go/src/github.com/lxn/win
is this a problem?
Hi,
I like this helpful project. Could we get a Go API wrapper for the MIDI system? Ideally would integrate into the gomidi driver interface.
https://docs.microsoft.com/en-us/windows/win32/multimedia/midi-functions?redirectedfrom=MSDN
At present, the latest version of golang is 1.8.3, when I run this project will be given the error,as follows:
../../github.com/lxn/win/advapi32.go:82: too many arguments in call to syscall.Syscall
have (uintptr, number, uintptr, number, number)
want (uintptr, uintptr, uintptr, uintptr)
../../github.com/lxn/win/advapi32.go:94: too many arguments in call to syscall.Syscall6
have (uintptr, number, uintptr, uintptr, uintptr, uintptr, uintptr, number)
want (uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr)
../../github.com/lxn/win/advapi32.go:106: too many arguments in call to syscall.Syscall6
have (uintptr, number, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr)
want (uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr)
../../github.com/lxn/win/advapi32.go:121: too many arguments in call to syscall.Syscall9
have (uintptr, number, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, number)
want (uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr)
../../github.com/lxn/win/advapi32.go:132: too many arguments in call to syscall.Syscall6
have (uintptr, number, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr)
want (uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr)
../../github.com/lxn/win/comctl32.go:207: too many arguments in call to syscall.Syscall
have (uintptr, number, uintptr, uintptr, uintptr)
want (uintptr, uintptr, uintptr, uintptr)
../../github.com/lxn/win/comctl32.go:216: too many arguments in call to syscall.Syscall
have (uintptr, number, uintptr, uintptr, uintptr)
want (uintptr, uintptr, uintptr, uintptr)
../../github.com/lxn/win/comctl32.go:228: too many arguments in call to syscall.Syscall6
have (uintptr, number, uintptr, uintptr, uintptr, uintptr, uintptr, number)
want (uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr)
../../github.com/lxn/win/comctl32.go:237: too many arguments in call to syscall.Syscall
have (uintptr, number, uintptr, number, number)
want (uintptr, uintptr, uintptr, uintptr)
../../github.com/lxn/win/comctl32.go:246: too many arguments in call to syscall.Syscall
have (uintptr, number, uintptr, uintptr, uintptr)
want (uintptr, uintptr, uintptr, uintptr)
I think it should be the project is not compatible with the current version of golang, I would like to ask the author will consider continuing to maintain this project?
Source code:
package main import ( "fmt" "github.com/lxn/win" "golang.org/x/sys/windows" ) func main() { wrongName := windows.StringToUTF16Ptr("ADFADFASDFSDAFASFD") handle := win.GetModuleHandle(wrongName) if handle == 0 { fmt.Println(win.GetLastError()) // This always returns 0. See https://github.com/golang/go/issues/41220 } }
Expected result:
Error code describing 'module not found' (ERROR_MOD_NOT_FOUND, 126)
Actual result:
0
According to golang/go#41220 , windows.GetLastError always returns nil. As the same reason, win.GetLastError always returns 0.
As wrapper provided by this package doesn't handle err return value from syscall.Syscall, the client doesn't know why the function call was failed.
Hi,
Thanks for the great library.
I happen to find that GetStockObject in gdi32.go (line 1319) calls getDeviceCaps instead of getStockObject.
I'm probably doing something stupid. But I'm trying to replicate this
Windows tutorial.
But when I run this code RegisterClassEx fails returning 0. Not sure if this helps but it never calls my WndProc function. (I place a Printf on the first line)
package main
import (
"fmt"
"github.com/lxn/win"
"golang.org/x/sys/windows"
)
func main() {
className := "SomeFunkyNameHere"
wc := win.WNDCLASSEX{}
hInst := win.GetModuleHandle(nil)
if hInst == 0 {
panic("GetModuleHandle")
}
wc.LpfnWndProc = windows.NewCallback(WndProc)
wc.HInstance = hInst
wc.LpszClassName = windows.StringToUTF16Ptr(className)
if atom := win.RegisterClassEx(&wc); atom == 0 {
panic("RegisterClassEx")
}
hwnd := win.CreateWindowEx(
0,
wc.LpszClassName,
windows.StringToUTF16Ptr("Learn to program"),
win.WS_OVERLAPPEDWINDOW,
win.CW_USEDEFAULT, win.CW_USEDEFAULT, win.CW_USEDEFAULT, win.CW_USEDEFAULT,
0,
0,
hInst,
nil,
)
if hwnd == 0 {
panic(win.GetLastError())
}
win.ShowWindow(hwnd, win.SW_SHOW)
msg := win.MSG{}
for win.GetMessage(&msg, 0, 0, 0) != 0 {
win.TranslateMessage(&msg)
win.DispatchMessage(&msg)
}
}
func WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) uintptr {
switch msg {
case win.WM_DESTROY:
win.PostQuitMessage(0)
case win.WM_PAINT:
ps := win.PAINTSTRUCT{}
hdc := win.BeginPaint(hwnd, &ps)
r := ps.RcPaint
hrgn := win.CreateRectRgn(r.Left, r.Top, r.Right, r.Bottom)
win.FillRgn(hdc, hrgn, win.COLOR_WINDOW+1)
win.EndPaint(hwnd, &ps)
}
return win.DefWindowProc(hwnd, msg, wParam, lParam)
}
D:\SourceCode\GoProj\src\goWin>go build -ldflags="-H windowsgui"
# github.com/lxn/walk
..\github.com\lxn\walk\bitmap.go:58: undefined: win.GdiFlush
..\github.com\lxn\walk\bitmap.go:194: undefined: win.GdiFlush
..\github.com\lxn\walk\bitmap.go:208: undefined: win.SetDIBits
..\github.com\lxn\walk\bitmap.go:247: undefined: win.AlphaBlend
..\github.com\lxn\walk\bitmap.go:258: undefined: win.BLENDFUNCTION
..\github.com\lxn\walk\brush.go:252: undefined: win.CreatePatternBrush
..\github.com\lxn\walk\brush.go:349: undefined: win.TRIVERTEX
..\github.com\lxn\walk\brush.go:360: undefined: win.GRADIENT_TRIANGLE
..\github.com\lxn\walk\brush.go:369: undefined: win.GradientFill
..\github.com\lxn\walk\brush.go:369: undefined: win.GRADIENT_FILL_TRIANGLE
..\github.com\lxn\walk\brush.go:369: too many errors
jun@jun-IdeaCentre-B545:~/codes/golang/src/goWin$ export GOOS="windows"
jun@jun-IdeaCentre-B545:~/codes/golang/src/goWin$ go build
var (
moduser32 = syscall.NewLazyDLL("user32.dll")
procWaitForInputIdle = moduser32.NewProc("WaitForInputIdle")
proGetWindowModuleFileName = moduser32.NewProc("GetWindowModuleFileNameW")
)
// WaitForInputIdle waits until the specified process has finished processing its initial input and is waiting for user input with no input pending, or until the time-out interval has elapsed.
func WaitForInputIdle(hwnd win.HWND, timeoutMsec int) {
_, _, _ = procWaitForInputIdle.Call(
uintptr(hwnd),
uintptr(timeoutMsec))
}
// GetWindowModuleFileName retrieves the full path and file name of the module associated with the specified window handle.
func GetWindowModuleFileName(hwnd win.HWND) (moduleFileName string) {
bufLen := 1000
buf := make([]uint16, bufLen+1)
textLen, _, _ := proGetWindowModuleFileName.Call(
uintptr(hwnd),
uintptr(unsafe.Pointer(&buf[0])),
uintptr(bufLen))
if textLen > 0 { // processes of other owner do not reveal their info (unless we have elevated privilege)
moduleFileName = syscall.UTF16ToString(buf)
}
return
}
I am preparing to write a dynamic link library file,it contains a winform. The code such as:
`
func init() {
title := "Spark"
hInst := win.GetModuleHandle(nil)
if hInst == 0 {
panic(fmt.Sprintf("GetModuleHandle: %v", win.GetLastError()))
}
wc := win.WNDCLASSEX{}
wc.CbSize = uint32(unsafe.Sizeof(wc))
wc.LpfnWndProc = syscall.NewCallback(wndProc)
wc.HInstance = hInst
wc.HbrBackground = win.COLOR_WINDOW + 1
wc.LpszClassName = syscall.StringToUTF16Ptr(title)
wc.Style = win.CS_HREDRAW | win.CS_VREDRAW
if atom := win.RegisterClassEx(&wc); atom == 0 {
panic(fmt.Sprintf("RegisterClassEx: %v", win.GetLastError()))
}
hwnd = win.CreateWindowEx(
win.WS_EX_TOOLWINDOW,
syscall.StringToUTF16Ptr(title),
syscall.StringToUTF16Ptr(title),
win.WS_VISIBLE | win.WS_POPUP,
0,
0,
0,
0,
0,
0,
hInst,
nil,
)
if hwnd == 0 {
panic(fmt.Sprintf("CreateWindowEx: %v", win.GetLastError()))
}
win.ShowWindow(hwnd, win.SW_HIDE)
win.UpdateWindow(hwnd)
var msg win.MSG
for {
if m := win.GetMessage(&msg, 0, 0, 0); m != 0 {
win.TranslateMessage(&msg)
win.DispatchMessage(&msg)
}
}
}
func wndProc(hwnd win.HWND, msg uint32, wparam, lparam uintptr) (result uintptr) {
switch msg {
case win.WM_DESTROY:
win.PostQuitMessage(0)
case win.WM_DEVICECHANGE:
OnDeviceChange(hwnd, msg, wparam, lparam)
case WM_USB_EVENT: // Customer Message
OnUsbEvent(hwnd, msg, wparam, lparam)
default:
return win.DefWindowProc(hwnd, msg, wparam, lparam)
}
return 0
}
//export DoPausePlay
func DoPausePlay() *C.char {
doPause()
return C.CString("0")
}
`
But when another program calls, it hangs at this code:
for { if m := win.GetMessage(&msg, 0, 0, 0); m != 0 { win.TranslateMessage(&msg) win.DispatchMessage(&msg) } }
Other methods, such as DoPausePlay(), cannot be called. How can I change this?
Seems you are missing RegCreateKeyEx needed to create keys
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724844(v=vs.85).aspx
This package call runtime.LockOSThread() to ensure all calls happen on the same os thread. Can I call runtime.UnlockOSThread() in my program after the initialization of win package?
Hi there Alexander,
I'm trying to simulate keystrokes but unfortunately win
lacks the INPUT struct required.
Is there any "easy" way to port it from the C headers to Go?
There's this other package which uses cgo to deal with it but in the project I'm working on I can't use cgo 👎...
https://github.com/AllenDang/w32/blob/e6b20c288197ddc4eac94ede4f67965a604a7bf4/user32.go#L922
Thanks!
While using GetRawInputData
, I've stumbled upon an issue where the value of UsButtonFlags
is apparently placed inside UsButtonData
.
After looking at the code, I noticed the Pad_cgo_0
field and got to read a bit about the beautiful world of field alignment in C. I still don't know much about it but here's what worked in my case:
type MYRAWMOUSE struct {
UsFlags uint16
Pad_cgo_0 [2]byte
UsButtonFlags uint16
UsButtonData uint16
UlRawButtons uint32
LLastX int32
LLastY int32
UlExtraInformation uint32
}
By just moving that padding above UsButtonFlags
it seems to work just fine, even for the info in LLastX
and LLastY
.
I was wondering about creating a PR but then noticed this might work differently depending on the target architecture. Can you please give me your thoughts on this? Is it safe to move that padding field, or will I have to look out for its position depending on my compiler target?
EDIT:
I did some more investigation on this and here's an interesting read on the subject: http://www.catb.org/esr/structure-packing/
I've also checked the paddings using this code:
/*
#include <windows.h>
*/
import "C"
import (
"github.com/davecgh/go-spew/spew"
)
func main() {
var test C.RAWMOUSE
spew.Dump(test)
}
Built for both 32bit and 64bit Windows:
set GOARCH=386 && go build -o ./build/Debug/test_offset_386.exe ./cmd/testoffset
set GOARCH=amd64 && go build -o ./build/Debug/test_offset_amd64.exe ./cmd/testoffset
Here's the output for 32bit:
$ ./build/Debug/test_offset_386.exe
(main._Ctype_struct_tagRAWMOUSE) {
usFlags: (main._Ctype_ushort) 0,
_: ([2]uint8) (len=2 cap=2) {
00000000 00 00 |..|
},
anon0: ([4]uint8) (len=4 cap=4) {
00000000 00 00 00 00 |....|
},
ulRawButtons: (main._Ctype_ulong) 0,
lLastX: (main._Ctype_long) 0,
lLastY: (main._Ctype_long) 0,
ulExtraInformation: (main._Ctype_ulong) 0
}
Here's the output for 64bit:
$ ./build/Debug/test_offset_amd64.exe
(main._Ctype_struct_tagRAWMOUSE) {
usFlags: (main._Ctype_ushort) 0,
_: ([2]uint8) (len=2 cap=2) {
00000000 00 00 |..|
},
anon0: ([4]uint8) (len=4 cap=4) {
00000000 00 00 00 00 |....|
},
ulRawButtons: (main._Ctype_ulong) 0,
lLastX: (main._Ctype_long) 0,
lLastY: (main._Ctype_long) 0,
ulExtraInformation: (main._Ctype_ulong) 0
}
You might need to check the RAWMOUSE struct and the Windows data type docs to make some sense of the above output.
The output is pretty much the same and the padding is set above the usButtonFlags
+usButtonData
inner struct. Maybe I need an actual 32bit machine for it to be different (not sure).
I wonder if the current Golang structure in this repo is prepared for 32bit builds since the commit was made in July 2012, or if this has been a bug all along 🤔
Hello i have code written in python, someone could help me write it in golang? I'm fresh in go, thank you.
import win32gui, win32ui
info = win32gui.GetCursorInfo()
hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
hbmp = win32ui.CreateBitmap()
hbmp.CreateCompatibleBitmap(hdc, 30, 30)
hdc = hdc.CreateCompatibleDC()
hdc.SelectObject(hbmp)
hdc.DrawIcon((0, 0), info[1])
hbmp.SaveBitmapFile(hdc, 'icon.bmp')
win32gui.DeleteObject(hbmp.GetHandle())
hdc.DeleteDC()
According to Using PDH APIs correctly in a localized language, in order to support counter names in different localization languages, PdhLookupPerfNameByIndex
needs to be used to look up the localized names for the counter paths. Unfortunately pdh.go
doesn't have that yet.
If I get to it, I can probably work on it myself, but I'm creating the issue now if somebody else wants to work on it as well.
I want to get.
Line 432 in 24c5960
I have encountered a very strange problem with the performance counter in the French operating system. When I use the PdhValidatePath
method to check if the key is reasonable, the system reports an error, but the performance data returns normally.
I note the same key on English is
\Network Adapter(*)\Packets Sent/sec
and the same key on French windows is
\Interface réseau(*)\Paquets/s
Performance monitoring data can be obtained using both keys, but PdhValidatePath reports an error.
Errcode is that
0xC0000BC0 (PDH_CSTATUS_BAD_COUNTERNAME) | Unable to parse the counter path. Check the format and syntax of the specified path.
I checked the msdn documentation and found that they did not use PdhValidatePath in their official sample.
https://docs.microsoft.com/en-us/windows/win32/perfctrs/browsing-performance-counters
I hope that you can help me to give pointers on the best practices of pdh in non-English environments.
Can't find that function
https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms647985%28v=vs.85%29.aspx
We have noticed that due to WMI calls used for monitoring as part of telegraf engine, WMI calls to extract performance counters are causing leak in the process. When looking at telegraf project code, I noticed that it is using pdh from this project, and not issuing WMI calls for performance counters directly.
More issues can be found @ influxdata/telegraf#6807
I didn't find direct calls to CoInitializeEx which tells me that PDH is someone calling that internally? Was this problem ever reported to you?
I'm running Win10 pro, all up to date
I'm using another package: https://github.com/sciter-sdk/go-sciter which has this as a dependency, I'm sorry I didn't capture the panic but it was pointing at this line here and failing during init:
https://github.com/lxn/win/blob/master/comctl32.go#L252
which I guess was not getting the address it wanted.
I checked out #1e0d6a9229bfb5986ba8b54e2ffc827233faa3e4 and the issue was resolved
Apologies this is not more thorough, if its not obvious shout back and Ill try recreate and grab any extra info you need
I'm having trouble getting win.SendInput
to behave.
package main
import (
"fmt"
"unsafe"
"github.com/lxn/win"
)
func main() {
println("Moving mouse")
input := []win.MOUSE_INPUT{
{
Type: win.INPUT_MOUSE,
Mi: win.MOUSEINPUT{
Dx: int32(200),
Dy: int32(200),
DwFlags: win.MOUSEEVENTF_MOVE,
},
},
}
fmt.Printf("SendInput(%d, %#v, %d)\n", len(input), input, unsafe.Sizeof(input[0]))
i := win.SendInput(uint32(len(input)), unsafe.Pointer(&input), int32(unsafe.Sizeof(input[0])))
fmt.Printf(" => %d (lastError: %d)\n", i, win.GetLastError())
}
When run, this outputs:
Moving mouse
SendInput(1, []win.MOUSE_INPUT{win.MOUSE_INPUT{Type:0x0, Mi:win.MOUSEINPUT{Dx:200, Dy:200, MouseData:0x0, DwFlags:0x8001, Time:0x0, DwExtraInfo:0x0}}}, 40)
=> 1 (lastError: 0)
But the mouse doesn't move.
I've also tried sending win.KBD_INPUT
events, and I am also unsuccessful there.
SendInput
is returning 1
which indicates it successfully did the event, but my mouse doesn't seem to move. Ideas?
Windows 10 Version 1607 Build 14393.1715
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.