Find the Executing function's name
Often I want to write the SAME code that will display the name of the currently executing method or function. That way I can just copy/paste the same code into multiple methods.
For example, in sub Form1_Load I could put this line:
System.Diagnostics.Debug.WriteLine("in Form1_Load")
In Button1_Click I’d have to out a different line:
System.Diagnostics.Debug.WriteLine("in Button1_Click")
In FoxPro, I can use the PROGRAM() function. How do you do it in .Net? Like this:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
System.Diagnostics.Debug.WriteLine("subroutine name = " + (New StackTrace).GetFrames(0).GetMethod.Name)
End Sub
The output is:
subroutine name = Form1_Load
I use something similar to this code in my Unit Tests (Use Visual Studio Test framework to create tests for your code) so the test code can detect what the name of the test is.
In fact, you can even find out the calling assembly within a program, and do something different depending on the caller!
In fact, run this code:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim st = New StackTrace
Dim Methods = st.GetFrames
For Each meth In Methods
System.Diagnostics.Debug.WriteLine(meth.GetMethod.DeclaringType.FullName + ":" + meth.GetMethod.Name)
Next
End Sub
If you set a breakpoint in this code, you’ll see that the output shows the method names:
This is the actual debugger output:
WindowsApplication1.exe!WindowsApplication1.Form1:Form1_Load
mscorlib.dll!System.EventHandler:Invoke
System.Windows.Forms.dll!System.Windows.Forms.Form:OnLoad
System.Windows.Forms.dll!System.Windows.Forms.Form:OnCreateControl
System.Windows.Forms.dll!System.Windows.Forms.Control:CreateControl
System.Windows.Forms.dll!System.Windows.Forms.Control:CreateControl
System.Windows.Forms.dll!System.Windows.Forms.Control:WmShowWindow
System.Windows.Forms.dll!System.Windows.Forms.Control:WndProc
System.Windows.Forms.dll!System.Windows.Forms.ScrollableControl:WndProc
System.Windows.Forms.dll!System.Windows.Forms.ContainerControl:WndProc
System.Windows.Forms.dll!System.Windows.Forms.Form:WmShowWindow
System.Windows.Forms.dll!System.Windows.Forms.Form:WndProc
System.Windows.Forms.dll!System.Windows.Forms.Control+ControlNativeWindow:OnMessage
System.Windows.Forms.dll!System.Windows.Forms.Control+ControlNativeWindow:WndProc
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow:DebuggableCallback
System.Windows.Forms.dll!System.Windows.Forms.SafeNativeMethods:ShowWindow
System.Windows.Forms.dll!System.Windows.Forms.Control:SetVisibleCore
System.Windows.Forms.dll!System.Windows.Forms.Form:SetVisibleCore
System.Windows.Forms.dll!System.Windows.Forms.Control:set_Visible
System.Windows.Forms.dll!System.Windows.Forms.Application+ThreadContext:RunMessageLoopInner
System.Windows.Forms.dll!System.Windows.Forms.Application+ThreadContext:RunMessageLoop
System.Windows.Forms.dll!System.Windows.Forms.Application:Run
Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase:OnRun
Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase:DoApplicationModel
Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase:Run
WindowsApplication1.exe!WindowsApplication1.My.MyApplication:Main
mscorlib.dll!System.AppDomain:_nExecuteAssembly
mscorlib.dll!System.AppDomain:ExecuteAssembly
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc:RunUsersAssembly
mscorlib.dll!System.Threading.ThreadHelper:ThreadStart_Context
mscorlib.dll!System.Threading.ExecutionContext:Run
mscorlib.dll!System.Threading.ThreadHelper:ThreadStart
This is the actual stack from the Call Stack window (turn off Tools->Options->Debugging->Just My Code):
> WindowsApplication1.exe!WindowsApplication1.Form1.Form1_Load(Object sender = {WindowsApplication1.Form1}, System.EventArgs e = {System.EventArgs}) Line 9 Basic
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.Form.OnLoad(System.EventArgs e) + 0x28b bytes
System.Windows.Forms.dll!System.Windows.Forms.Form.OnCreateControl() + 0x52 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.CreateControl(bool fIgnoreVisible) + 0x172 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.CreateControl() + 0x1b bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.WmShowWindow(ref System.Windows.Forms.Message m) + 0x8e bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x6ed bytes
System.Windows.Forms.dll!System.Windows.Forms.ScrollableControl.WndProc(ref System.Windows.Forms.Message m) + 0x45 bytes
System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.WndProc(ref System.Windows.Forms.Message m) + 0x11 bytes
System.Windows.Forms.dll!System.Windows.Forms.Form.WmShowWindow(ref System.Windows.Forms.Message m) + 0x3e bytes
System.Windows.Forms.dll!System.Windows.Forms.Form.WndProc(ref System.Windows.Forms.Message m) + 0x230 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) + 0xd bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x36 bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg = 24, System.IntPtr wparam, System.IntPtr lparam) + 0x57 bytes
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.Control.SetVisibleCore(bool value = true) + 0x12f bytes
System.Windows.Forms.dll!System.Windows.Forms.Form.SetVisibleCore(bool value = true) + 0xdc bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.Visible.set(bool value) + 0xe bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = -1, System.Windows.Forms.ApplicationContext context = {Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.WinFormsAppContext}) + 0xee bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x53 bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.ApplicationContext context) + 0x15 bytes
Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun() + 0xc0 bytes
Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel() + 0xe4 bytes
Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(string[] commandLine) + 0x62 bytes
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x39 bytes
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x2b bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x3b bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x81 bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x40 bytes
You can get similar results from Foxpro. Program(-1) will return the # of stack frames. SYS(16) returns the executing program, and Program(i) returns the name of the procedure at the stack level i.
res=func1()
?res
PROCEDURE func1
?PROGRAM()
RETURN func2()
PROCEDURE func2
?PROGRAM()
?PROGRAM(-1)
FOR i = 1 TO PROGRAM(-1)
?SYS(16)+ PROGRAM(i)
ENDFOR
RETURN 4
See also How to log application API calls using import module addresses
Comments
Anonymous
February 26, 2008
PingBack from http://www.biosensorab.org/2008/02/27/find-the-executing-functions-name/Anonymous
February 26, 2008
PingBack from http://msdnrss.thecoderblogs.com/2008/02/27/find-the-executing-functions-name/Anonymous
March 01, 2008
Might be a silly question, but what does the RETURN 4 do in the above code? Should that be RETURN i? Also, I have to admit, I like the VFP implementation much better!Anonymous
September 23, 2008
I have a collection of almost 30,000 pictures and videos. When I add new pictures to the collection,Anonymous
December 04, 2008
PingBack from http://www.baby-parenting.com/baby/babyname/function.include-onceAnonymous
March 14, 2010
Thank you for this -- I've been looking for this for years, but never put the right words together on search. I only succeeded this time because I was so frustrated I threw a bunch of words in there I thought would never work. I kept throwing 'reflection' in there. I'd offer to have your baby, but I'm too old. Sorry.