1

The question says it all really. What is the difference? I am wanting to get the path the application has been installed to and so far have seen no discrepancy between the two.

Only difference I see in the MSDN pages is that Application.StartupPath mentions ClickOnce applications (I am not running a ClickOnce application - can't stand them!)

There are probably other ways to get it too, looking through Intellisense. Is it just a case of "more than one way to skin a cat" or are there merits and drawbacks to each method?

bmgh1985
  • 779
  • 1
  • 14
  • 38
  • 1
    The My namespace was added in .NET 2.0/VS2005 to help VB.NET programmers fall in the pit of success. The difference between the two is not subtle, App.SP asks the operating system about the EXE that got the process started. That is not yours in plenty of cases, like COM servers, Office add-ins, ClickOnce. – Hans Passant Feb 18 '15 at 18:08

1 Answers1

2

The types contained within the My namespace are contained within Microsoft.VisualBasic.dll - they aren't commonly (or ever!) used across other .NET languages. Those within the Application namespace are.

Under the hood, Application.StartupPath does this:

Public ReadOnly Shared Property StartupPath As String
    Get
        If (Application.startupPath Is Nothing) Then
            Dim stringBuilder As System.Text.StringBuilder = New System.Text.StringBuilder(260)
            UnsafeNativeMethods.GetModuleFileName(NativeMethods.NullHandleRef, stringBuilder, stringBuilder.Capacity)
            Application.startupPath = Path.GetDirectoryName(stringBuilder.ToString())
        End If
        (New FileIOPermission(FileIOPermissionAccess.PathDiscovery, Application.startupPath)).Demand()
        Return Application.startupPath
    End Get
End Property

Whilst My.Application.Info.DirectoryPath does this:

Public ReadOnly Property DirectoryPath As String
    Get
        Return Path.GetDirectoryName(Me.m_Assembly.Location)
    End Get
End Property

which calls this:

Public Overrides ReadOnly Property Location As String
    <SecuritySafeCritical>
    Get
        Dim str As String = Nothing
        RuntimeAssembly.GetLocation(Me.GetNativeHandle(), JitHelpers.GetStringHandleOnStack(str))
         If (str IsNot Nothing) Then
            (New FileIOPermission(FileIOPermissionAccess.PathDiscovery, str)).Demand()
        End If
        Return str
    End Get
End Property

GetModuleFileName used in StartupPath is a call to the native Win32 API, and GetLocation used in DirectoryPath involves a "native" call to the .NET CLR Runtime, so you'd need to dig even deeper to find out where it gets its information from.

TL;DR

Use Application.StartupPath as a preference and to help develop good habits, since it doesn't rely on the Microsoft.VisualBasic additions to .NET, and will make the transition to other languages easier should you ever choose to use them.

Community
  • 1
  • 1
James Thorpe
  • 31,411
  • 5
  • 72
  • 93
  • Nicely explained, thanks. Quick sidebar- if I am using `My.[Anything]` already in the application (I am in this instance), I assume that too would require those same additions, meaning in this instance it makes no difference. – bmgh1985 Feb 18 '15 at 17:44
  • 1
    @bmgh1985 No - there's no downside once the assembly is loaded, you may as well use as much or as little of it as you like. In the same fashion, personally I would also avoid the likes of `CInt` and use `Convert.ToInt32` etc instead, more from the point of view of getting used to using the newer .NET constructs where possible, rather than hangovers from pre .NET VB. – James Thorpe Feb 18 '15 at 19:08