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