Thanks for your response. It seems logic to do what you say (aka lets make DllMain in C if Go does not let us control it)
So I did a main.c: ``` #include <windows.h> extern void RunMe(); BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: RunMe(); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } ``` Then a main.go that use main.c ``` package main //#include "main.c" import "C" import ( "syscall" "golang.org/x/sys/windows" ) //export RunMe func RunMe() { windows.MessageBox(windows.HWND(0), syscall.StringToUTF16Ptr("RunMe"), syscall.StringToUTF16Ptr("RunMe"), windows.MB_OK) } func main() {} ``` Then I compile by cd into the directory containing the main.go and main.c and running: ``` GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc go build -a -o ~/Desktop/dropamd64.dll -buildmode=c-shared ``` However I get an error from x86_64-w64-mingw32-gcc that DllMain is defined multiple time. I am not sure the issue is from DllMain though, because If I change DllMain to TestRudeus I get also the error TestRudeus is defined multiple time... Le dimanche 10 novembre 2024 à 17:15:52 UTC+1, Jason E. Aten a écrit : > I'll add that the one way I've found to address the "Go runtime cannot > shut itself down" problem > is to compile to wasm. WebAssembly hosts > like the browser -- and running the wasm on a background web worker -- > provide very nice ways of killing > a web worker thread. I believe (but have not tried it), that wasm runtimes > like wazero > and wasmtime also provide means to pause and kill threads. > https://github.com/tetratelabs/wazero/issues/421 may be relevant. > > Runtimes like wazero compile the wasm to native code. These > days they can, very impressively, execute at native or near native speed. > Moreover, if you use tinygo (llvm under the covers) you can actually > get wasm code to go faster (sometimes _much_ faster) than the native go > compiler, even though you are going through a wasm layer. > > Since it would be vastly more portable than writing a DLL, you might > explore the wasm approach if the wasm runtimes provide for what you > are trying to do on Windows (which they well may not, but its worth > exploring). > > On Sunday, November 10, 2024 at 3:14:52 PM UTC Jason E. Aten wrote: > >> Use CGO in your .go file, and then there, or in an adjacent C file, >> actually do write a DllMain function; >> https://learn.microsoft.com/en-us/windows/win32/dlls/dllmain >> >> When fdwReason == DLL_PROCESS_ATTACH, then you know this is the first >> load of the DLL >> into this process. I think your subject line acknowledges that you known >> this. >> >> Note that the APIENTRY annotation on the DllMain is required, in order to >> get the >> right calling convention. >> >> Be aware that the go runtime has a major problem when used inside a DLL: >> it >> provides no way to shut itself down. This means that you can never unload >> a DLL that you have loaded, even though Windows processes routinely do >> unload DLLs. >> >> On XP or later you can use GetModuleHandleEx with the >> GET_MODULE_HANDLE_EX_FLAG_PIN flag to prevent unloading of the DLL. >> This means that your process won't crash on unload, but also that the >> DLL will not actually be unloaded. In order to update the DLL, you must >> kill the >> process. >> >> On Sunday, November 10, 2024 at 1:54:16 PM UTC rudeus greyrat wrote: >> >>> I am trying to write DLL in go. I want it to execute some stuff when the >>> DLL is attached to a process. >>> >>> I thought init() will be the equivalent of onattach but It seems I am >>> wrong. >>> >>> I created this as a proof of concept: >>> ``` >>> package main >>> >>> import "C" >>> import ( >>> "syscall" >>> >>> "golang.org/x/sys/windows" >>> ) >>> >>> //export RunMe >>> func RunMe() { >>> >>> windows.MessageBox(windows.HWND(0), >>> syscall.StringToUTF16Ptr("RunMe"), syscall.StringToUTF16Ptr("RunMe"), >>> windows.MB_OK) >>> } >>> >>> func init() { >>> windows.MessageBox(windows.HWND(0), syscall.StringToUTF16Ptr("DLL >>> Loaded"), syscall.StringToUTF16Ptr("DLL Load"), windows.MB_OK) >>> } >>> >>> func main() {} >>> ``` >>> >>> I compile on Linux with: >>> ``` >>> GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc go >>> build -a -o ~/Desktop/dropamd64.dll -buildmode=c-shared cmd/dll64bit/main.go >>> ``` >>> >>> I transfer on my Windows machine then here is the amazing result: >>> *rundll32.exe Z:\dropamd64.dll -----> Nothing happens* >>> *rundll32.exe Z:\dropamd64.dll,RunMe ------> Runs RunMe() and init() >>> and I get 2 MessageBox* >>> >>> My question is, how to get a DLL that runs stuff only when process is >>> attached ? >>> >>> There not a lot of official Golang doc about DLL (some few people write >>> here and there some tutorials that are not always right and correct ...) So >>> if you have some trustworthy doc please share. >>> >>> >>> >>> >>> -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/6b193e5a-7ae0-4c6d-8362-bfef9a2484f3n%40googlegroups.com.