Dealing with Windows security

Windows User Access Control (UAC for short) is a security feature of Windows which helps prevent unauthorized changes to the operating system. It prompts you to give additional permissions for certain system actions. You may need to do this to install files or registry items into system locations for example.

64-bit apps

For 64-bit Windows apps you can build your app so that it requests UAC when it starts. To do this, go to the Windows Build Settings Inspector and make sure the Architecture is set to x86 64-bit or ARM 64-bit. In the Advanced settings of the Inspector you can change the Security setting from "User" (the default) to either "Highest Available" or "Administrator". With "Administrator" selected your app will display the UAC prompt when it is launched.

32-bit apps

For 32-bit apps you need to use an alternate technique to prompt UAC. This method creates a Visual Basic Script (VBS) to launch your program with Elevated Access Rights. It does not bypass the security of Windows! It causes the UAC dialog to appear so the user can agree to or enter administrator credentials. The program parameter needs to be the NativePath of the executable file.

This method can be used to launch Console apps to do things like update "protected" registry items and/or install programs.

Sub ExecuteWithUAC(program As String, args As String)
  Var f As FolderItem
  Var t As TextOutputStream
  Var script As String = "Set objShell = CreateObject(""Shell.Application"")" + EndOfLine _
    + "objShell.ShellExecute ""<Program>"", ""<Args>"", """", ""runas"", 1" + EndOfLine

  Var s As String
  f = GetTemporaryFolderItem
  f = New FolderItem(f.NativePath + ".vbs")
  t = TextOutputStream.Create(f)
  s = script.ReplaceAll("<Program>", program)
  s = s.ReplaceAll("<Args>", ReplaceAll(args, Chr(34), Chr(34) + Chr(34)))
  t.WriteLine(s)
  t.Close

  Var sh As New Shell
  sh.Mode = 0
  sh.TimeOut = 10000
  sh.Execute("Wscript.exe " + f.NativePath)
  f.Remove
End Sub

Thanks to long-time Xojo customer Wayne Golding for this code!