Automating Tasks in Visual Studio

Ever wondered how to automate tasks in Visual Studio such as auto fill forms, paste into multiple locations or even print all open documents? Well with the use of VS Marcros it will be possible and the possibilities are endless only restricted by your imagination.  VS Macros is a very powerful tool within Visual Studio and most probaly most developers don’t use this or whats worse they might have bought a third party solution to automate some tasks in Visual Studio.

Having said that this article is to show you how to develop a simple macro to get you started.  This macro that I will run through is how to make a shortcut for commenting within Visual Studio Text Editor, that comment will include the current time the comment was made and username who commented it, which is useful specially if you are working with other developers as well.

So lets get started.

1. Open the Macro Explorer

First you have to go to macro explorer and check whether the macro you want to make is already available as there are some built in macros that come with Visual Studio.  You can do that by going to Tools -> Macros -> Macro Explorer.  On the Macro Explorer view you can see that there is a  Sample Project, browse through that and check whether the solution you want to develop is avaibale if not proceed to step 2

2. Create a New Macro Project

If the one you need is not on the Sample Macros then start developing your own.  You can create your own project, use the MyMacros that is already in there or even the Samples, its all up to you.  For this sample we use “MyMacros”.

3. Create a New Module

Now right click on the “MyMacros” project and choose “New module”

and give it a useful name.   For this sample I will use “MyCustomModule”.

4. Create a New Macro

Now right click on that new module you just created and select “New macro”, you will now be presented with the Marco Editor.  Now you have a new Sub which is “Macro1″, rename it to what you want, in this sample I will use “BetterComments”.

5. Start Developing

The one we want to achieve here is to create a better comment, use the code below as a sample.

If you notice there is a function there called LineOrientedCommentStart, this was just copied in the sample macros and it adds that comment character in front of the text comment, it also checks for the document extension to place the proper comment charaters, you can extend this to use other file types as well.

Importsss System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports EnvDTE90a
Imports EnvDTE100
Imports System.Diagnostics

Public Module MyCustomModule
    Sub BetterComments()
        Dim textSelection As EnvDTE.TextSelection

        textSelection = DTE.ActiveWindow.Selection

        textSelection.NewLine()
        textSelection.Insert(LineOrientedCommentStart())
        textSelection.Insert(" ---------------------------------------------------")

        textSelection.NewLine()
        textSelection.Insert(LineOrientedCommentStart())
        textSelection.Insert(" " + Date.Now + " - " + System.Environment.UserDomainName + "\" + System.Environment.UserName())

        textSelection.NewLine()
        textSelection.Insert(LineOrientedCommentStart())
        textSelection.Insert(" ")

        textSelection.NewLine()
        textSelection.Insert(LineOrientedCommentStart())
        textSelection.Insert(" ---------------------------------------------------")
    End Sub

    Function LineOrientedCommentStart(Optional ByVal document As Document = NothingAs String
        Dim extension As String

        If (document Is NothingThen
            document = DTE.ActiveDocument
        End If

        extension = document.Name
        If (extension.EndsWith(".cs"Or extension.EndsWith(".cpp"Or extension.EndsWith(".h"Or extension.EndsWith(".idl"Or extension.EndsWith(".jsl")) Then
            Return "//"
        ElseIf (extension.EndsWith(".vb")) Then
            Return "'"
        Else
            Throw New Exception("Unrecognized file type. You can add this file type by modifying the function Utilities.LineOrientedCommentStart to include the extension of this file.")
        End If
    End Function
End Module

6. Assign a Keyboard Shortcut

Now youre done in developing you macro, save it and assign a keyboard shortcut.  Go to Tools -> Options and the dialog below will show.  Type the name of your macro in the “Show commands containing” text box to view you newly developed macro and assign shortcut keys using “Text Editor” only (you dont want to activate that macro in Class Diagram or UML Designer).  In this sample we use Alt + Insert.

7. Use your Macro

Now on text editor press Alt + Insert and you should see your new comment now.

Running Applications on A Higher Priority

Did you notice when you run a certain application on a Higher Priority things are processed really quickly (this also depends on what application are you running) but take for example WinRar which is the one I tried, things get zipped and extracted faster than it is on normal priority.  But there are some applications that have slower performance than normal, I guess you have to test and see whether you would benefit in this solution.

Now if you are free to change the codes you can just do it like this in C#

System.Diagnostics.Process myProcess = System.Diagnostics.Process.GetCurrentProcess();
myProcess.PriorityClass = System.Diagnostics.ProcessPriorityClass.High;

or VB

Dim myProcess As System.Diagnostics.Process = System.Diagnostics.Process.GetCurrentProcess()
myProcess.PriorityClass = System.Diagnostics.ProcessPriorityClass.High

and all you have to do is to invoke this before you load for Form or anywhere you want to change the Process priority.

But what is you dont have that luxury to do it in the code? Or the codes are jsut batch files or vbscripts which does not have a rich objects and classes available for use like .Net. Yes you can still do it by going to the task manager and assigning a process that priority but you dont want to do it anytime. Theres another solution which is really easy and all you have to do is run the process with the /<priority> switch.  Where the priority can be anything in this list

  • realtime
  • high
  • normal
  • low
  • abovenormal (Windows 2000 only)
  • belownormal(Windows 2000 only)

Now to do that all you have to do is to use the start command and here is the syntax

start /{priority} {application},

ex.

start /high winword
start /low notepad
"C:\YourDirectory" start /realtime YourApplication.exe

or even from run command

cmd /c start /low calc

So you can use your imagination now if you want to use this in your scripts

Execute Applications on Remote Systems

Running executable applications remotely is really simple as long as you know the credentials of the remote workstation you want to run it on.

So how would you do that?

Through the use of PsExec. So what is PsExec? PsExec is a telnet-replacement that lets you execute processes on other systems without having to installing a client software. PsExec is free and can be downloaded here.

Once you downloaded it you can easily run command prompt from that directory.

To give you an example lets say I want to run a console application located at “D:MyApplications” named “MyExecutable.exe” at the workstation which has the IP “10.10.1.255”. Now the username for that workstation is “user” and the password is “pass”.

So the command for it will be :

psexec.exe \\10.10.1.255 -u user -p pass -c -f "D:\MyApplications\MyExecutable.exe"

So what does the switches mean?

-u : send the username where the application will run as.
-p : that’s the password of that user.
-c : by using this switch, it copies the specified program in the specified location to the remote system for execution.
-f : if file already exists on the remote system it still copies and overwrites it.

So with a little bit of imagination you can do lots with it like performing command line commands remotely or you can even run it from a C# or VB.Net application.

Like such

VB.Net

Dim sShellCommand = "c:\PsExec\psexec.exe \\10.10.1.255 -u user -p pass -c -f ""D:\MyApplications\MyExecutable.exe"""
Shell(sShellCommand, AppWinStyle.Hide)

C#.Net

System.Diagnostics.Process oProcess = new System.Diagnostics.Process();
oProcess.EnableRaisingEvents = false;
oProcess.StartInfo.FileName = "c:\\PsExec\\psexec.exe";
oProcess.StartInfo.Arguments = "\\\\10.10.1.255 -u user -p pass -c -f \"D:\\MyApplications\\MyExecutable.exe\"";
oProcess.Start();

So if you want to know what are the other switches just type PsExec and you will see all switches you might need

Quick Tip : Modifying INI files in C# and VB.Net

Currently I am doing a lot of start up scripts on a Citrix environment and a lot of it have to deal with Network device mapping, allocation of license keys for users and de-allocating them, provisioning Initialization files, etc.

I think I have a lot to share in terms of some very useful code snippets and this is one of it – modifying INI files. To give you a better idea on how it goes the image below with the item highlight is the portion of the ini we are modifying.

C# Code

public class IniFile
{
public string sPath;
public IniFile(string INIPath)
{
sPath = INIPath;
}
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string sSection,  string sKey, string sValue, string sFilePath);

[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string sSection,  string sKey, string sDefinition, StringBuilder sReturnValue, int iSize,  string sFilePath);

public void SetIniValue(string sSection, string sKey, string sValue)
{
 WritePrivateProfileString(sSection, sKey, sValue, this.sPath);
}

public string GetIniValue(string sSection, string sKey)
{
 StringBuilder sReturnValue = new StringBuilder(255);
 int i = GetPrivateProfileString(sSection, sKey, "", sReturnValue,  255, this.sPath);
 return sReturnValue.ToString();
}
}

Usage

IniFile myIniFile = new IniFile("C:\\Sample.ini");
myIniFile.SetIniValue("Section1", "Key2", "Test Value");

And for those who want it in VB.net

Public Class IniFile
Public sPath As String

Public Sub New(ByVal INIPath As String)
 sPath = INIPath
End Sub

<DllImport("kernel32")> _
Private Shared Function WritePrivateProfileString(ByVal sSection As String, ByVal sKey As String, ByVal sValue As String, ByVal sFilePath As String) As Long
End Function

<DllImport("kernel32")> _
Private Shared Function GetPrivateProfileString(ByVal sSection As String, ByVal sKey As String, ByVal sDefinition As String, ByVal sReturnValue As StringBuilder, ByVal iSize As Integer, ByVal sFilePath As String) As Integer
End Function

Public Sub SetIniValue(ByVal sSection As String, ByVal sKey As String, ByVal sValue As String)
 WritePrivateProfileString(sSection, sKey, sValue, Me.sPath)
End Sub

Public Function GetIniValue(ByVal sSection As String, ByVal sKey As String) As String
 Dim sReturnValue As New StringBuilder(255)
 Dim i As Integer = GetPrivateProfileString(sSection, sKey, "", sReturnValue, 255, Me.sPath)
 Return sReturnValue.ToString()
End Function

End Class

Usage

Dim myIniFile As New IniFile("C:\Sample.ini")
myIniFile.SetIniValue("Section1", "Key2", "Test Value")
Follow

Get every new post delivered to your Inbox.

Join 773 other followers