How to change a project’s source control from SourceSafe to TFS

  • This article does not cover how to migrate your SourceSafe database to TFS.
  • This article is intended to only describe how to migrate a project’s source control from SourceSafe to TFS.
  • This article assumes you have already successfully migrated your SourceSafe database to TFS, the project’s source control is currently SourceSafe, and you have a working TFS server or a working visualstudio.com account (aka visual studio online).
  • FYI: visualstudio.com hosts a TFS (team foundation as a service) that is free to use for up to 5 users. Very nice! Check it out.
  • I have wasted a lot of time trying to figure out how to properly migrate a project’s source control from SourceSafe to TFS. There is no completely correct way to do it.
  • What I provide in the post is a method I use, and have used many times now, that seems to be the most reliable method. There may be better ways of accomplishing the same thing, with less steps.
  • The instructions as listed below seem to work for me. Whenever I forget a step, or do things out of order, there always seems to be problems.
  • So I suggest you follow these instructions exactly as listed below at least once, see if it works for you, then maybe you can come up with a better way.
  • If you find a better way, please let me know so I can update this to better help other people.

Visual Studio 2010/2012/2013:

  • Launch Visual Studio.
  • Go to Tools, Options, Source Control.
  • Change the source control plug-in to “Visual Studio Team Foundation Server”.
  • Open the “Team Explorer” panel (View, Team Explorer).
  • If you have not already done so for another project, click the “Connect to Team Project” icon, and enter your TFS server url, username, password, and select the desired team project collection and root team project(s), then click Connect.
  • Double-click “Source Control” within the desired project in the Team Explorer panel.
  • If you have not already done so for another project, right-click the topmost element in the sources tree, select “Set Mapping” and selected the desired local folder. Choose wisely, its a pain in the ass to change it later.
  • Navigate to the desired project’s path in the Source Control Explorer.
  • Right-click, select Get Latest Version. This is important! You cannot check out files in a project unless you have the latest version of the files using the “get latest version” command.
  • Resolve all conflicts.
  • Select and right-click the .sln and .vcxproj files, select “Check Out for Edit”.
  • Navigate using Windows Explorer to the project’s path and delete the “mssccprj.scc” file. This is important! If you do not delete this file, then Visual Studio will always set the project’s source control back to SourceSafe whenever you open the project.
  • Double-click the .sln file in Windows Explorer or in Source Control Explorer.
  • Dismiss the error about the missing mssccprj.scc file.
  • Most likely you will get a message about incorrect source control bindings. Select the option to “temporarily work offline”. If you don’t have this option, then you can choose the option to “permanently remove source control bindings”, but then the following directions may not match exactly.
  • Go to Tools, Options, Source Control.
  • Change the source control plug-in to “Visual Studio Team Foundation Server”. This is important! Most likely Visual Studio changed it to “none” or back to SourceSafe in an attempt to match the project’s current source control bindings which is still SourceSafe.
  • Go to File, Source Control, Change Source Control.
  • Select the solution and click Bind.
  • Select the project and click Bind.
  • Go to the Team Explorer panel, double-click Source Control.
  • Select and right-click the .sln and .vcxproj files, select “Check In Pending Changes”. This is important! If you don’t check in the files now, you may have to go through these entire steps all over again. I’ve had to go through this many times. Trust me. Check the files in now!
  • Make sure you click “Check In” on the right side panel to commit the changes.
  • There should not be any conflicts. If you get any conflicts then you’ve done something wrong. You will have to compare the files and use some common sense. Most likely you will want to overwrite the sever version with the local version (keep the local version).
  • You’re welcome!

Instructions for Visual Studio 2005 coming soon!

 

 

How to recursively purge deleted items in SourceSafe

  • Microsoft’s KB article:  How to Reduce the Size of a Visual SourceSafe Database incorrectly says to use this command:
  • ss purge %/ -r (this will not work)
  • It also suggests using “VSSEMS” which seems to be non-existent. The link goes to the author’s personal blog which no longer exists. Good luck finding a legit download.
  • Here are the correct instructions (use at your own risk):
  • Make a backup of your entire SourceSafe files.
  • Make a backup of your entire SourceSafe files.
  • Make a backup of your entire SourceSafe files.
  • Did you make a backup? Just FYI: the first time I tried this it actually deleted everything, not sure why. Everything! Get it? All the projects folders were still there but they were all empty folders with no files. All the files were missing. Make a backup.
  • Open a command prompt.
  • Change directory to your SourceSafe installation path (example: cd “program files (x86)\microsoft visual sourcesafe”)
  • Run the analyze tool:
  • analyze -F -V3 -D -C “path-to-folder-containing-srcsafe.ini”
  • If you get any errors run it again.
  • Set “SSDIR” environment variable to your srcsafe.ini path (example: set SSDIR=e:\dev\sourcesafe\msdev60\database)
  • ss purge -r %/*
  • Enjoy!

 

 

How to not step into functions using the Visual Studio 2013 debugger

  • If you are using Visual Studio versions prior to 2012, this information is already documented here: How to Not Step Into Functions using the Visual C++ Debugger
  • Visual Studio 2012/2013 no longer use the “/NativeDE/StepOver” registry key, they use “natstepfilter” files.
  • As of 4/1/2014, there is no official documentation about using the natstepfilter files that I can find.
  • The default natstepfilter file is located here:
  • C:\Program Files[ (x86)]\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\default.natstepfilter
  • If you want to not step into a specific function, operator, etc, while debugging, you can add specific information to this file.
  • This feature only works for native code. It works with “debugger type” set to “auto”, as long a the code your are debugging is native C++.
  • Here is an example of how to not step into any CString functions (add this inside the <StepFilter> block):

<Function><Name>ATL::CStringT.*</Name><Action>NoStepInto</Action></Function>

  • More examples coming soon!

How to remove all elements from a std::queue

  • Unlike std::vector, std::queue does not have a clear() function.
  • Here is an easy way to remove all the elements from a queue:
while( !queue.empty() )
{
  queue.pop();
};

Debugging with UIAccess=true

  • If you attempt to debug an application which an app manifest with UIAccess=true, you may receive the following error:

Unable to start program [Application].

The application manifest has the uiAccess attribute set to ‘true’.
Running an Accessibility application requires following the steps
described in Help.

[OK] [Help]

  • Clicking [Help] goes to an non-existent webpage.

Solution:

  • Set Visual Studio to run as administrator (right-click the VS shortcut, select properties, compatibility tab, and check run as administrator).
  • If you are using remote debugging, also set the Visual Studio Remote Debugger to run as administrator.

Automatically insert/update filename, date, revision number in source files (using Source Safe)

  • If you use Source Safe, you can add auto-updating fields inside comments to your source files so that whenever you check-in/check-out your files, Source Safe will automatically update those fields in your source files.
  • This is useful for reference purposes, or when doing file-content searches for specific criteria. This cannot be used for updating preprocessor defines, or anything useful during compile time.
  • There are probably a lot of other fields, but these are the ones that I use:
$Workfile: $
$Date: $
$Revision: $
$Author: $
  • Just add those fields inside a comment anywhere in your source files.
  • Whenever you check-in/check-out the file, Source Safe will insert/update the fields.
  • You will end up with something like this:

/*

$Workfile: DoStuff.h $

$Date: 4/25/13 4:47p $

$Revision: 65 $

$Author: Ed $

*/

Everything vs Agent Ransack vs SearchMyFiles vs File Finder

  • This is not a performance/benchmark comparison.
  • I have been looking for the ultimate 3rd party search tool. I have tried Everything, Agent Ransack, SearchMyFiles, and File Finder.
  • Some of these search tools are a great alternative to using Windows Search, however, some are much better than the others.
  • In my opinion, a useful 3rd party search tool must have the following features:
  • search for files by filename.
  • search for files by file content.
  • limit the scope of the search to a specific folder (including all sub-folders).
  • limit the scope of the search to specific file types, for example, search for *.h and *.cpp files containing the text “hello”.
  • search within Microsoft Office file content (this may require an iFilter plugin, thats acceptable).
  • search within PDF file content (this may require an iFilter plugin, thats acceptable).
  • a nice, clean, and well organized UI.
  • if searching for file content, it should showing a portion of the content where the matching criteria is found.
  • the user should not have to read a farking manual or learn regular expressions to figure out how to use any of the above mentioned features.
  • and last but not least, it needs to be FAST!
  • If you don’t want to read the entire article then use Agent Ransack, its the best.

Agent Ransack (highly recommended):

  • Link (download and install and use at your own risk): http://www.mythicsoft.com/agentransack
  • search by filename = yes
  • search for file content = yes
  • limit scope to specific folder = yes. Also, subfolders are optional, and you can select multiple folders.
  • limit scope to specific file types = yes
  • search within Office files = yes (worked without any iFilter plugin)
  • search within PDF files = yes (worked without any iFilter plugin)
  • intuitive UI = yes
  • shows portion of found file content = yes. You have to select the search result item, and it displays a portion in the bottom right corner of the window
  • fast = yes
  • too many options = no
  • too few options = no
  • Conclusion: its very fast, searches by filename and file content, searches within Office and PDF files. Very good!

SearchMyFiles (partially recommended):

  • Link (download and install and use at your own risk): http://www.nirsoft.net/utils/search_my_files.html
  • search by filename = yes
  • search for file content = yes
  • limit scope to specific folder = yes. Also, subfolders are optional, and you can select multiple folders
  • limit scope to specific file types = yes
  • search within Office files = yes (worked without any iFilter plugin)
  • search within PDF files = no (still did not work even after installing the iFilter plugin)
  • intuitive UI = yes
  • shows portion of found file content = yes. A portion is displayed with each search result
  • fast = yes
  • too many options = yes. The initial search window is very cluttered
  • too few options = no
  • Conclusion: its very fast, searches by filename and file content, searches within Office documents but not PDF files. Very good, but Agent Ransack is better.

File Finder (partially recommended):

  • Link (download and install and use at your own risk): http://www.mcrenox.com.ar/filefinder/
  • search by filename = yes
  • search for file content = yes
  • limit scope to specific folder = yes
  • limit scope to specific file types = yes
  • search within Office files = no (still did not work even after installing the iFilter plugin)
  • search within PDF files = no (still did not work even after installing the iFilter plugin)
  • intuitive UI = yes
  • shows portion of found file content = no
  • fast = yes. Its the only 3rd party search tool that I know of that specifically mentions that its multi-threaded. It is very fast at searching for filenames. It has been my experience that the search results appear almost instantaneously after clicking search
  • too many options = no
  • too few options = yes. It does not remember the selected folder, filespec, or file content keywords between instances
  • Conclusion: its very fast, searches by filename and file content, but does not search within Office documents nor PDF files. Except for Everything, its faster than all the others at searching by filenames.
  • I still partially recommend this app even though it has some issues. I like the fact that its almost as fast as Everything but does not index my files. I like the fast that its multi-threaded, although I’m not sure if that causes any extra wear and tear to the harddrives. Overall it seems to be a very well designed app that just needs a few minor fixes.

Everything (partially recommended):

  • Link (download and install and use at your own risk): http://www.voidtools.com/
  • search by filename = yes
  • search for file content = no
  • limit scope to specific folder = yes, but the usage is not very intuitive. I had to read the FAQ to figoure it out
  • limit the scope to specific file types = yes, but the usage is not very intuitive. I had to read the FAQ to figure it out
  • search within Office files = no
  • search within PDF files = no
  • intuitive UI = no (the usage for some features in explained in the FAQ and there is absolutely nothing in the UI to hint about how to use it)
  • shows portion of found file content = no
  • fast = YES!!! It is very fast. It has been my experience that the search results are sometimes displayed as I type
  • too many options = no
  • too few options = yes
  • Conclusion: it doesn’t search for file content, so in my opinion its useless. The UI sucks, all you get is 1 editbox to enter the search criteria. There is nothing intuitive about it. However, if you just want to search by filename it is very fast.
  • I still partially recommend this app only because it is very fast at searching for filenames, but thats it. If you want to do anything else then don’t waste your time with this one.

Conclusion:

  • If you are looking for a 3rd party search tool to replace use of Windows Search, to search by either filenames or file content, then I recommend Agent Ransack or SearchMyFiles.
  • Agent Ransack has less options than SearchMyFiles but the UI is much cleaner and more intuitive.
  • SearchMyFiles has more options than any of the others, but the initial window where you type in your search criteria has all the options on it, its cluttered, and in my opinion overly complicated for any non-super-user. SearchMyFiles does not search within PDF files, even with the iFilter plugin.
  • So if you want simple then use Agent Ransack. If you want every conceivable search option and don’t care how overly complicated the UI is, then use SearchMyFiles.
  • File Finder also does very well at searching by file content, however it does not search within Office documents nor PDF files, even with the iFilter plugins.
  • If all you care about is searching for filenames, then I would recommend Everything or File Finder.
  • Everything is fast because it indexes the files.
  • File Finder is fast because its multi-threaded.
  • In my opinion, File Finder is much better than Everything, however that is just from my own personal tastes. I like the File Finder UI much better, and even though it has some issues I like the fact that it produces almost instantaneous search results without having to index my files.

TODO:

CStatic::SetBitmap not redrawing correctly

  • If you add a “Picture Control” to a dialog in the resource editor, you can specify a bitmap to automatically load in the control’s properties.
  • If you create a control variable for this “Picture Control”, you get a CStatic variable.
  • You can set or change the bitmap at runtime using CStatic::SetBitmap.
  • If the specified HBITMAP has local scope, the picture control will not update, you will usually get a white rectangle instead of the bitmap image.
  • The supplied HBITMAP must have class or global scope. Or more correctly, the HBITMAP value which is passed to SetBitmap must be valid for the lifetime of the CStatic control object (which means the HBITMAP must be valid for the lifetime of the control’s parent window).
  • The suggested way to use SetBitamp is to supply a dialog’s class member CBitmap.
  • For example:
// class member variables:
CBitmap mLogoBmp;
CStatic mPictureControl;
// to update the picture control's bitmap image:
if( mLogoBmp.m_hObject == 0 && mLogoBmp.LoadBitmap( IDB_X ) )
{
  mPictureControl.SetBitmap( mLogoBmp );
}

Force program X to run instead of program Y

  • A common question is how do I automatically force program X to run instead of program Y when I launch program Y?
  • This is easy using a old registry trick that’s been around since Windows NT. Some viruses would use this feature, so it became common for antivirus software to hook this activity and block it. That’s old school. I’ve never heard of any modern antivirus software blocking this activity.
  • Here is a useful example:
  • If you want to launch Visual Studio 2010 and have it automatically use the batch file whenever it launches, follow the steps below:
  • Browse to C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE.
  • Make a copy devenv.exe, and rename the new copy to devenv2010.exe. I use this method of copying the exe to a new name, so that the original file stays intact. I had problems whenever I tried to rename the original devenv.exe.
  • Make a copy of devenv.exe.config, and rename the new copy to devenv2010.exe.config.
  • Launch Regedit.
  • Navigate to HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options.
  • Right-click the Image File Execution Options key and select New Key.
  • Name the key devenv2010.exe.
  • Right-click the devenv2010.exe key and select New String Value.
  • Set the string item’s name to debugger.
  • Set the string item’s value to the full file-path-name of your batch file.
  • Update all your Visual Studio 2010 shortcuts to target the devenv2010.exe, instead of devenv.exe. If the shortcut is pinned to the taskbar or start menu, use shift-right-click to select properties.
  • Now whenever you click your desktop or pinned Visual Studio 2010 shortcuts it will launch with the batch file instead. You can then setup temporary environment variables in the batch file and launch visual studio.
  • This is not re-enterant. For example, if launch the batch file, and the batch file launches visual studio, and the batch file is setup as an exe alias to visual studio, it will not re-launch the batch file again, it will launch visual studio.
  • This does not apply if you open an SLN file. If you open an SLN file directly, it will launch Visual Studio directly. This only applies if you launch the Visual Studio exe.

When I use CFile::Write, only one character is written

CFile myFile( hFile ); // attach a CFile object to the handle we have
static const TCHAR sz[20] = _T("Hockey is best!\r\n");
myFile.Write( sz, strlen( sz ) );
  • Assume the project is being compiled with character-set set to Unicode.
  • The biggest error is in this line: myFile.Write( sz, strlen( sz ) );
  •  sz is a TCHAR*, but strlen is an ANSI function expecting a char* not a TCHAR*.
  • The resulting length returned by strlen( sz ) will be 1, because sz is storing Unicode characters, so the character at sz[1] is zero (char value of zero, not ASCII ’0′) because Unicode characters are 2-byte.
  • CFile::Write does not know anything about strings, it handles raw bytes. So you do not want to pass the number of characters, you want to pass the number of bytes.
  • For example, the string literal “Hockey is best!\r\n” is 18 characters (including the terminating zero char) regardless if its a Unicode or ANSI string, however, if its a Unicode string it contains 26 bytes, if its an ANSI string it contains 18 bytes.
  • The correction is to use the _tcslen( sz ) * sizeof( TCHAR ) instead of strlen.
CFile myFile( hFile ); // attach a CFile object to the handle we have
static const TCHAR sz[20] = _T("Hockey is best!\r\n");
myFile.Write( sz, _tcslen( sz ) * sizeof( TCHAR ) ); // use number of bytes
  • If you open it in some text viewers, you will only see “H” instead of “Hockey is best!”
  • This is most likely caused by the fact that you are creating a binary file, filling it with Unicode characters, and not including a BOM (byte order mark).
  • Files without a BOM are expected to contain ANSI characters.
  • Files containing Unicode characters *REQUIRE* a BOM.
  • If you attempt to open this file in a text viewer, how is it supposed to know if the file’s content is ANSI or Unicode? Should it assume because the 2nd byte is a zero that its Unicode? That is not correct.
  • The biggest error now is that the file is being populated with Unicode characters but does not contain a BOM.
  • The correction is to either use a class which will automatically insert a BOM for you (instead of using CFile), or manually insert one yourself.
  • This can be done by manually inserting a Unicode BOM at the beginning of the file.
  • You can insert specific byte values into a string literal by using \xAB where AB are the 2 hex digits. This is especially useful for inserting non-printable characters.
  • Unicode string literals in Microsoft Visual Studio are 2-byte little endian, so we should use the BOM for UTF-16 little endian (aka UTF-16LE).
  • The BOM for UTF-16LE is FF FE, so we insert “\xFF\xFE” at the beginning of our file.
CFile myFile( hFile ); // attach a CFile object to the handle we have
myFile.Write( "\xFF\xFE", 2 ); // UTF-16LE BOM, use ANSI string for raw bytes
static const TCHAR sz[20] = _T("Hockey is best!\r\n");
myFile.Write( sz, _tcslen( sz ) * sizeof( TCHAR ) ); // use number of bytes
  • The next problem is that you are creating a TCHAR array of 20 bytes, and then initializing it with a string literal.
  • This is nonsense. What if you change the content of the string literal in the future? You would have to manually count the number of characters in the string literal and adjust the TCHAR array size to make sure it is large enough to store the string and an extra terminating zero.
  • The correction is to omit the 20, and let the compiler figure out the necessary size based on the size of the supplied string literal.
  • So, the best way to create the c-string array and initialize it with a string literal is like this:
CFile myFile( hFile ); // attach a CFile object to the handle we have
myFile.Write( "\xFF\xFE", 2 ); // UTF-16LE BOM, use ANSI string for raw bytes
static const TCHAR sz[] = _T("Hockey is best!\r\n");
// or static const TCHAR* sz = _T("Hockey is best!\r\n"); // same thing
myFile.Write( sz, _tcslen( sz ) * sizeof( TCHAR ) ); // use number of bytes
  • One more thing. This code snippet is using TCHAR but it will only work in Unicode builds, not ANSI builds.
  • This is nonsense. There is no point in using TCHAR unless you are writing code which can run in either Unicode or ANSI builds.
  • If you want to write Unicode strings to a file in either Unicode or ANSI builds, you must use WCHAR instead of TCHAR.
  • So the correction is to use WCHAR instead of TCHAR like this:
CFile myFile( hFile ); // attach a CFile object to the handle we have
myFile.Write( "\xFF\xFE", 2 ); // UTF-16LE BOM, use ANSI string for raw bytes
static const WCHAR sz[] = L"Hockey is best!\r\n";
myFile.Write( sz, wcslen( sz ) * sizeof( WCHAR ) ); // use number of bytes
  • One more thing. Using “sz” for a variable name is horrible.
  • First of all, variable names should describe the *PURPOSE* of the variable, not the type. “sz” does not describe the purpose, it incorrectly describes the type. We already know the variable is a string, so it does not make sense to name the variable an abbreviation for string.
  • Name things appropriately based on their purpose. “Temp” is a perfectly acceptable name for a variable used in the immediate scope as temporary storage.
  • Secondly, “sz” is “hungarian notation” for a zero-terminated string, however it’s almost always used for ANSI string variables.
  • If you are going to use hungarian notation, use it properly. I dislike hungarian notation, but if you are going to use it, then a more correct name would be “wszTemp” to indicate its a wide zero-terminated string use for temporary storage.
CFile myFile( hFile ); // attach a CFile object to the handle we have
myFile.Write( "\xFF\xFE", 2 ); // UTF-16LE BOM, use ANSI string for raw bytes
static const WCHAR wszTemp[] = L"Hockey is best!\r\n";
myFile.Write( wszTemp, wcslen( wszTemp ) * sizeof( WCHAR ) ); // use number of bytes
Follow

Get every new post delivered to your Inbox.

%d bloggers like this: