The My Namespace
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The reference material consulted while preparing these pages is listed in the section bibliography. |
This page is written against Visual Basic 17.13 on .NET 10 (SDK 10.0.402) and was checked on 2026-10-19. The examples that start
with Option Strict On and print results are complete console programs that were built with warnings treated as errors and run in
the .NET 10 SDK container (Linux, arm64). The examples that need Windows Forms were built with
EnableWindowsTargeting on the same container and were not run; they are labelled "built, not run". Where an example is meant
to fail, the compiler messages shown are the ones the SDK printed. Every console example here has the root namespace ShelfApp,
because the CLR and compiler messages include it.
My is the Visual Basic feature that most often surprises people who come from books, blog posts and Stack Overflow answers written for
.NET Framework: code such as My.Computer.Name or My.Settings.PageSize compiled in every project there, and on .NET it compiles
only in some project types. This page explains what My is, how the project decides what it contains, what every part of it does, what
to use instead where it is missing, and how to add your own members to it. The runtime library behind My, with the functions that
exist in every project, is on The Visual Basic Runtime Library;
the project-level setting MyType also appears in Visual Basic and .NET.
What My is
My is a namespace that sits in your project’s root namespace, together with a small amount of code that the compiler generates for you.
It was introduced with Visual Basic 2005 as a set of shortcuts ("speed-dial for the framework") to the objects an application usually needs: the
application and its information, the computer and its devices, the current user, application settings, embedded resources and the forms of a
Windows Forms program. Nothing in My is magic and nothing in it cannot be written by hand: each shortcut is a property that returns an object from
the Microsoft.VisualBasic runtime or from the BCL.
| Member | What it gives you | Defined by |
|---|---|---|
|
information about the assembly ( |
generated class |
|
the machine and its devices: |
generated class |
|
the current user’s name and roles |
|
|
typed application and user settings |
a class that the Settings designer generates in your project (it is not generated by the compiler) |
|
typed access to the project’s embedded resources |
a module that the Resources designer generates in your project |
|
one default instance of each form of the project |
generated class |
|
default instances of generated web-service proxies |
generated class |
|
the ASP.NET request, response and trace log |
ASP.NET Web Forms project type on .NET Framework; not available on .NET |
Source: Development with My
Two facts explain nearly everything else on this page. First, the compiler decides what My contains from the project’s MyType
property, so the same My.Computer.Name can compile in one project and fail in the next. Second, the types behind My.Computer, My.User and
My.Application are not in the part of the runtime that every .NET program has; on .NET they are in Microsoft.VisualBasic.Forms,
which ships with the Windows Desktop runtime. The next two sections show both facts with real output.
MyType decides what exists
The compiler receives the project property as the conditional-compilation constant _MyType (the SDK passes MyType into the
constants list, which is why you can also test it with #If _MyType = "Console" Then; see
Conditional Compilation and Directives). The compiler then
adds a hidden source file to the compilation, in which Namespace My contains the pieces that the value asks for. The SDK’s Visual Basic targets
file sets MyType to Empty for every target that is not .NET Framework, and its own comment says that project templates are responsible for choosing a
non-empty value when it makes sense. The SDK templates for Windows Forms and WPF projects do so; the console template does not.
The results of building a class library for net10.0-windows (with UseWindowsForms on) once for each value, and then inspecting the generated
types with reflection, are:
MyType |
MyApplication inherits |
Generated members of My |
Result on a plain net10.0 project |
|---|---|---|---|
|
not generated |
nothing: |
compiles |
|
|
|
does not compile: BC30002, the types are missing |
|
|
|
does not compile: BC30002 |
|
|
the same, plus |
does not compile: BC30002 |
|
|
the same as |
does not compile: BC30002 |
|
not applicable |
ASP.NET objects |
does not compile on any .NET target: BC30002 for |
|
not generated |
only |
compiles |
(The base classes in the second column were read from the compiled assembly with MetadataLoadContext; the "does not compile" results were
produced by building the same project with -p:MyType=... on net10.0.) The practical rules are:
-
A console application or a class library keeps
MyType=Empty.My.Computer,My.Application,My.User,My.Settings,My.ResourcesandMy.Formsdo not exist there, and writing them gives BC30456. The program below uses every one of them:
Option Strict On
Module Program
Sub Main()
Console.WriteLine(My.Application.Info.Version.ToString())
Console.WriteLine(My.Computer.Name)
Console.WriteLine(My.User.Name)
Console.WriteLine(My.Settings.ToString())
Console.WriteLine(My.Resources.ToString())
Console.WriteLine(My.Forms.ToString())
Console.WriteLine(My.WebServices.ToString())
Console.WriteLine(My.Request.ToString())
Console.WriteLine(My.Response.ToString())
Console.WriteLine(My.Log.ToString())
End Sub
End Module
The compiler prints (root namespace ShelfApp, with warnings as errors off so only the My problems appear):
Program.vb(5,27): error BC30456: 'Application' is not a member of 'ShelfApp.My'.
Program.vb(6,27): error BC30456: 'Computer' is not a member of 'ShelfApp.My'.
Program.vb(7,27): error BC30456: 'User' is not a member of 'ShelfApp.My'.
Program.vb(8,27): error BC30456: 'Settings' is not a member of 'ShelfApp.My'.
Program.vb(9,27): error BC30456: 'Resources' is not a member of 'ShelfApp.My'.
Program.vb(10,27): error BC30456: 'Forms' is not a member of 'ShelfApp.My'.
Program.vb(11,27): error BC30456: 'WebServices' is not a member of 'ShelfApp.My'.
Program.vb(12,27): error BC30456: 'Request' is not a member of 'ShelfApp.My'.
Program.vb(13,27): error BC30456: 'Response' is not a member of 'ShelfApp.My'.
Program.vb(14,27): error BC30456: 'Log' is not a member of 'ShelfApp.My'.
Source: How My depends on project type
-
Setting
MyTypetoConsolein a plainnet10.0project does not give a console project itsMy, because the generated code names types fromMicrosoft.VisualBasic.Forms. A program with onlyConsole.WriteLine(My.Computer.Name)and<MyType>Console</MyType>fails with:
vbc : error BC30002: Type 'Global.Microsoft.VisualBasic.ApplicationServices.ConsoleApplicationBase' is not defined.
vbc : error BC30002: Type 'Global.Microsoft.VisualBasic.ApplicationServices.User' is not defined.
vbc : error BC30002: Type 'Global.Microsoft.VisualBasic.Devices.Computer' is not defined.
-
Webis a leftover of ASP.NET Web Forms on .NET Framework. Building withMyTypeset toWebonnet10.0-windowsprinted:
vbc : error BC30002: Type 'Global.Microsoft.VisualBasic.ApplicationServices.WebUser' is not defined.
vbc : error BC30002: Type 'Global.Microsoft.VisualBasic.Logging.AspLog' is not defined.
vbc : error BC30002: Type 'Global.System.Web.HttpRequest' is not defined.
-
Customturns the generated parts off while keeping theThreadSafeObjectProviderhelper. On .NET Framework it was the setting for a project that wanted to supply its ownMy; todayEmptydoes the same. -
A Windows Forms or WPF project on
net10.0-windowsmust setMyTypeitself when it wantsMy. The SDK’swinformstemplate writes its ownSub Mainand does not setMyType, so in a freshly generated projectMy.Computeris empty until you add<MyType>WindowsForms</MyType>(orWindowsFormsWithCustomSubMainwhen you keep your ownSub Main).
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<RootNamespace>ShelfDesktop</RootNamespace>
<MyType>WindowsForms</MyType>
<OptionStrict>On</OptionStrict>
</PropertyGroup>
</Project>
Source: Development with My
Where the My types live on .NET
The generated My.Computer, My.Application and My.User are thin classes over runtime types. On .NET Framework they were all in Microsoft.VisualBasic.dll. On .NET they are
split. The part that does not need a UI toolkit is in Microsoft.VisualBasic.Core, which every project references: its exported types
are in only three namespaces, Microsoft.VisualBasic, Microsoft.VisualBasic.CompilerServices and Microsoft.VisualBasic.FileIO. The rest of the
My machinery is in Microsoft.VisualBasic.Forms, part of the Windows Desktop targeting pack. Loading that assembly’s public surface with
MetadataLoadContext shows what is Windows-only:
Microsoft.VisualBasic
AudioPlayMode
Microsoft.VisualBasic.ApplicationServices
ApplicationBase, ApplyApplicationDefaultsEventArgs, ApplyApplicationDefaultsEventHandler, AssemblyInfo,
AuthenticationMode, CantStartSingleInstanceException, ConsoleApplicationBase, NoStartupFormException,
ShutdownEventHandler, ShutdownMode, StartupEventArgs, StartupEventHandler, StartupNextInstanceEventArgs,
StartupNextInstanceEventHandler, UnhandledExceptionEventArgs, UnhandledExceptionEventHandler, User,
WindowsFormsApplicationBase
Microsoft.VisualBasic.CompilerServices
HostServices, IVbHost
Microsoft.VisualBasic.Devices
Audio, Clock, Computer, ComputerInfo, Keyboard, Mouse, Network, NetworkAvailableEventArgs,
NetworkAvailableEventHandler, ServerComputer
Microsoft.VisualBasic.Logging
DiskSpaceExhaustedOption, FileLogTraceListener, Log, LogFileCreationScheduleOption, LogFileLocation
Microsoft.VisualBasic.MyServices
ClipboardProxy, FileSystemProxy, RegistryProxy, SpecialDirectoriesProxy
Microsoft.VisualBasic.MyServices.Internal
ContextValue`1
Notable consequences, all read from that listing:
-
Microsoft.VisualBasic.DevicesandMicrosoft.VisualBasic.ApplicationServices(the wholeMy.ComputerandMy.Applicationmachinery) are in the Forms assembly, so they exist only fornet*-windowstargets with the Windows desktop pack. -
Computerhas exactlyAudio,Clipboard,Keyboard,MouseandScreen; its base classServerComputerhasClock,FileSystem,Info,Name,NetworkandRegistry. There is noPorts:My.Computer.Ports(serial ports) from .NET Framework books does not exist on .NET; useSystem.IO.Ports.SerialPortfrom theSystem.IO.Portspackage. -
The file-system operations that
My.Computer.FileSystemwraps live inMicrosoft.VisualBasic.FileIO.FileSystemin the Core assembly, so they work in a console program and on Linux (see "Replacements outside a Windows project" below). -
Microsoft.VisualBasic.Logging.LogandFileLogTraceListenerare in the Forms assembly as well. -
The
Userclass sits in the Forms assembly; it hasCurrentPrincipal,IsAuthenticated,IsInRoleandName.
The generated code
For a Windows Forms project (MyType=WindowsForms), reflection over the compiled assembly shows what the compiler generated for My:
ShelfDesktop.My.MyApplication : WindowsFormsApplicationBase
ShelfDesktop.My.MyComputer : Computer
ShelfDesktop.My.MyProject : Object
Application, Computer, Forms, User, WebServices, MyForms, MyWebServices, ThreadSafeObjectProvider`1,
and private fields (m_AppObjectProvider, m_ComputerObjectProvider, m_MyFormsObjectProvider, ...)
ShelfDesktop.My.MyProject+MyForms : Object
one property per Form class (Form1, ...), Create__Instance__, Dispose__Instance__
ShelfDesktop.My.MyProject+MyWebServices : Object
no members apart from Create__Instance__ and Dispose__Instance__
ShelfDesktop.My.MyProject+ThreadSafeObjectProvider`1 : Object
GetInstance, m_ThreadStaticValue
The pieces you should know:
-
MyProjectis a module (hidden from IntelliSense withHideModuleName), which is why you writeMy.Applicationand notMy.MyProject.Application. Each property returns a lazily created, per-thread instance throughThreadSafeObjectProvider(Of T), whoseGetInstancemethod keeps its value in a thread-static field (m_ThreadStaticValue). Two threads therefore see two differentMy.Forms.Form1objects and twoMy.Computerobjects. -
MyApplicationandMyComputerarePartial Friend Classtypes. A second part, written by you, can add members, handlers and overrides; this is howMy.Computer.ShelfFolderin the example below is made. -
MyFormshas one property perFormsubclass in the project; the property creates the form on first use and again after it was disposed. -
MyWebServicescontains nothing but the infrastructure: there is no way to add a web-service reference on .NET that fills it. -
The generated
Main(MyApplication.Main) is what the entry point of aWindowsFormsproject calls. It creates the application, wires the Application Framework and callsRun.
My.Application
My.Application is an instance of the generated MyApplication class. It has these parts in a Windows project.
| Member | Purpose |
|---|---|
|
|
|
the command-line arguments as a read-only collection of strings (without the program name) |
|
the current culture of the thread; |
|
reads an environment variable, throws if it is missing (unlike |
|
a |
|
the collection of open forms (Windows Forms only) |
|
protected or Windows-Forms-specific; the main form is set in |
|
the application life cycle |
The attributes behind Info are ordinary assembly attributes, which the SDK writes from project properties. The program below reads the same data
without My, from a console project that sets Version, AssemblyTitle, Company, Product, Description and Copyright; it is the replacement to use in a console program
and the mapping to remember when Info shows an unexpected value. The other objects are covered by the same program, which prints one block for each My area:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<RootNamespace>ShelfApp</RootNamespace>
<OptionStrict>On</OptionStrict>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NuGetAudit>false</NuGetAudit>
<Version>1.2.0</Version>
<AssemblyTitle>Shelf catalogue</AssemblyTitle>
<Company>Shelf Club</Company>
<Product>Shelf</Product>
<Description>A small library catalogue</Description>
<Copyright>Copyright 2026 Shelf Club</Copyright>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Configuration.ConfigurationManager" Version="10.0.0" />
</ItemGroup>
</Project>
(The System.Configuration.ConfigurationManager package in that project file is for the settings example further down.)
Option Strict On
Imports System.Globalization
Imports System.IO
Imports System.Net.NetworkInformation
Imports System.Reflection
Imports System.Runtime.InteropServices
Module AlternativesDemo
Sub Main(args As String())
Dim asm As Assembly = Assembly.GetEntryAssembly()
Console.WriteLine("-- My.Application.Info")
Console.WriteLine("AssemblyName : " & asm.GetName().Name)
Console.WriteLine("Version : " & asm.GetName().Version.ToString())
Console.WriteLine("Title : " & asm.GetCustomAttribute(Of AssemblyTitleAttribute)().Title)
Console.WriteLine("Company : " & asm.GetCustomAttribute(Of AssemblyCompanyAttribute)().Company)
Console.WriteLine("ProductName : " & asm.GetCustomAttribute(Of AssemblyProductAttribute)().Product)
Console.WriteLine("Description : " & asm.GetCustomAttribute(Of AssemblyDescriptionAttribute)().Description)
Console.WriteLine("Copyright : " & asm.GetCustomAttribute(Of AssemblyCopyrightAttribute)().Copyright)
Console.WriteLine("Info. version: " & asm.GetCustomAttribute(Of AssemblyInformationalVersionAttribute)().InformationalVersion)
Console.WriteLine("DirectoryPath: " & (AppContext.BaseDirectory = Path.GetDirectoryName(asm.Location) & Path.DirectorySeparatorChar).ToString())
Console.WriteLine("-- My.Application.CommandLineArgs / Culture")
Console.WriteLine("Args : " & args.Length.ToString())
Console.WriteLine("Culture : " & CultureInfo.CurrentCulture.DisplayName & " / UI " & CultureInfo.CurrentUICulture.DisplayName)
Console.WriteLine("-- My.Computer.Name / Info / Clock")
Console.WriteLine("Machine name set: " & (Environment.MachineName.Length > 0).ToString())
Console.WriteLine("OS : " & RuntimeInformation.OSDescription)
Console.WriteLine("Architecture : " & RuntimeInformation.OSArchitecture.ToString())
Console.WriteLine("UTC offset : " & TimeZoneInfo.Local.GetUtcOffset(Date.UtcNow).ToString())
Console.WriteLine("Tick count : " & (Environment.TickCount64 > 0).ToString())
Console.WriteLine("-- My.Computer.Network")
Console.WriteLine("IsAvailable : " & NetworkInterface.GetIsNetworkAvailable().ToString())
Console.WriteLine("-- My.User")
Console.WriteLine("User name : " & Environment.UserName)
Console.WriteLine("-- My.Computer.Registry / Clipboard / Audio")
Console.WriteLine("Windows only : " & OperatingSystem.IsWindows().ToString())
Console.WriteLine("-- My.Computer.FileSystem.SpecialDirectories")
Console.WriteLine("Temp : " & Path.GetTempPath())
Console.WriteLine("MyDocuments : " & Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments))
Console.WriteLine("AppData : " & Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData))
End Sub
End Module
Run as dotnet run — one two in the .NET 10 container (the container’s current culture is the invariant culture, and it has no Documents folder, which is why those values are empty):
-- My.Application.Info
AssemblyName : ShelfApp
Version : 1.2.0.0
Title : Shelf catalogue
Company : Shelf Club
ProductName : Shelf
Description : A small library catalogue
Copyright : Copyright 2026 Shelf Club
Info. version: 1.2.0
DirectoryPath: True
-- My.Application.CommandLineArgs / Culture
Args : 2
Culture : Invariant Language (Invariant Country) / UI Invariant Language (Invariant Country)
-- My.Computer.Name / Info / Clock
Machine name set: True
OS : Ubuntu 24.04.5 LTS
Architecture : Arm64
UTC offset : 00:00:00
Tick count : True
-- My.Computer.Network
IsAvailable : True
-- My.User
User name : root
-- My.Computer.Registry / Clipboard / Audio
Windows only : False
-- My.Computer.FileSystem.SpecialDirectories
Temp : /tmp/
MyDocuments :
AppData :
The mapping from a My expression to its replacement is collected in the table below the sections on each object (see "Replacements outside a Windows project").
The Application Framework
In a WindowsForms project My.Application also is the Windows Forms Application Framework. Its options are set in the constructor of MyApplication, and its life cycle is exposed as events.
Visual Studio writes the options into a designer file (Application.Designer.vb) that you edit through the project’s Application page. On .NET with no designer you can write the same constructor yourself; an explicit
Sub New replaces the one the compiler generates, and the build above shows that it compiles without a duplicate-definition error.
| Option (protected property) | Effect |
|---|---|
|
when |
|
calls |
|
calls |
|
|
|
milliseconds that a splash screen stays visible |
|
|
| Event | When it is raised |
|---|---|
|
before the first form is created; its |
|
after the framework is initialised, before the main form; set |
|
a second instance was started (needs |
|
an exception reached the top of the UI thread; |
|
the network came up or went down; |
|
after the main form closed, before the process ends |
The complete Windows tour project that is used in the rest of this page (built, not run; EnableWindowsTargeting was on, the container is Linux) has this project file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<EnableWindowsTargeting>true</EnableWindowsTargeting>
<RootNamespace>ShelfDesktop</RootNamespace>
<MyType>WindowsForms</MyType>
<OptionStrict>On</OptionStrict>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NuGetAudit>false</NuGetAudit>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Configuration.ConfigurationManager" Version="10.0.0" />
</ItemGroup>
</Project>
and this MyApplication.vb. The class is declared in Namespace My with the same name that the compiler uses, so the two parts merge:
Option Strict On
Imports System.Drawing
Imports System.Windows.Forms
Imports Microsoft.VisualBasic.ApplicationServices
Imports Microsoft.VisualBasic.Logging
Namespace My
Partial Friend Class MyApplication
' The Application Framework options. Visual Studio writes the same lines into
' Application.Designer.vb; on .NET an explicit constructor replaces the generated one.
Public Sub New()
MyBase.New(AuthenticationMode.Windows)
IsSingleInstance = True
EnableVisualStyles = True
SaveMySettingsOnExit = True
ShutdownStyle = ShutdownMode.AfterMainFormCloses
End Sub
Protected Overrides Sub OnCreateMainForm()
MainForm = My.Forms.MainForm
End Sub
Private Sub MyApplication_ApplyApplicationDefaults(sender As Object, e As ApplyApplicationDefaultsEventArgs) Handles Me.ApplyApplicationDefaults
e.Font = New Font("Segoe UI", 10.0F)
e.HighDpiMode = HighDpiMode.SystemAware
e.MinimumSplashScreenDisplayTime = 0
e.ColorMode = SystemColorMode.System
End Sub
Private Sub MyApplication_Startup(sender As Object, e As StartupEventArgs) Handles Me.Startup
Log.DefaultFileLogWriter.Location = LogFileLocation.ExecutableDirectory
Log.WriteEntry("Started with " & e.CommandLine.Count.ToString() & " argument(s)", TraceEventType.Information)
If e.CommandLine.Contains("--reset") Then My.Settings.Reset()
End Sub
Private Sub MyApplication_StartupNextInstance(sender As Object, e As StartupNextInstanceEventArgs) Handles Me.StartupNextInstance
e.BringToForeground = True
Log.WriteEntry("Second instance with " & e.CommandLine.Count.ToString() & " argument(s)")
End Sub
Private Sub MyApplication_UnhandledException(sender As Object, e As UnhandledExceptionEventArgs) Handles Me.UnhandledException
Log.WriteException(e.Exception, TraceEventType.Critical, "Unhandled")
MessageBox.Show(e.Exception.Message, Info.Title, MessageBoxButtons.OK, MessageBoxIcon.Error)
e.ExitApplication = False
End Sub
Private Sub MyApplication_NetworkAvailabilityChanged(sender As Object, e As Microsoft.VisualBasic.Devices.NetworkAvailableEventArgs) Handles Me.NetworkAvailabilityChanged
Log.WriteEntry("Network available: " & e.IsNetworkAvailable.ToString())
End Sub
Private Sub MyApplication_Shutdown(sender As Object, e As EventArgs) Handles Me.Shutdown
Log.WriteEntry("Shutdown")
End Sub
End Class
End Namespace
Built, not run. Notes on the listing:
-
Handles Me.Startupworks becauseMyApplicationinheritsWindowsFormsApplicationBase; in aConsoleproject the base class has no such events. -
The
Startuphandler resets the settings when--resetis on the command line, which is a common use ofe.CommandLine. -
OnCreateMainFormsetsMainFormto the default instanceMy.Forms.MainForm. A project that has noSub Mainmust set it, or the framework has no form to run and raisesNoStartupFormException(a type in the Forms assembly). -
UnhandledExceptionis the framework’s safety net for the UI thread only. Exceptions on other threads or inasync Subhandlers do not arrive here; see Windows Forms Applications for the other handlers. -
ColorMode = SystemColorMode.Systemcompiled without an experimental-API diagnostic on this SDK; the dark-mode behaviour itself should be checked on a real machine.
Logging with My.Application.Log
My.Application.Log wraps a TraceSource with a default FileLogTraceListener. WriteEntry(message, severity) and WriteException(ex, severity, details) write lines with a timestamp and the severity; the listener has Location (for example LogFileLocation.ExecutableDirectory, the Startup handler above sets it),
BaseFileName, Append, AutoFlush, MaxFileSize, ReserveDiskSpace, LogFileCreationSchedule and DiskSpaceExhaustedBehavior. It is a file logger only; for an application with structured logs and levels, use Microsoft.Extensions.Logging
(see Debugging and Diagnostics). My.Log for ASP.NET (AspLog) does not exist on .NET.
My.Computer
My.Computer is the machine. Each child is a different small class; the table lists the child, its members as read from the reference assembly, and the cross-platform replacement
for use in a console project or a library.
| Object | Members (from the reference assembly) | Replacement without My |
|---|---|---|
|
computer name |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
the primary |
|
|
does not exist on .NET |
|
Two points are easy to miss. Network.DownloadFile and UploadFile are the older, user-interface-oriented download API; new code should use HttpClient. And
FileSystem is the only part of My.Computer that a console program can use through a public type: Microsoft.VisualBasic.FileIO.FileSystem is the same code. The program below drives it on Linux:
Option Strict On
Imports Microsoft.VisualBasic.FileIO
Module FileSystemDemo
Sub Main()
Dim root As String = IO.Path.Combine(IO.Path.GetTempPath(), "shelf-fs-demo")
If FileSystem.DirectoryExists(root) Then FileSystem.DeleteDirectory(root, DeleteDirectoryOption.DeleteAllContents)
FileSystem.CreateDirectory(IO.Path.Combine(root, "notes", "archive"))
Dim notes As String = FileSystem.CombinePath(root, "notes")
Dim dune As String = FileSystem.CombinePath(notes, "dune.txt")
FileSystem.WriteAllText(dune, "Dune, Herbert" & vbLf, False)
FileSystem.WriteAllText(dune, "Arrakis" & vbLf, True)
FileSystem.WriteAllText(FileSystem.CombinePath(FileSystem.CombinePath(notes, "archive"), "emma.txt"), "Emma, Austen" & vbLf, False)
Console.WriteLine("-- ReadAllText")
Console.Write(FileSystem.ReadAllText(dune))
Console.WriteLine("-- GetFiles (all sub-directories, *.txt)")
For Each f In FileSystem.GetFiles(root, SearchOption.SearchAllSubDirectories, "*.txt").OrderBy(Function(x) x)
Console.WriteLine(IO.Path.GetRelativePath(root, f))
Next
Console.WriteLine("-- FindInFiles")
For Each f In FileSystem.FindInFiles(root, "Austen", True, SearchOption.SearchAllSubDirectories)
Console.WriteLine(IO.Path.GetRelativePath(root, f))
Next
Console.WriteLine("-- CopyDirectory and GetParentPath")
Dim backup As String = FileSystem.CombinePath(root, "backup")
FileSystem.CopyDirectory(notes, backup)
Console.WriteLine(FileSystem.GetFiles(backup).Count.ToString() & " file(s) in backup")
Console.WriteLine(IO.Path.GetRelativePath(root, FileSystem.GetParentPath(FileSystem.CombinePath(backup, "dune.txt"))))
Console.WriteLine("-- DeleteDirectory")
FileSystem.DeleteDirectory(root, DeleteDirectoryOption.DeleteAllContents)
Console.WriteLine("exists after delete: " & FileSystem.DirectoryExists(root).ToString())
End Sub
End Module
-- ReadAllText
Dune, Herbert
Arrakis
-- GetFiles (all sub-directories, *.txt)
notes/archive/emma.txt
notes/dune.txt
-- FindInFiles
notes/archive/emma.txt
-- CopyDirectory and GetParentPath
1 file(s) in backup
backup
-- DeleteDirectory
exists after delete: False
Notes: CombinePath takes exactly two arguments (a three-argument call is BC30057), the search methods take the SearchOption before the patterns, FindInFiles takes (directory, text, ignoreCase, searchOption).
The calls that show dialogs and recycle-bin deletes (UIOption.AllDialogs, RecycleOption.SendToRecycleBin) are Windows behaviour and belong to
Files, Directories and Streams.
Extending My.Computer
Because the generated MyComputer is Partial, you can add members to My.Computer. The example below (part of the Windows tour, built, not run) adds a ShelfFolder property that
creates and returns a per-user data folder. It uses the inherited FileSystem and SpecialDirectories children:
Option Strict On
Imports System.IO
Namespace My
' MyComputer is generated as a partial class, so a second part can add members to My.Computer
Partial Friend Class MyComputer
Public ReadOnly Property ShelfFolder As String
Get
Dim folder As String = Path.Combine(FileSystem.SpecialDirectories.CurrentUserApplicationData, "Shelf")
FileSystem.CreateDirectory(folder)
Return folder
End Get
End Property
End Class
End Namespace
My.User
My.User is a Microsoft.VisualBasic.ApplicationServices.User with Name, IsAuthenticated, IsInRole(role) and CurrentPrincipal. With AuthenticationMode.Windows
(the default of the generated constructor) the principal is the Windows identity, so Name is DOMAIN\user; with ApplicationDefined you assign CurrentPrincipal yourself,
which is how a program with its own log-in uses it. IsInRole("BUILTIN\Administrators") tests Windows group membership; the BuiltInRole enumeration of .NET Framework is
not in the .NET assembly (the reference listing above has no such type), so pass the group name as a string. In a console program the replacement is
Environment.UserName, or System.Security.Principal.WindowsIdentity.GetCurrent() on Windows.
My.Settings
My.Settings gives typed, persisted settings. It rests on System.Configuration.ApplicationSettingsBase from the System.Configuration.ConfigurationManager package, and the Visual Studio Settings designer writes the class you see below.
Two scopes exist:
| Scope | Attribute | Behaviour |
|---|---|---|
User |
|
read and write; saved with |
Application |
|
read-only at run time; the default comes from the application’s |
The class and the My.Settings property are ordinary code (the settings designer generates exactly this shape; the property is a module in Namespace My, which is how a member is added to My). Written by hand,
it works in a console program too, because only the System.Configuration.ConfigurationManager package is needed. The program writes a user setting and reads it back in the next process:
Option Strict On
Imports System.Configuration
Namespace My
<Global.System.Runtime.CompilerServices.CompilerGenerated()>
Partial Friend NotInheritable Class MySettings
Inherits ApplicationSettingsBase
Private Shared ReadOnly defaultInstance As MySettings =
CType(Synchronized(New MySettings()), MySettings)
Public Shared ReadOnly Property [Default] As MySettings
Get
Return defaultInstance
End Get
End Property
<UserScopedSetting()>
<DefaultSettingValue("20")>
Public Property PageSize As Integer
Get
Return CInt(Me("PageSize"))
End Get
Set(value As Integer)
Me("PageSize") = value
End Set
End Property
<ApplicationScopedSetting()>
<DefaultSettingValue("shelf.db")>
Public ReadOnly Property DatabaseFile As String
Get
Return CStr(Me("DatabaseFile"))
End Get
End Property
End Class
<Global.Microsoft.VisualBasic.HideModuleName()>
Friend Module MySettingsProperty
Friend ReadOnly Property Settings As MySettings
Get
Return MySettings.Default
End Get
End Property
End Module
End Namespace
Module SettingsDemo
Sub Main()
Console.WriteLine("PageSize (default) : " & My.Settings.PageSize.ToString())
Console.WriteLine("DatabaseFile : " & My.Settings.DatabaseFile)
My.Settings.PageSize = 50
My.Settings.Save()
Dim cfg As Configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal)
Console.WriteLine("user file exists : " & IO.File.Exists(cfg.FilePath).ToString())
Console.WriteLine("user file path : " & cfg.FilePath)
My.Settings.Reload()
Console.WriteLine("PageSize (reloaded) : " & My.Settings.PageSize.ToString())
End Sub
End Module
Run twice in the same container (the project sets Version, Company and AssemblyTitle as above; the long folder name contains a hash that identifies the program, and /root is the container’s home):
--- first run
PageSize (default) : 20
DatabaseFile : shelf.db
user file exists : True
user file path : /root/.local/share/Shelf_Club/ShelfApp_Url_jgfpubpizyjaxpv0hqug1xdjy2ec1pco/1.2.0.0/user.config
PageSize (reloaded) : 50
--- second run
PageSize (default) : 50
DatabaseFile : shelf.db
user file exists : True
user file path : /root/.local/share/Shelf_Club/ShelfApp_Url_jgfpubpizyjaxpv0hqug1xdjy2ec1pco/1.2.0.0/user.config
PageSize (reloaded) : 50
Source: ApplicationSettingsBase class
What the output shows and what to remember:
-
The first run starts with the default
20fromDefaultSettingValue, saves50, and the second process starts with50. The value is stored per company, product-and-path hash and version (1.2.0.0in the path): a new assembly version starts with the defaults unless you callMy.Settings.Upgrade()(guard it with anUpgradeRequiredsetting, the usual pattern). -
Save()is explicit. In a Windows Forms projectSaveMySettingsOnExit = True(the generated default) saves when the application ends; a console program has no such hook, so callSave()yourself. -
Reload()discards unsaved changes,Reset()restores the defaults. -
An application-scoped setting is read-only. Assigning to it, a wrong type or a missing name are all compile-time errors with
Option Strict On. With the module below (added after theMySettingsclass above):
Module SettingsDemo
Sub Main()
My.Settings.DatabaseFile = "other.db"
My.Settings.PageSize = "many"
My.Settings.Missing = 1
End Sub
End Module
the compiler printed (line numbers count the class that precedes the module in the file):
Program.vb(51,9): error BC30526: Property 'DatabaseFile' is 'ReadOnly'.
Program.vb(52,32): error BC30512: Option Strict On disallows implicit conversions from 'String' to 'Integer'.
Program.vb(53,9): error BC30456: 'Missing' is not a member of 'MySettings'.
-
The settings file is XML that is not meant to be shared, signed or secret: do not store passwords or tokens in it. See Security and Cryptography.
-
For new .NET code that is not Windows Forms, the usual alternatives are
appsettings.jsonwithMicrosoft.Extensions.Configuration(read-only, layered, environment-aware) for configuration, and a small JSON file (see Serialization: JSON and XML) written toEnvironment.SpecialFolder.ApplicationDatafor user preferences.
My.Resources
My.Resources exposes the entries of the project’s Resources.resx as typed properties. As with settings, the property group is a module in Namespace My.Resources, which the Resources designer (a custom tool) generates; the
compiler does not. The module below has the same shape as the generated file, and the .resx files next to it are compiled into the assembly by the SDK (the default file Resources.resx and the Spanish
satellite Resources.es.resx). The resource name is the root namespace plus the file name, ShelfApp.Resources:
Option Strict On
Imports System.Globalization
Imports System.Resources
Namespace My.Resources
' The same shape as the file that Visual Studio generates for a project's Resources.resx
<Global.Microsoft.VisualBasic.HideModuleName()>
Friend Module Resources
Private ReadOnly manager As New ResourceManager("ShelfApp.Resources", GetType(Resources).Assembly)
Friend ReadOnly Property ResourceManager As ResourceManager
Get
Return manager
End Get
End Property
Friend ReadOnly Property Greeting As String
Get
Return manager.GetString("Greeting", CultureInfo.CurrentUICulture)
End Get
End Property
Friend ReadOnly Property BookCount As String
Get
Return manager.GetString("BookCount", CultureInfo.CurrentUICulture)
End Get
End Property
End Module
End Namespace
Module ResourcesDemo
Sub Main()
Console.WriteLine(My.Resources.Greeting)
Console.WriteLine(String.Format(My.Resources.BookCount, 2))
CultureInfo.CurrentUICulture = New CultureInfo("es")
Console.WriteLine(My.Resources.Greeting)
Console.WriteLine(String.Format(My.Resources.BookCount, 2))
End Sub
End Module
Welcome to the shelf
2 books on the shelf
Bienvenido a la estanteria
2 books on the shelf
Source: ResourceManager class
The second Greeting comes from the satellite resource for es, and BookCount falls back to the neutral resource because the Spanish file does not define it, which is the normal resource fallback. Typed properties exist
for strings, images (System.Drawing.Bitmap), icons, byte arrays and streams. Remember that CurrentUICulture (not CurrentCulture) selects the satellite assembly.
My.Forms and default instances
In a Windows Forms project My.Forms has a property for each form, and Visual Basic lets you use the class name as that property: BookForm.Show() means My.Forms.BookForm.Show(). This is the default instance. The form is created on first use, and a new one is created
after it has been closed and disposed. The rule of the compiler is: when a name denotes a class that has a default instance and it is used where an instance is required, it is replaced by the My.Forms property.
It exists to ease migration from VB6, where Form1.Show worked without creating a form. Its costs are the usual ones of hidden global state: two parts of the program talk to the same hidden object, there is one instance per thread, Me
is not always what you expect when the form is also created with New, and unit tests cannot replace it. Prefer creating forms with New BookForm() and passing them where they are needed. The compiler does not generate default instances for classes that are not forms.
When the project type has no MyForms, using the class name as an instance is an ordinary error. In a project with MyType=Windows the program below
Option Strict On
Imports System.Windows.Forms
Public Class BookForm
Inherits Form
End Class
Module Program
Sub Main()
BookForm.Show()
My.Forms.BookForm.Show()
End Sub
End Module
does not compile:
Program.vb(11,9): error BC30469: Reference to a non-shared member requires an object reference.
Program.vb(12,9): error BC30456: 'Forms' is not a member of 'ShelfDesktop.My'.
Source: Development with My
In the Windows tour project the main form is shown with MainForm = My.Forms.MainForm and the second form with BookForm.Show(); both appear in the listings below. WPF projects have no form default instances; My.Forms is a Windows Forms concept.
Unsupported on .NET
-
My.WebServices. The class is generated, but there is no ASMX/WCF proxy generator that fills it on .NET. UseHttpClientor a generated gRPC/OpenAPI client. -
My.Request,My.Response,My.Log(ASP.NET) belong toMyType=Weband System.Web; they do not exist on .NET. In ASP.NET Core useHttpContextandILogger. See Web, HTTP and Services. -
My.Computer.Portsdoes not exist (see above). -
MyType=Webdoes not compile (BC30002 forWebUser,AspLogandHttpRequest). -
Windows-only members of the supported objects: everything in the Forms assembly runs on Windows only;
My.Computer.Registry,Audio,Keyboard,Mouse,ScreenandClipboarddepend on Windows Forms. A program that must also run on Linux or macOS should not useMy.*at all, and uses the replacements in the next section.
Replacements outside a Windows project
The program in "My.Application" printed the replacements for Info, Culture, Name, Info, Clock, Network, User and the special directories. In summary:
My expression |
Replacement that works in any project |
|---|---|
|
|
|
|
|
|
|
the |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
your own |
|
a |
MsgBox and InputBox need Windows Forms
MsgBox and InputBox are functions of the runtime library (Microsoft.VisualBasic.Interaction), not of My, but they are reached for in the same programs. They compile in any project, and calling them fails unless
Windows Forms is available, because they show a Windows Forms dialog. Some neighbouring functions are Windows-only in a different way: the compiler’s platform analyzer (CA1416) flags Beep, GetSetting, SaveSetting, StrConv, Dir, Rename and others
(which are annotated as supported on Windows only), and with warnings as errors the build fails.
The program below calls them from a console program on Linux. CA1416 is turned off in this one project with <NoWarn>$(NoWarn);CA1416</NoWarn>, because the point of the program is to show what happens at run time (without that
line the build fails with error CA1416: This call site is reachable on all platforms. 'Public Overloads Sub Beep()' is only supported on: 'windows'. and the same for GetSetting and SaveSetting):
Option Strict On
Module DialogsDemo
Private Sub Attempt(label As String, action As Action)
Try
action()
Console.WriteLine(label & ": returned")
Catch ex As Exception
Console.WriteLine(label & ": " & ex.GetType().FullName & " - " & ex.Message)
End Try
End Sub
Sub Main()
Attempt("MsgBox", Sub() MsgBox("Saved", MsgBoxStyle.Information, "Shelf"))
Attempt("InputBox", Sub() Console.WriteLine(InputBox("Title?", "Shelf", "Dune")))
Attempt("Interaction.MsgBox", Sub() Interaction.MsgBox("Saved"))
Attempt("Beep", Sub() Beep())
Attempt("GetSetting", Sub() Console.WriteLine(GetSetting("Shelf", "Window", "Left", "0")))
Attempt("SaveSetting", Sub() SaveSetting("Shelf", "Window", "Left", "10"))
End Sub
End Module
MsgBox: System.PlatformNotSupportedException - Method requires System.Windows.Forms.
InputBox: System.PlatformNotSupportedException - Method requires System.Windows.Forms.
Interaction.MsgBox: System.PlatformNotSupportedException - Method requires System.Windows.Forms.
Beep: System.PlatformNotSupportedException - Operation is not supported on this platform.
GetSetting: System.NullReferenceException - Object reference not set to an instance of an object.
SaveSetting: System.NullReferenceException - Object reference not set to an instance of an object.
Source: Interaction module
The failures differ: MsgBox and InputBox throw PlatformNotSupportedException with the text "Method requires System.Windows.Forms."; Beep throws PlatformNotSupportedException; GetSetting and SaveSetting throw NullReferenceException (they use the Windows registry, which is not present).
The SaveSetting/GetSetting pair stores values under the registry key HKEY_CURRENT_USER\Software\VB and VBA Program Settings; use My.Settings or a JSON file in new code. In a console program ask the user with
Console.ReadLine; see Console Applications. In a Windows Forms program prefer MessageBox.Show, which has the same buttons and icons. The mapping of MsgBoxStyle and MsgBoxResult values is in
The Visual Basic Runtime Library.
Extending My with your own members
Any code in Namespace My of the project becomes part of My. The two usual forms are a module whose properties become My.X (as My.Settings and My.Resources do), and a partial class (MyApplication, MyComputer, MySettings) when the type already exists. A module needs HideModuleName
so that IntelliSense offers My.Shelf and not the module name. The program below adds a My.Shelf service backed by a Lazy(Of T) and shows that it is an ordinary member:
Option Strict On
Namespace My
' Your own service, reachable as My.Shelf
Friend NotInheritable Class ShelfService
Private ReadOnly titles As New List(Of String) From {"Dune", "Emma"}
Public ReadOnly Property Count As Integer
Get
Return titles.Count
End Get
End Property
Public Sub Add(title As String)
titles.Add(title)
End Sub
Public Function Latest() As String
Return titles(titles.Count - 1)
End Function
End Class
<Global.Microsoft.VisualBasic.HideModuleName()>
Friend Module MyShelfExtension
Private ReadOnly instance As New Lazy(Of ShelfService)(Function() New ShelfService())
Friend ReadOnly Property Shelf As ShelfService
Get
Return instance.Value
End Get
End Property
End Module
End Namespace
Module ExtendMyDemo
Sub Main()
My.Shelf.Add("Ulysses")
Console.WriteLine("count : " & My.Shelf.Count.ToString())
Console.WriteLine("latest : " & My.Shelf.Latest())
' The module name is hidden from IntelliSense but is still a valid qualifier
Console.WriteLine("same : " & Object.ReferenceEquals(My.Shelf, My.MyShelfExtension.Shelf).ToString())
Console.WriteLine("type : " & My.Shelf.GetType().FullName)
Console.WriteLine("namespace: " & GetType(My.ShelfService).Namespace)
End Sub
End Module
count : 3
latest : Ulysses
same : True
type : ShelfApp.My.ShelfService
namespace: ShelfApp.My
Source: Development with My
Rules and cautions, all of them checked above:
-
The program runs on a console project (
MyType=Empty), so this is the way to get aMy-style entry point everywhere. -
HideModuleNameonly hides the module from IntelliSense;My.MyShelfExtension.Shelfis still valid and is the same object asMy.Shelf. -
The types sit in
ShelfApp.My, the project’s root namespace plusMy. A library that definesNamespace Mydoes not export it to its consumers as theirMy: each project has its own. -
A name that collides with a generated one (
Application,Computer,User,Forms,Settings,Resources,WebServices) is an error in projects that generate it; give custom members distinctive names. -
A per-thread instance, as
ThreadSafeObjectProvidergives, is a deliberate choice; aLazy(Of T)as above is shared by every thread, so the object must be thread-safe. -
Treat
Myextensions as a convenience for the application project. Shared libraries should take their dependencies as parameters.
The Windows tour
The rest of the tour project ties the objects together. It is a Windows Forms program (built, not run), the same program of which MyApplication.vb and MyComputerExtension.vb were shown above. MySettings.vb is the settings class with an added System.Drawing.Point setting:
Option Strict On
Imports System.Configuration
Namespace My
' What the Settings designer generates: user-scoped settings are read/write and saved per user,
' application-scoped ones are read-only and come from the application's .config file
<Global.System.Runtime.CompilerServices.CompilerGenerated()>
Partial Friend NotInheritable Class MySettings
Inherits ApplicationSettingsBase
Private Shared ReadOnly defaultInstance As MySettings = CType(Synchronized(New MySettings()), MySettings)
Public Shared ReadOnly Property [Default] As MySettings
Get
Return defaultInstance
End Get
End Property
<UserScopedSetting()>
<DefaultSettingValue("20")>
Public Property PageSize As Integer
Get
Return CInt(Me("PageSize"))
End Get
Set(value As Integer)
Me("PageSize") = value
End Set
End Property
<UserScopedSetting()>
<DefaultSettingValue("100, 100")>
Public Property WindowLocation As Drawing.Point
Get
Return CType(Me("WindowLocation"), Drawing.Point)
End Get
Set(value As Drawing.Point)
Me("WindowLocation") = value
End Set
End Property
<ApplicationScopedSetting()>
<DefaultSettingValue("shelf.db")>
Public ReadOnly Property DatabaseFile As String
Get
Return CStr(Me("DatabaseFile"))
End Get
End Property
End Class
<Global.Microsoft.VisualBasic.HideModuleName()>
Friend Module MySettingsProperty
Friend ReadOnly Property Settings As MySettings
Get
Return MySettings.Default
End Get
End Property
End Module
End Namespace
Resources.vb is the resources module (with the string resource of the Resources.resx shown earlier), and BookForm.vb is the second form that uses the file system, the resources and the default instance:
Option Strict On
Imports System.Globalization
Imports System.Resources
Namespace My.Resources
<Global.Microsoft.VisualBasic.HideModuleName()>
Friend Module Resources
Private ReadOnly manager As New ResourceManager("ShelfDesktop.Resources", GetType(Resources).Assembly)
Friend ReadOnly Property Greeting As String
Get
Return manager.GetString("Greeting", CultureInfo.CurrentUICulture)
End Get
End Property
End Module
End Namespace
Option Strict On
Imports System.Windows.Forms
Public Class BookForm
Inherits Form
Public Sub New()
Text = "Book"
Dim path As String = My.Computer.FileSystem.CombinePath(My.Computer.ShelfFolder, "books.txt")
If My.Computer.FileSystem.FileExists(path) Then Text = My.Computer.FileSystem.ReadAllText(path)
Dim greeting As String = My.Resources.Greeting
Text = greeting
End Sub
End Class
and MainForm.vb is the main form, which touches the other objects of My.Computer:
Option Strict On
Imports System.Windows.Forms
Public Class MainForm
Inherits Form
Private WithEvents AboutButton As New Button() With {.Text = "About", .Dock = DockStyle.Top}
Private WithEvents CopyButton As New Button() With {.Text = "Copy ISBN", .Dock = DockStyle.Top}
Private WithEvents HelpButton2 As New Button() With {.Text = "Open second form", .Dock = DockStyle.Top}
Private ReadOnly output As New TextBox() With {.Multiline = True, .Dock = DockStyle.Fill, .ReadOnly = True}
Public Sub New()
Controls.Add(output)
Controls.Add(HelpButton2)
Controls.Add(CopyButton)
Controls.Add(AboutButton)
Text = My.Application.Info.Title & " " & My.Application.Info.Version.ToString()
Location = My.Settings.WindowLocation
StartPosition = FormStartPosition.Manual
End Sub
Private Sub AboutButton_Click(sender As Object, e As EventArgs) Handles AboutButton.Click
With My.Application.Info
output.Text = .ProductName & " " & .Version.ToString() & " by " & .CompanyName & Environment.NewLine &
.Copyright & Environment.NewLine &
"Working set: " & .WorkingSet.ToString() & " bytes" & Environment.NewLine &
"Loaded assemblies: " & .LoadedAssemblies.Count.ToString() & Environment.NewLine &
"Directory: " & .DirectoryPath
End With
output.AppendText(Environment.NewLine & "Computer: " & My.Computer.Name &
" / " & My.Computer.Info.OSFullName & " " & My.Computer.Info.OSVersion &
Environment.NewLine & "RAM: " & (My.Computer.Info.TotalPhysicalMemory \ 1048576UL).ToString() & " MB" &
Environment.NewLine & "Screen: " & My.Computer.Screen.Bounds.Width.ToString() & "x" & My.Computer.Screen.Bounds.Height.ToString() &
Environment.NewLine & "User: " & My.User.Name & ", authenticated: " & My.User.IsAuthenticated.ToString() &
Environment.NewLine & "Admin: " & My.User.IsInRole("BUILTIN\Administrators").ToString() &
Environment.NewLine & "Now (local/UTC): " & My.Computer.Clock.LocalTime.ToString("s") & " / " & My.Computer.Clock.GmtTime.ToString("s") &
Environment.NewLine & "Network: " & My.Computer.Network.IsAvailable.ToString() &
Environment.NewLine & "Caps lock: " & My.Computer.Keyboard.CapsLock.ToString() &
Environment.NewLine & "Mouse wheel: " & My.Computer.Mouse.WheelExists.ToString() &
Environment.NewLine & "Culture: " & My.Application.Culture.Name & " / " & My.Application.UICulture.Name)
End Sub
Private Sub CopyButton_Click(sender As Object, e As EventArgs) Handles CopyButton.Click
My.Computer.Clipboard.SetText("9780306406157")
If My.Computer.Clipboard.ContainsText() Then output.Text = My.Computer.Clipboard.GetText()
End Sub
Private Sub HelpButton2_Click(sender As Object, e As EventArgs) Handles HelpButton2.Click
' Default instance: the class name acts as a variable that creates the form on first use
BookForm.Show()
' The same object, spelled explicitly
My.Forms.BookForm.Text = "Book (" & My.Settings.PageSize.ToString() & " per page)"
My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Asterisk)
End Sub
Protected Overrides Sub OnFormClosing(e As FormClosingEventArgs)
My.Settings.WindowLocation = Location
My.Settings.PageSize = 30
My.Settings.Save()
My.Computer.Registry.SetValue("HKEY_CURRENT_USER\Software\Shelf", "LastRun", Date.Now.ToString("s"))
Dim last As Object = My.Computer.Registry.GetValue("HKEY_CURRENT_USER\Software\Shelf", "LastRun", "never")
My.Application.Log.WriteEntry("Closing; last run " & CStr(last))
MyBase.OnFormClosing(e)
End Sub
End Class
All of it built with TreatWarningsAsErrors and no warning on the .NET 10 SDK; none of it was run because the container is Linux. Points worth noting in the listings:
-
My.Computer.Info.TotalPhysicalMemoryis aULong, so the division uses\ 1048576UL. -
My.User.IsInRole("BUILTIN\Administrators")uses the group name because the enumeration overload is missing on .NET. -
HelpButton2_Clickcreates the form through its default instance and then sets its title throughMy.Forms.BookForm: the same object, spelled two ways. -
OnFormClosingsaves the window position throughMy.Settings, writes the registry throughMy.Computer.Registry.SetValuewith a full key path (the first argument starts with the hive name) and logs throughMy.Application.Log.
Differences from C# and from .NET Framework
-
C# has no
My. The same functions are called asMicrosoft.VisualBasic.FileIO.FileSystem,Microsoft.VisualBasic.Interactionand so on from C# when a reference toMicrosoft.VisualBasicis added; the Application Framework, default instances andMy.Settingshave no C# counterpart (C# Windows Forms usesApplication.Run(new MainForm()),Properties.Settings.DefaultandProperties.Resources). See Interop with C# and Other .NET Languages. -
On .NET Framework every project type had
My,MyTypedefaulted by project template,My.Computer.PortsandMy.WebServicesworked, and the designer pages of the project (Application, Settings, Resources) were the normal way to configure them. On .NET only the Windows Forms and WPF projects have a non-emptyMy. -
My.SettingsandMy.Resourcescome from the project designer in Visual Studio; without the designer you write the two small files by hand, as shown.
Where the books are outdated
Older Visual Basic books and tutorials use My freely and assume that it is always there. Check these points before copying their code:
| Book habit | Today on .NET |
|---|---|
|
does not compile in a console project (BC30456); use |
|
no |
|
needs the |
|
a console program throws |
|
throws on a console project; use |
|
needs |
|
works only in |
|
ASP.NET Web Forms is .NET Framework only; see ASP.NET Web Forms |
Error and warning reference
| Diagnostic | Meaning (messages are the compiler’s, shown above) |
|---|---|
BC30456 |
|
BC30002 |
|
BC30469 |
|
BC30526 |
|
BC30512 |
|
BC30057 |
|
CA1416 |
a runtime-library member is annotated as Windows-only and the call site is reachable on other platforms |
Pitfalls checklist
-
Do not assume
Myexists: check theMyTypeof the project before usingMy.*in an answer, a library or a console tool. -
My.SettingsandMy.Resourcesare not generated by the compiler; if they are missing, the designer files are missing. -
My.Formsand default instances are per thread; touching a form from another thread through the default instance creates a second form. -
Do not put secrets in
user.config. -
Settings are keyed by version and path: a new version starts with the defaults unless you upgrade.
-
A
Myextension in a library is private to the library’s own project. -
Anything in
Microsoft.VisualBasic.Formsis Windows-only, includingLogandMy.User. -
Prefer explicit objects (a
HttpClient, anILogger, a form created withNew) overMyin code that has to be tested.
References
-
Visual Basic language reference: objects (the
Myobject reference pages) -
Microsoft.VisualBasic.ApplicationServices, Microsoft.VisualBasic.Devices, Microsoft.VisualBasic.MyServices and Microsoft.VisualBasic.FileIO.FileSystem
-
Windows Forms Applications, The Visual Basic Runtime Library and Files, Directories and Streams in this section
-
Modules and Shared Members (the
HideModuleNameattribute and how a module’s members are reached)