IPFilter Updater… Updated!

I’ve made some minor changes to the IPFilter Updater.

The list mirror it was using was out of date, so I’ve found a new list provider (I-Blocklist) and obtained their permission to point at that list.

The project has also now been re-hosted on Codeplex.

New home: https://ipfilter.codeplex.com/

Creating a machine account login for SQL Server

You can create a machine account login for SQL Server with the following command:

CREATE USER [MACHINENAME] FOR LOGIN [DOMAIN\MACHINENAME$] WITH DEFAULT_SCHEMA=[dbo]

Deleting and purging items from Team Foundation Server

When you delete an item from TFS, it’s not actually permanently gone.

You can view deleted items by going to Tools > Options > Source Control > Visual Studio Team Foundation Server and checking the Show deleted items in the Source Control Explorer option:

image

You can then see folders and files that have been deleted, which allows you to right click on them to choose Undelete (or go to File > Source Control > Undelete).

It’s useful to show deleted items by default, but you may find that your source tree ends up a bit clogged with all the deleted files and folders.

You can purge items you want to delete permanently by using the TFS command-line tools.

TF.EXE is found with Visual Studio 2010 under C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE for 64 bit machines, and C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE on 32 bit.

You might find it useful to add that path to your command line.

The commandlet you want to use is destroy, which tf.exe can give us info on:

C:\Windows\System32>tf help destroy
TF - Team Foundation Version Control Tool, Version 10.0.30319.1
Copyright (c) Microsoft Corporation.  All rights reserved.

Destroys, or permanently deletes, version-controlled items from Team
Foundation version control.

tf destroy [/keephistory] itemspec1 [;versionspec]
[itemspec2...itemspecN] [/stopat:versionspec] [/preview]
[/startcleanup] [/noprompt] [/silent]
[/login:username,[password]]
[/collection:TeamProjectCollectionUrl]

Versionspec:
Date/Time         D"any .Net Framework-supported format"
or any of the date formats of the local machine
Changeset number  Cnnnnnn
Label             Llabelname
Latest version    T
Workspace         Wworkspacename;workspaceowner

To run the command, you have to specify the collection URL. An easy way to get this is open your Team Explorer window in Visual Studio (View > Team Explorer), select the root server node and look in the Properties window at the Url property.

Now you need the server name of the folder or file you want to purge. Locate the file or folder in the Source Control Explorer, right click and choose Properties…

The Server Name: value is what you want and can be selected and copied to the clipboard.

Now you can run the command:

tf destroy $/MyProject/Main/Bin /collection:http://servername:8080/tfs/myproject
Do you want to destroy $/MyProject/Main/Bin and all of its children? (Yes/No) y
Destroyed: $/MyProject/Main/Bin;X3601
Destroyed: $/MyProject/Main/Bin/Native;X3601

Now if you refresh in Solution Explorer, the purged items won’t even show up anymore.

Manually schedule a disk check at next restart

You can schedule a chkdsk at reboot time for a drive by using the Windows command line utility fsutil.

You do this by setting the “dirty” flag for a drive, which marks the drive for a chkdsk when you next reboot.

Usage:

fsutil dirty query <volume pathname>

e.g.

fsutil dirty set C:

You can check if a drive has been marked as dirty by using the query command:

fsutil dirty query <volume pathname>

Debugging MSBuild scripts

If you want to debug an MSBuild script from without Visual Studio, you need to use the /debug command line option.

The trick is that this option is not normally available; you need to set a registry key to enable it.

Enable the MSBuild Debugger

Under the HKLM\Software\Microsoft\MSBuild\4.0 key, create a string value called EnableDebugger with a value of “true”.

If you’re on a 64 bit system, you’ll also want to set the same value under the key HKLM\Software\Wow6432Node\Microsoft\MSBuild\4.0.

Verify

If you then run msbuild /help, you should now see the documentation on the /debug switch:

/debug
                    Causes a debugger prompt to appear immediately so that
                    Visual Studio can be attached for you to debug the
                    MSBuild XML and any tasks and loggers it uses.

Debugging

Now you can pass the /debug option to MSBuild when running it. This will immediately break into the debugger, which will usually give you a prompt to select your JIT debugger:

image

The debug session will then start at the very top of the root MSBuild project file, and you can go from there.

You can set breakpoints in your MSBuild project files from within the IDE, and inspect the MSBuild variables using Locals and Watch.

Some more tips:

  • Your breakpoints may not show up to be hit yet until the project file they’re contained in actually loads. If you continue on, the project will get loaded and the breakpoint will get hit.
  • To prevent yourself breaking into framework code that you don’t have source for, you can check the Enable Just My Code (Managed only) option under Debug > Options and Settings > Debugging > General.
  • From the Immediate window to evaluate conditions using EvaluateCondition:
Immediate input: EvaluateCondition("'$(MyProperty)' == ''")
Immediate output: false
  • From the Immediate window you can evaluate expressions using EvaluateExpression (remember to escape slashes):
Immediate input: EvaluateExpression("C:\\$(MyFolderName)")
Immediate output: C:\MyFolder

Original article and full details (recommended reading) is here: http://blogs.msdn.com/b/visualstudio/archive/2010/07/06/debugging-msbuild-script-with-visual-studio.aspx

Generating a type library for Visual Basic 6 ActiveX Components

When generating setup code or isolation code (for Side by Side assemblies and Registration-free COM), VB6 ActiveX Components can be a little troublesome.

ActiveX exes in particular can be difficult, with the WiX heat tool and various SxS tools not being able to harvest COM registration information from them properly.

A good way of avoiding these problems is to generate a type library (.tlb) from the VB6 component, and then pointing the code generation tools at the type library.

In VB6, you can generate a Type Library (.tlb) file for an ActiveX component:

  1. Project > <Project Name> Properties…
  2. Go to the Component tab
  3. Check Remote Server Files
  4. Click OK and build the project

image

You should now see a .tlb and .vbr file next to your binary.

The .vbr file is a text file containing registry information, which will be very helpful if the type library is still missing information you want to use for your isolation or installation authoring.

Reference

How To Make a Typelib (.TLB) File for ActiveX Components @ MSDN

When System.Diagnostics.Process creates a process, it inherits inheritable handles from the parent process.

This post covers the cause of a bug I ran into at work.

Our application would check for available updates when it started, and if they were found, it would launch the installer directly and exit the application immediately, so that the installer could run without encountering file locks.

The installer was complaining our executable was still locked, meaning it had to schedule the overwrite of the old file with the new one after a reboot.

After quite a bit of troubleshooting, it looked like while the application was launching msiexec and closing down successfully, msiexec was still grabbing the same lock handle to the exe for no good reason.

So what was happening?

System.Diagnostics.Process

When you create a new process from a .NET application, you would use the classes in the System.Diagnostics namespace. Specifically, Process and ProcessStartInfo. As we were in this case.

These wrap the Windows API function CreateProcess and its alternatives and supporting types.

If we look at the CreateProcess definition, there’s a boolean argument in there called bInheritHandles:

BOOL WINAPI CreateProcess(
__in_opt     LPCTSTR lpApplicationName,
__inout_opt  LPTSTR lpCommandLine,
__in_opt     LPSECURITY_ATTRIBUTES lpProcessAttributes,
__in_opt     LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in         BOOL bInheritHandles,
__in         DWORD dwCreationFlags,
__in_opt     LPVOID lpEnvironment,
__in_opt     LPCTSTR lpCurrentDirectory,
__in         LPSTARTUPINFO lpStartupInfo,
__out        LPPROCESS_INFORMATION lpProcessInformation
);

What does the Windows API documentation say about this?

If this parameter is TRUE, each inheritable handle in the calling process is inherited by the new process. If the parameter is FALSE, the handles are not inherited. Note that inherited handles have the same value and access rights as the original handles.

Inheritable handles?

Handle Inheritance

A child process can inherit handles from its parent process. An inherited handle is valid only in the context of the child process. To enable a child process to inherit open handles from its parent process, use the following steps.

  1. Create the handle with the bInheritHandle member of the SECURITY_ATTRIBUTES structure set to TRUE.
  2. Create the child process using the CreateProcess function, with the bInheritHandles parameter set to TRUE.

Well if we look at the internals of .NET, and look at how the Process class is calling CreateProcess, we find that it’s passing bInheritHandles as TRUE.

So this means if we start a process using the System.Diagnostics classes, the child process will inherit our inheritable handles.

What was happening is the locked file handle to wsClient.exe was being inherited from the parent process to the Windows Installer, so the executable was remaining locked even when the parent process exited.

Solution

One solution is to avoid System.Diagnostics in this particular instance, and use CreateProcess manually when we launch our child process, to ensure it doesn’t inherit handles.

I would recommend you use the System.Diagnostics classes in any other case.

Code

using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using Microsoft.Win32.SafeHandles;

namespace CreateProcessTest
{
    [StructLayout(LayoutKind.Sequential)]
    internal class ProcessInformation
    {
         public IntPtr hProcess = IntPtr.Zero;
         public IntPtr hThread = IntPtr.Zero;
         public int dwProcessId;
         public int dwThreadId;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal class StartupInfo
    {
         public int cb;
         public IntPtr lpReserved = IntPtr.Zero;
         public IntPtr lpDesktop = IntPtr.Zero;
         public IntPtr lpTitle = IntPtr.Zero;
         public int dwX;
         public int dwY;
         public int dwXSize;
         public int dwYSize;
         public int dwXCountChars;
         public int dwYCountChars;
         public int dwFillAttribute;
         public int dwFlags;
         public short wShowWindow;
         public short cbReserved2;
         public IntPtr lpReserved2 = IntPtr.Zero;
         public SafeFileHandle hStdInput = new SafeFileHandle(IntPtr.Zero, false);
         public SafeFileHandle hStdOutput = new SafeFileHandle(IntPtr.Zero, false);
         public SafeFileHandle hStdError = new SafeFileHandle(IntPtr.Zero, false);

         public StartupInfo()
         {
             dwY = 0;
             cb = Marshal.SizeOf(this);
         }

         public void Dispose()
         {
             // close the handles created for child process
             if (hStdInput != null && !hStdInput.IsInvalid)
             {
                 hStdInput.Close();
                 hStdInput = null;
             }

             if (hStdOutput != null && !hStdOutput.IsInvalid)
             {
                 hStdOutput.Close();
                 hStdOutput = null;
             }

             if (hStdError == null || hStdError.IsInvalid) return;

             hStdError.Close();
             hStdError = null;
         }
     }

     [StructLayout(LayoutKind.Sequential)]
     internal class SecurityAttributes
     {
         public int nLength = 12;
         public SafeLocalMemHandle lpSecurityDescriptor = new SafeLocalMemHandle(IntPtr.Zero, false);
         public bool bInheritHandle;
     }

     [SuppressUnmanagedCodeSecurity, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)]
     internal sealed class SafeLocalMemHandle : SafeHandleZeroOrMinusOneIsInvalid
     {
         internal SafeLocalMemHandle() : base(true) { }

         [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
         internal SafeLocalMemHandle(IntPtr existingHandle, bool ownsHandle) : base(ownsHandle)
         {
             SetHandle(existingHandle);
         }

         [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
         internal static extern bool ConvertStringSecurityDescriptorToSecurityDescriptor(string stringSecurityDescriptor,
             int stringSDRevision, out SafeLocalMemHandle pSecurityDescriptor, IntPtr securityDescriptorSize);

         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), DllImport("kernel32.dll")]
         private static extern IntPtr LocalFree(IntPtr hMem);

         protected override bool ReleaseHandle()
         {
             return (LocalFree(handle) == IntPtr.Zero);
         }
     }

     public static class Test
     {
         const int normalPriorityClass = 0x0020;

         [DllImport("Kernel32", CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false)]
         internal static extern bool CreateProcess(
             [MarshalAs(UnmanagedType.LPTStr)]string applicationName,
             StringBuilder commandLine,
             SecurityAttributes processAttributes,
             SecurityAttributes threadAttributes,
             bool inheritHandles,
             int creationFlags,
             IntPtr environment,
             [MarshalAs(UnmanagedType.LPTStr)]string currentDirectory,
             StartupInfo startupInfo,
             ProcessInformation processInformation
        );

        public static void Main(string[] args)
        {
            // We can use the string builder to build up our full command line, including arguments
            var sb = new StringBuilder("notepad.exe");
            var processInformation = new ProcessInformation();
            var startupInfo = new StartupInfo();
            var processSecurity = new SecurityAttributes();
            var threadSecurity = new SecurityAttributes();

            processSecurity.nLength = Marshal.SizeOf(processSecurity);
            threadSecurity.nLength = Marshal.SizeOf(threadSecurity);

            if (CreateProcess(null, sb, processSecurity, threadSecurity, false, normalPriorityClass,
                 IntPtr.Zero, null, startupInfo, processInformation))
            {
                // Process was created successfully
                return;
            }

            // We couldn't create the process, so raise an exception with the details.
            throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
         }
     }
}

Utilities

I used the invaluable SysInternals tools Process Monitor, Process Explorer and Handle to diagnose what was going on.

References

Handle Inheritance @ MSDN

Child process keeps parent’s socket open – Diagnostics.Process and Net.TcpListene @ social.msdn.microsoft.com

.NET Decompilers

Reflector history

The de facto .NET decompiler has been Reflector for what seems like forever.

Reflector was originally developed by Lutz Roeder, and made freely available to the community.

It was acquired by Red Gate Software in August 2008, who promised to maintain it as a free product.

They reneged on this promise in February 2011, stating that Reflector would become a commercial product.

This created a community backlash, culminating in creation and/or promotion of several free rival products through open source or offered by other vendors.

Red Gate backpedalled in April 2011 by saying that the final 6.8 version of Reflector would continue to be free, while future releases of Reflector (moving forward with version 7.x) would be paid for.

List of .NET Decompilers

Name Company License Language Support Rating Comments
ILSpy SharpDevelop Open Source C# 4 except for expression trees, dynamic, fixed fields   ILSpy development was started directly as a result of Red Gate’s announcement that Reflector would be paid for.
CodeReflect DevExtras Free (Commercially supported) MSIL, C#, VB.NET    
JustDecompile Telerik Free (Commerically supported)      
dotPeek JetBrains Free (Commercially supported) C#    
Reflector 6.8 Red Gate Free MSIL, C#, VB.NET, more through plugins   Any future versions (7.x) are paid for. You need to be an existing Reflector user, and allow your Reflector to update to version 6.8.

How to check if the current user is an Administrator (even if UAC is on)

There may be a scenario where you want to determine from code if the current user is an Administrator.

One example of this which I have had to deal with is checking for software updates.

Say your application contacts a service to see if there is a newer version of the application available; if so, you can download and run the installer.

Imagine that the installer requires admin privileges; you don’t want to run the installer if the current user does not have administrative privileges.

So how can we check if the user is an admin or not?

In VB6, C++ etc

There is a Windows API function you can use very easily to see if the current user is an admin: IsUserAnAdmin.

BOOL IsUserAnAdmin(void);

Visual Basic 6 Declaration

Private Declare Function IsUserAnAdmin Lib “Shell32″ Alias “#680″ () As Integer

While you can still use this, it is actually deprecated, and the documentation recommends you call the CheckTokenMembership function instead (which IsUserAnAdmin is a wrapper for).

.NET

C#.NET

using System;
using System.Security.Principal;

var identity = WindowsIdentity.GetCurrent();
if (identity == null) throw new InvalidOperationException("Couldn't get the current user identity");
var principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);

User Account Control (UAC)

A problem arises when you use any of the above code on a machine that has UAC enabled, and the process is not elevated.

While the user may be an administrator, when the process is not elevated yet, the user has a split token – which doesn’t have the administrator privileges.

A way around this is to use the GetTokenInformation API call to inspect the token to see if it’s a split token. In most cases this will mean that UAC is on and the current user is an administrator.

This is not 100% reliable (see References) but it’s probably the best we can do for now.

C#.NET

This code is slightly easier in .NET, as there’s already a fair amount of code we don’t have to write to get the current process’s token.

First, we’ll need some code to support the GetTokenInformation API call:

[DllImport("advapi32.dll", SetLastError = true)]
static extern bool GetTokenInformation(IntPtr tokenHandle, TokenInformationClass tokenInformationClass, IntPtr tokenInformation, int tokenInformationLength, out int returnLength);

/// <summary>
/// Passed to <see cref="GetTokenInformation"/> to specify what
/// information about the token to return.
/// </summary>
enum TokenInformationClass
{
     TokenUser = 1,
     TokenGroups,
     TokenPrivileges,
     TokenOwner,
     TokenPrimaryGroup,
     TokenDefaultDacl,
     TokenSource,
     TokenType,
     TokenImpersonationLevel,
     TokenStatistics,
     TokenRestrictedSids,
     TokenSessionId,
     TokenGroupsAndPrivileges,
     TokenSessionReference,
     TokenSandBoxInert,
     TokenAuditPolicy,
     TokenOrigin,
     TokenElevationType,
     TokenLinkedToken,
     TokenElevation,
     TokenHasRestrictions,
     TokenAccessInformation,
     TokenVirtualizationAllowed,
     TokenVirtualizationEnabled,
     TokenIntegrityLevel,
     TokenUiAccess,
     TokenMandatoryPolicy,
     TokenLogonSid,
     MaxTokenInfoClass
}

/// <summary>
/// The elevation type for a user token.
/// </summary>
enum TokenElevationType
{
    TokenElevationTypeDefault = 1,
    TokenElevationTypeFull,
    TokenElevationTypeLimited
}

Then, the actual code to detect if the user is an Administrator (returning true if they are, otherwise false).

var identity = WindowsIdentity.GetCurrent();
if (identity == null) throw new InvalidOperationException("Couldn't get the current user identity");
var principal = new WindowsPrincipal(identity);

// Check if this user has the Administrator role. If they do, return immediately.
// If UAC is on, and the process is not elevated, then this will actually return false.
if (principal.IsInRole(WindowsBuiltInRole.Administrator)) return true;

// If we're not running in Vista onwards, we don't have to worry about checking for UAC.
if (Environment.OSVersion.Platform != PlatformID.Win32NT || Environment.OSVersion.Version.Major < 6)
{
     // Operating system does not support UAC; skipping elevation check.
     return false;
}

int tokenInfLength = Marshal.SizeOf(typeof(int));
IntPtr tokenInformation = Marshal.AllocHGlobal(tokenInfLength);

try
{
    var token = identity.Token;
    var result = GetTokenInformation(token, TokenInformationClass.TokenElevationType, tokenInformation, tokenInfLength, out tokenInfLength);

    if (!result)
    {
        var exception = Marshal.GetExceptionForHR( Marshal.GetHRForLastWin32Error() );
        throw new InvalidOperationException("Couldn't get token information", exception);
    }

    var elevationType = (TokenElevationType)Marshal.ReadInt32(tokenInformation);
    
    switch (elevationType)
    {
        case TokenElevationType.TokenElevationTypeDefault:
            // TokenElevationTypeDefault - User is not using a split token, so they cannot elevate.
            return false;
        case TokenElevationType.TokenElevationTypeFull:
            // TokenElevationTypeFull - User has a split token, and the process is running elevated. Assuming they're an administrator.
            return true;
        case TokenElevationType.TokenElevationTypeLimited:
            // TokenElevationTypeLimited - User has a split token, but the process is not running elevated. Assuming they're an administrator.
            return true;
        default:
            // Unknown token elevation type.
            return false;
     }
}
finally
{    
    if (tokenInformation != IntPtr.Zero) Marshal.FreeHGlobal(tokenInformation);
}

Visual Basic 6 (VB6)

For Visual Basic 6, there’s some additional code, as we need to get the token for the current process, and use more calls to also get the operating system version.

Type OSVERSIONINFO

dwOSVersionInfoSize As Long

dwMajorVersion As Long

dwMinorVersion As Long

dwBuildNumber As Long

dwPlatformId As Long

szCSDVersion As String * 128

End Type

‘ dwPlatformId values

Public Const VER_PLATFORM_WIN32s = 0

Public Const VER_PLATFORM_WIN32_WINDOWS = 1

Public Const VER_PLATFORM_WIN32_NT = 2

Public Declare Function GetVersionEx Lib “kernel32″ Alias “GetVersionExA” (ByRef lpVersionInformation As OSVERSIONINFO) As Long

‘ These functions are for getting the process token information, which IsUserAnAdministrator uses to

‘ handle detecting an administrator that’s running in a non-elevated process under UAC.

Private Const TOKEN_READ As Long = &H20008

Private Const TOKEN_ELEVATION_TYPE As Long = 18

Private Declare Function IsUserAnAdmin Lib “Shell32″ Alias “#680″ () As Integer

Private Declare Function CloseHandle Lib “kernel32″ (ByVal hObject As Long) As Long

Private Declare Function OpenProcessToken Lib “advapi32.dll” (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long

Private Declare Function GetTokenInformation Lib “advapi32.dll” (ByVal TokenHandle As Long, ByVal TokenInformationClass As Long, TokenInformation As Any,_ ByVal TokenInformationLength As Long, ReturnLength As Long) As Long

Public Function IsUserAnAdministrator() As Boolean

On Error GoTo IsUserAnAdministratorError

IsUserAnAdministrator = False

If IsUserAnAdmin() Then

IsUserAnAdministrator = True

Exit Function

End If

‘ If we’re on Vista onwards, check for UAC elevation token

‘ as we may be an admin but we’re not elevated yet, so the

‘ IsUserAnAdmin() function will return false

Dim osVersion As OSVERSIONINFO

osVersion.dwOSVersionInfoSize = Len(osVersion)

If GetVersionEx(osVersion) = 0 Then

Exit Function

End If

If osVersion.dwPlatformId <> VER_PLATFORM_WIN32_NT Or osVersion.dwMajorVersion < 6 Then

‘ If the user is not on Vista or greater, then there’s no UAC, so don’t bother checking.

Exit Function

End If

Dim result As Long

Dim hProcessID As Long

Dim hToken As Long

Dim lReturnLength As Long

Dim tokenElevationType As Long

‘ We need to get the token for the current process

hProcessID = GetCurrentProcess()

If hProcessID <> 0 Then

If OpenProcessToken(hProcessID, TOKEN_READ, hToken) = 1 Then

result = GetTokenInformation(hToken, TOKEN_ELEVATION_TYPE, tokenElevationType, 4, lReturnLength)

If result = 0 Then

‘ Couldn’t get token information

Exit Function

End If

If tokenElevationType <> 1 Then

IsUserAnAdministrator = True

End If

CloseHandle hToken

End If

CloseHandle hProcessID

End If

Exit Function

IsUserAnAdministratorError:

‘ Handle errors

End Function

References

Blog Post by Chris Jackson: How to Determine if a User is a Member of the Administrators Group with UAC Enabled on Windows Vista

Error building project when referencing native assembly dependency in app.manifest

If you’re using an app.manifest, and defining assembly dependencies (i.e. for SxS / Side by side / Reg-free COM etc), you may encounter this error when you build the project:

Could not find file ‘AssemblyName, Version=x.x.x.x, PublicKeyToken=xxxxxxxxxxx, ProcessorArchitecture=x86, Type=win32′.

This is even when the native assembly is in place where the project can find it.

Example

For example, your app.manifest may contain this fragment:

<dependency>
<dependentAssembly>
<assemblyIdentity name=Native.Custom version=1.0.0.0 processorArchitecture=x86 type=win32 publicKeyToken=12345678/>
</dependentAssembly>
</dependency>

This manifest is available to the project, with the manifest file in the project directory or in a subdirectory called “Native.Custom”.

In this case, I have a sub directory called Native.Custom, which contains my Native.Custom.manifest file.

Solution

The problem may be because the ClickOnce manifests are being generated.

  1. Open your project file in a text editor (or right click it in Visual Studio and choose Edit Project)
  2. Find the  GenerateManifests element and set it to false:
  3. <GenerateManifests>false</GenerateManifests>
  4. Save the project and reload it.

Now you should hopefully be able to build.