El TecnoBaúl de Kiquenet

Kiquenet boring stories

Archive for the ‘VisualStudio’ Category

Delete TestResults folder (Unit Testing Visual Studio)

Posted by kiquenet en 5 enero 2015

Cleaning up Visual Studio TestResults with PowerShell

If you write your unit tests using Visual Studio, then you know how quickly those pesky "TestResults" folders can eat up precious disk space over time.

Assuming all of your code is collocated in the same parent directory, replace "C:\TFS" with your parent directory.

(get-childitem C:\TFS\* -recurse) | where{$_.name -eq "TestResults"} |% {remove-item $_.fullname -recurse}


Error Handling when deleting folders and files.

Validating contents TestResults folder (subfolders In and Out, *.trx files, …)

$dir = "C:\TFS\"
(get-childitem $dir -recurse) | where { $_.name -eq "TestResults"} | foreach {

   $delete = $false;
   (get-childitem  $_.FullName -recurse) | where {$_.name -eq "Out"}  | foreach {
        $ParentS = ($_.Fullname).split("\")
        $Parent = $ParentS[@($ParentS.Length – 3)]
        if ($Parent -eq "TestResults") {$delete = $true;}


   if ($delete)
        Write-Host -ForegroundColor red ("Eliminando {0}" -f  $_.FullName )
        Remove-item $_.fullname -recurse


Write-Host -ForegroundColor red ("Eliminado TestResults de {0}" -f  $dir )


Posted in .NET, PowerShell, Productividad, Scripts, VisualStudio | Etiquetado: , , | Leave a Comment »

Error in Pre Build (Post Build) Event

Posted by kiquenet en 9 octubre 2014

About this error when you compiles a project.

Unable to copy file "C:\TFS\Main\AddIn\FicPwd.key" to "bin\Debug\FicPwd.key". Access to the path ‘bin\Debug\FicPwd.key’ is denied.

$(TargetDir) = C:\TFS\Main\AddIn\bin\Debug

For PreBuild Event:

attrib -r "$(TargetDir)FicPwd.key"


Maybe using Powershell

$computer = gc env:computername

$fileList = Get-ChildItem ".\InfoPath Form Template" | Where-Object {$_.name -like "*.dll" -or $_.name -like "*.pdb" -or $_.name -like "*.xsf"  }

foreach ($fileItem in $fileList)
$fileItem.set_IsReadOnly($false) # Remove readonly flag


Posted in Comandos, Scripts, VisualStudio | Etiquetado: , , , | Leave a Comment »

Troubleshooting VSIX

Posted by kiquenet en 11 agosto 2014

VSIX Best Practices

This post is about a new way to install extensions to Visual Studio, introduced in VS 2010, called the VSIX file. The information it contains will be of most interest to readers who develop Visual Studio extensions, but I encourage users who download and install those extensions to read it as well.

A VSIX file conforms to the ECMA Open Packaging Conventions (OPC) standard. It’s created as part of a VSIX project build in Visual Studio, and you can view its contents with any zip file utility. If you upload your VSIX to the Visual Studio Gallery, your customer can install it right in Visual Studio, in the new Extension Manager:


It can also be installed by downloading and double clicking on the file, and uninstalled either in the Extension Manager, or by simply deleting the associated files. You can find introductory information about VSIX here and here.

The VSIX feature comes with a lot of options. In most cases you don’t have to understand them all. This post is a list of tips that will give you some guidance about how to use the new VSIX capabilities in the best way. Here’s what I’m going to talk about:

  • How to package your extension into a VSIX in the simplest way
  • How to install via MSI if you need to
  • How to use VSIX versioning
  • What to avoid

Packaging your extensions using VSIX

  • Use strong names for all your assemblies. You don’t want your “util.dll” to collide with somebody else’s; if you don’t use strong names the system won’t distinguish between them, and somebody will get a run time error.
  • Distribute your whole product in one independent VSIX if you can. The feature does allow one VSIX to depend on another. But, save that for situations where each one is developed and shipped separately, because shipping a single VSIX will reduce the amount of information you have to understand.
  • If you ship more than one VSIX, and they share common assemblies, copy the common assemblies into each separate VSIX. This has the effect of shipping your whole product in one VSIX described above. There’s no runtime harm in shipping copies of common assemblies – in memory the CLR will only load one:
    But be aware that it will load only one, and the first one loaded wins. So you should ship updates to all your VSIXs that contain common assemblies together.
  • If your product is extending another extension, then your VSIX needs to take a dependency on the target VSIX using either the Select Installed Extension or Manual Reference choice in the dialog below (which you raise by clicking the Add Reference button in the VSIX Manifest Editor).
    In this case
    • Read the Versioning section below to understand the best way to specify the version of your target VSIX in this dialog.
    • Stay aware of your target extension’s updates, and test to make sure your extension is still compatible with each update.
  • If your VSIX publishes an API that another VSIX will use
    • Read the versioning section below to understand how your users will expect your versioning to behave.
    • Maintain binary compatibility between versions if you can; this just makes life simpler for your extenders.
    • Keep your extenders aware of approaching updates so they can test against them. Make sure they know in advance if you plan to release a version that breaks compatibility.

Installing via MSI

Some extensions still need to be installed by MSI: for example some of your files might have to be in a specific, well-known location, you might have a component like an MSBuild task that VSIX install doesn’t support, you might need to use binding redirection – see more information here. There’s no problem with doing that. In fact, we provide a way for an MSI installed extension to make itself visible in the new Extension Manager, so that the customer can see all his extensions in one place.

To make your extension visible in the Extension Manager, your MSI install should create a subdirectory in the Extensions directory for the hosting product:

For a non-administrative, per-user install (recommended) in Visual Studio, the path will look like this:
        Users\user id\AppData\Local\Microsoft\VisualStudio\10.0\Extensions\your company\extension name\version\
and for a per-machine install:
        Program Files\VS 10.0 install directory\Common7\Ide\Extensions\your company\your extension name\version\
An Isolated Shell application will define its own Extension directory.

In that folder, put the extension.vsixmanifest file built by your VSIX project, with an added element that marks it as installed by MSI:

 <Identifier Id="VSIXProject2.Microsoft IT.8532242f-afdc-44fa-82b2-0b6b5afc1c38">


Note that although the user will then see the extension in the Extension Manager, since it’s installed by MSI, he still needs to manage it through Windows Add/Remove Programs.


If your extension is self-contained (i.e. you distribute it in a single VSIX that doesn’t have any dependencies on other ones), and no other VSIXs will depend on yours (i.e. your VSIX doesn’t expose any APIs), you don’t need to read this section. If your VSIX does offer or consume APIs, or you distribute multiple VSIXs with common shared assemblies, read on for more information.

First, let’s do a quick review of how versioning works in the CLR. For an assembly with a strong name, its CLR identity comes from a combination of the file name on disk, Assembly Version string, an optional cultural attribute, and a digital signature. When one assembly references (i.e. consumes APIs from) another one, the consumer is targeted to a particular version of the referenced assembly at build time. (Binding redirection can change this at run time, but the VSIX installer doesn’t support that yet.) The version string contains four segments: <major version>.<minor version>.<build number>.<revision> (for example “”). The recommended convention for using the version string is that when an assembly’s API breaksbinary compatibility, the major version is incremented. (Note that I’m talking about Assembly Version, which is part of the strong name, not Assembly File Version, which is purely informational – you can use Assembly File Version any way you like. See more information here.)

That’s all background information. Now let’s talk about using versioning with VSIX files. The first thing I’m going to recommend, although it probably sounds a little unexpected, is that you not change the Assembly Version strings when you ship an update of your VSIX. This is because, as I mentioned above, the VSIX installer doesn’t support binding redirection yet, so if you do change any segment of an assembly version number, you may break downstream VSIXs that depend on the old version number of your assembly. The VSIX file has its own mechanism for version management, and I recommend that you use that one instead, because its added flexibility gets you around the binding redirection issue.

For a VSIX that uses an API from another VSIX:

The syntax of a VSIX version string is the same as the assembly one, and we will use the recommended convention to indicate that a new release breaks binary compatibility with the old one: incrementing the major version number. The big advantage of the VSIX versioning mechanism is that if you’re consuming an API from another VSIX, you can specify a range of version numbers of the target VSIX that you’re compatible with. Let’s see how this works. When you raise the Add VSIX Reference dialog in the VSIX Manifest Editor:



in the Version fields just above, you can specify a range between minimum and maximum version numbers that you’re compatible with. If the developer of the VSIX whose API you consume obeys the versioning conventions, you can specify a range like from Min 1.0 to Max 1.9999 to indicate that you will use any version of your dependency between those two. When the VSIX you depend on installs, for example, version 1.2, you will be compatible with it. When the user attempts to install 2.0, the installer will recognize the incompatibility:


and display a warning dialog:


If the user updates the extension you depend on anyway, your extension will be disabled because of the incompatibility, and he should look for an update from you that’s compatible with the new version of the API.

If for any reason you believe you are dependent on a specific version of the target extension, you can code that number as the Min and Max values to target only that version:


If you only code the Min value, you will bind to anything equal or higher. I don’t recommend that, because binary compatibility breakage (in the example below, from 1.x to 3.0) can lead to run time errors.


For a VSIX that offers an API to other VSIXs:

If you release an extension that offers an API, you should handle the versioning at the VSIX level. This means leaving the Assembly Version string unchanged across releases, and incrementing your VSIX version number (shown in the VSIX manifest editor below).


It’s great for your consumers if your API can maintain binary compatibility across releases. If you need to break compatibility, increment the major version number. But at that point, when the VSIX installer upgrades your extension, all the consumers of your API will have to ship releases that are compatible with the new API.

Things to avoid:

    • Embedding one VSIX inside another (using the Add payload selection in the Add VSIX Reference dialog). 

      In the current version of Visual Studio, certain combinations of embedded VSIXs and version updates don’t install properly. This feature should be avoided for now; the safest practice is to install VSIXs that have a dependency relationship separately.


In this article we looked at a set of recommendations for using the new VSIX feature. What I want to leave you with is: minimize complexity. Take advantage of the new VSIX features as you need them, but keep your life as simple as possible by using only the features you need. That way the VSIX install experience will be simple for your customers, which is the  reason VSIX was invented.

How VSIX extensions are discovered and loaded in VS 2010

is the new technology used for deploying extensions in Visual Studio 2010. The primary goal of this new technology is to encourage extension creation and consumption by easing the management (“management” meaning Browsing/Installing/Uninstalling/Enabling/Disabling) of Visual Studio extensions. To take full advantage of the VSIX installer for deploying your extensions, it helps to know a little bit more about how Visual Studio decides which extensions to load.

Dmitry Goncharenko provided a good high-level overview of how these VSIX extensions are discovered and loaded in his post Bootstrapping of VS packages and VSIX extensions in VS2010. Let’s now take a more in-depth look at how this process works.

An extension consists of:

  1. an extension.vsixmanifest file, which contains metadata about the extension
  2. any additional files that represent the extension content. This could include MEF assemblies, VS Package assemblies, VS Template ZIP files, PkgDef files, etc..

The simplest vsix extension would contain only the extension.vsixmanifest file, though that would admittedly be a very uninteresting extension.

Extension Discovery

In accordance with the goal of simplicity, a VSIX extension install consists of only copying the extension files into one of a few well-known locations. These locations are defined in the “Master PkgDef” file, located at <VsInstallRootFolder>\Common7\IDE\devenv.pkgdef and pictured below.


The relevant values are described below.




The root folder under which machine wide VSIXs are deployed.

(This is set as <VsInstallRootFolder>\Common7\IDE\Extensions)


The root folder under which user specific VSIXs are deployed.

(This is set as %LocalAppData%\Microsoft\VisualStudio\10.0\Extensions)


A list of additional folders where extensions will be searched for. The name for this property was originally defined by the PkgDef subsystem. This list is shared with vsix extensions so that any extensions that contain .pkgdef files will be properly loaded. Note that this includes ApplicationExtensionsFolder.

Upon initialization, the Extension Manager service, SVsExtensionManager, will search the above locations for extension.vsixmanifest files. The PkgDefSearchPath folders are searched first, followed by the UserExtensionsRootFolder.

Extension Loading Rules

At this point, each extension must pass a few trials before being considered installed by the Extension Manager. Before diving into the details, here’s a quick summary of these:

  • The extension.vsixmanifest XML conforms to the XSD.
  • The extension has not been marked for deletion.
  • The extension’s identifier cannot conflict with any other previously discovered extensions.

First, if the extension.vsixmanifest XML does not conform to the VSIX manifest XSD schema, it is ignored. If the manifest XML passes schema validation, then it will be deserialized into an object model in memory. Second, the Extension Manager needs to verify that the extension is not marked for deletion. Before going any further, it would be helpful to discuss what exactly this means.

If you’ve uninstalled an extension through the Extension Manager dialog in Visual Studio, you may have noticed that the uninstall occurs extremely fast. This is because the extension is only marked for deletion at that time. On a subsequent initialization of the Extension Manager (the next time Visual Studio or the VSIX Installer are launched), all of the pending deletions are cleaned up on a background thread *after* all installed extensions have been discovered. Therefore, any extension that is marked for deletion should be discarded and no longer considered installed.

Third, if the extension contains the same ID as another extension that has already been discovered, it will be discarded. This is where the search order becomes important. The UserExtensionsRootFolder is searched last in order to give precedence to machine wide extensions when an ID conflict is encountered.

Once an extension has passed these checks, it is considered “installed” by the Extension Manager service. Figuring out whether an extension is not installed because of one of the above reasons is easy since the Extension Manager logs this information to the Visual Studio activity log. The activity log can be enabled by running the Visual Studio process (<VsInstallRootFolder>\Common7\IDE\devenv.exe) with the ‘/log’ switch, as follows:

devenv.exe /log <path_to_log_file>

The Mechanics of Enabled/Disabled Extensions

So your extension is successfully “installed”, but how does the Extension Manager determine whether it’s “Enabled”? The answer depends upon where your extension is installed. Extensions installed to any directory in the PkgDefSearchPath list of folders are always enabled. Extensions installed to the UserExtensionsRootFolder path must be individually enabled through a list maintained in the HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\10.0\ExtensionManager\EnabledExtensions registry key. TheExtension Manager Install API, used by the extension install dialog as well as the VSIX installer, will write the entry in the EnabledExtensions key for any newly installed extension so that extensions installed in this manner are automatically enabled. You’ll notice that if you manually install an extension by copying the extension files to a subfolder in the UserExtensionsRootFolder path, it will be disabled at first because the corresponding entry in EnabledExtensions has not been added. Enabling the extension can also be accomplished through the Extension Manager dialog.


Lastly, extensions in the UserExtensionsRootFolder path will all be disabled when running Visual Studio as an administrator, if the following option is not checked under Tools->Options->Environment->Extension Manager


This option was likely the most common culprit for why users (particularly administrators running WindowsXP) found that their extensions were not enabled in Beta2 and prior builds of Visual Studio, since the default value for the option was ‘False’. Due to the frequency with which customers ran into this problem, we’ve changed the default value for this option to ‘True’. Note that the Extension Manager dialog provides a warning if you’re running Visual Studio elevated, but do not have this option checked.


When in doubt about why an extension does not seem to be loaded or enabled, you should consult the Visual Studio activity log, which will output various diagnostics during the loading process. You may also want to check out the following posts related to extension loading:




Posted in VisualStudio | Etiquetado: , | Leave a Comment »

TroubleShooting Visual Studio

Posted by kiquenet en 22 julio 2014

For Version 10.0, 11.0, 12.0.

Open cmd and navigate to

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE


C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE

and try to type the following commands:

  1. devenv.exe /log

  2. devenv.exe /safemode

  3. devenv.exe /resetskippkgs

  4. devenv.exe /installvstemplates

  5. devenv.exe /resetsettings

  6. devenv.exe /resetuserdata

Source : MSDN

Posted in Soporte, VisualStudio | Etiquetado: , , | Leave a Comment »

Customizing Code Coverage in Visual Studio 11

Posted by kiquenet en 24 junio 2014

1. The .runsettings file

Advanced VS 11 code coverage settings are specified in a .runsettings file. This is the configuration file used by VS 11 unit testing tools.

Some of you, who have used VS 2010, may be familiar with .testsettings file. You may be wondering why the same file was not used for VS 11. The reason for this was that the .testsettings file applies only to the MSTest based unit tests of VS 2010. The VS 11 unit testing tools not only apply for MSTest, but also 3rd party unit testing adapters such as NUnit and xUnit.net. Using a .testsettings file will not work with these. Hence a different settings file, the .runsettings, was used.

To customize code coverage, you will need to add .runsettings file to your solution. There isn’t a built-in template for this right now. You would need to add it as an xml file and edit its contents:

1. Right click Solution -> Add New Item -> XML File -> Save file as CodeCoverage.runsettings (the extension of .runsettings is important).

2. Copy the sample runsettings content given later in this blog into your file.

3. Edit it to customize code coverage, as explained in next section.

4. Set it as the default setting file to be used via Test -> Test Settings -> Select Test Settings File

After this, the specified settings should be used whenever you analyze code coverage.


2. Common customization scenarios

2.1. Customizing the set of binaries analyzed for code coverage

Here, we want include / exclude specific binaries from code coverage. Using the runsettings file, there are two approaches to do this:

Customize by exclusion

Here we include everything, and exclude what we don’t need – an opt-out approach. This may be useful if the code of interest changes often and new binaries get introduced frequently: you would like these new binaries to be automatically included for code coverage when they are loaded. There are some known binaries that you don’t want coverage, like some test automation code. These are excluded.

Here, leave the includes as empty to include all assemblies. Specify the assemblies to be excluded thru by their name / path.



<!– Do not specify any includes. This will attempt to include all binaries –>



<!– Exclude modules that aren’t to be processed, by their name / path –>





Customize by inclusion

Here we include exactly what we need, and exclude everything else – an opt-in approach. This may be useful if the code of interest is present in well-known binaries; you just want these binaries to be covered.

Here explicitly include the binaries of interest. Leave the excludes as empty to exclude everything.



<!– Include modules of interest, by their name / path –>




<!—- Do not specify any excludes. Anything not included will get excluded –>



Note that while both inclusions and exclusions can be used together, it can make things very confusing. So it is preferable to use one mechanism to customize.

2.2. Specifying symbol search paths

Code coverage requires symbols (PDB) for binaries to be instrumented. For binaries built by your solution, symbols are generally present alongside the binary and code coverage automatically works. In some cases, you may be referencing binaries external to your solution, but still need code coverage for these external binaries. In such cases, you can specify the symbol search path to look for symbols as part of the runsettings file.




A set of local and remote paths can be specified here. Note however that symbol resolution can take time, especially when using a remote build share with a lot of binaries. Best would be to avoid this by copying symbols alongside the binary, and not specify any search paths.

3. Sample .runsettings file

Below is a sample runsettings file. When creating a new runsettings, start with this, and customize it as needed.

<?xml version="1.0" encoding="utf-8"?>




<DataCollector friendlyName="Code Coverage"uri="datacollector://Microsoft/CodeCoverage/2.0"assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">





About include/exclude lists:

Empty "Include" clauses imply all; empty "Exclude" clauses imply none.

Each element in the list is a regular expression (ECMAScript syntax).

An item must first match at least one entry in the include list to be included.

Included items must then not match any entries in the exclude list to remain included.

It is considered an error to exclude all items from instrumentation as no data would be collected.














Additional paths to search for symbol files. Symbols must be found for modules to be instrumented.

If symbols are alongside the binaries, they are automatically picked up. Otherwise specify the here.

Note that searching for symbols increases code coverage runtime. So keep this small and local.


  <Path>C:\Users\User\Documents\Visual Studio 11\Projects\ProjectX\bin\Debug</Path>




























<Source>.*\\microsoft sdks\\.*</Source>


























4. Specifying runsettings file while running unit tests

Unit tests can be run in different contexts. The below specifies how runsettings are specified in each case.

4.1. In Visual Studio IDE

Select setting file to be used via Test -> Test Settings -> Select Test Settings File. Then invoke ‘Analyze Code Coverage’.


4.2. In command line

The tool vstest.console.exe is the way to run unit tests from command line. It is the successor of MSTest – and can run not only the MSTest based tests, but also tests of third party unit adapters (like NUnit, xUnit.net, etc).

To run tests with the runsettings file here:

1. Launch the Visual Studio Native Tools command prompt.

2. Run:

> vstest.console.exe TestAssembly.dll /EnableCodeCoverage /settings:CodeCoverage.runsettings

4.3. In Build

Here, there is a TFS Build Definition, as part of which unit tests are run and overall code coverage is measured. If there is a .runsettings file customizing code coverage, the same runsettings file can be used in the Build as well.

Below are the steps to do it.

1. Edit the build definition. Go to Process tab, and edit test run details.


2. Make sure the test runner is ‘Visual Studio Test Runner’. Set Options to ‘Custom’. Hit Browse to choose the settings file.


3. Pick the settings file and save the definition.



Posted in VisualStudio | Etiquetado: , , | Leave a Comment »

Visual Studio 2013–Install Error

Posted by kiquenet en 19 mayo 2014

During installation I am getting an error

“Microsoft visual studio 2013 VsGraphic Helper Dependencies RC Incorrect Function”


Windows 8.1

ISO VS 2013 ultimate

I try copy contents in local, and I get the same error.


– verify checksum of ISO. Get file again, copy to local.

– Uninstall the failed version of 2013 from control panel -> Uninstall programs

– Restart the computer

– Clean %temp%

– Mount ISO, execute as Administrator setup.exe

– Re-run the setup again.



Posted in Soporte, VisualStudio | Etiquetado: , , | Leave a Comment »

Create Private Accessors for Visual Studio 2012

Posted by kiquenet en 19 mayo 2014

Con Visual Studio 2012 desaparece la creación desde IDE de los Private Accessors.

Posibles soluciones: crear los Private Accessors con la clase Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject o usar el comando publicize.exe.

Open a command prompt, or a “VS2013 x86 Native Tools Command Prompt” to have the search path already set up, and run publicize.

In case you do not have the path set up correctly, the tool can be found at
%Program Files (x86)%\Microsoft Visual Studio 11.0\Common7\IDE for Visual Studio 2012 or %Program Files (x86)%\Microsoft Visual Studio 12.0\Common7\IDE for VS 2013.

publicize.exe [options] input-assembly

publicize.exe creates classes named NameOfTheSourceClass_Accessor. In case the class to be tested is called MyClass, the accessor is named MyClass_Accessor.

Starting with Visual Studio 2012, private accessors cannot be created any more by the IDE. The post Home-made Private Accessor for Visual Studio 2012+ presents an approach on how to create private accessors using the classMicrosoft.VisualStudio.TestTools.UnitTesting.PrivateObject.

Axel Mayer noted in the MSDN forums post How to create private accessors in VS 2012 that one can use the command line tool publicize.exe to create private accessors too.



Home-made Private Accessor for Visual Studio 2012+

How to create private accessors in VS 2012

publicize.exe documentation

Posted in .NET, VisualStudio | Etiquetado: , | Leave a Comment »

Hide or Show the Solution File in Solution Explorer

Posted by kiquenet en 31 octubre 2012

If you don’t like seeing the solution file in Solution Explorer, you can easily hide it (or show it if you have it hidden).  First, let’s review what the default looks like with the solution file showing:


Now if we go to Tools -> Options -> Projects and Solutions -> General and uncheck "Always show solution":


This is the result:


SPECIAL NOTE:  This only works when there is one project in the solution.  If you have multiple projects in your solution it will ignore this setting and give you the default view.




Posted in .NET, Trucos, VisualStudio | Etiquetado: , | Leave a Comment »

Setup Projects y scripts “uninstall”

Posted by kiquenet en 17 agosto 2012

If the user wants to uninstall the product, he can go to "Add/Remove Programs", or he can just double-click the uninstall.cmd. The contents are:

%windir%\system32\msiexec /x {CC3EB7BF-DD82-48B9-8EC5-1B0B62B6D285}

The GUID there is the ProductCode from the Setup Project in Visual Studio.


How can I dynamically generate a batch file that contains the ProductCode for the, at build time?

"Using Visual Studio 2005/2008, you don’t need to write any code to add a uninstall option for a Setup project (Yes I know some people can write code to do it)

1) In the Setup Project –> File System windows –> Right Click “File System on Target machine” –> add a Special Folder, select System Folder;

2) Into this system folder Add a file. Browse for msiexec.exe from local System32 folder and add it. Override default properties of this file as follows:

Condition:=Not Installed (make sure you put ‘Not Installed’ exactly like that, same case and everything), Permanent:=True, System:=True, Transitive:=True, Vital:=False.

3) Create a new shortcut under the ‘Users Program Menu’, Set Target to the System Folder which you created in the step 1. and point it’s at the msiexec.exe. Rename the shortcut to ‘Uninstall Your Application’. Set the Arguments property to /x{space}[ProductCode].

4) Build the project, ignore warning about the fact that msiexec should be excluded, DONT exclude it or the setup project wont build.

The ‘Not Installed’ condition and Permananet:=True ensure that the msiexec.exe is only placed into the system folder as part of the install IF it doesn’t aready exist, and it is not removed on an uninstall – therefore it;s pretty safe to ignore that warning and just go for it.


Otra opciones más enrevesadas:

1.) make your application read command line arguments, the code below is from a WPF project

public partial class App : Application


  void Application_Startup(object sender,StartupEventArgs e)


    for(int i = 0;i != e.Args.Length;++i)


      if(e.Args[i].Split(‘=’)[0].ToLower() == "/u")


        string guid = e.Args[i].Split(‘=’)[1];

        string path = Environment.GetFolderPath(Environment.SpecialFolder.System);

        ProcessStartInfo uninstallProcess = new ProcessStartInfo(path+"\\msiexec.exe","/x "+guid);







To add the uninstall link in the deployment project you just need to follow the steps below:

  1. Select your deployment project and go to the file system editor.
  2. Using the file system editor you navigate to the desired location of the install file.
  3. From the decired location you create a new shortcut to your primary output and name it Uninstall – or whatever else you would like.
  4. In the properties of the new shortcut you set the arguments property to /u=[ProductCode]

2.) creates an uninstall.cmd. It runs as a custom action during installation.

var fso, ts;
var ForWriting= 2;
fso = new ActiveXObject("Scripting.FileSystemObject");

var parameters = Session.Property("CustomActionData").split("|"); 
var targetDir = parameters[0];
var productCode = parameters[1];

ts = fso.OpenTextFile(targetDir + "uninstall.cmd", ForWriting, true);

ts.WriteLine("@echo off");
ts.WriteLine("goto START");
ts.WriteLine(" Uninstall.cmd");
ts.WriteLine("@REM The uuid is the 'ProductCode' in the Visual Studio setup project");
ts.WriteLine("%windir%\\system32\\msiexec /x " + productCode);

Una buena referencia para Extending VS Setup Projects:


Gran referencia que explica en detalle los Setup Projects: PackageCode, ProductCode, UpgradeCode, herramienta Orca, etc.






Posted in .NET, SetupProjects, VisualStudio | Leave a Comment »

Cómo saber si un assembly esta compilado en modo Debug o Release

Posted by kiquenet en 9 julio 2010

Necesidad de conocer cual era el modo en el cual fue compilado cierto assembly. La primer herramienta a la que acudí me dió una respuesta: Reflector de Lutz Roeder.

El compilador agrega el attributo DebuggableAttribute como información del assembly. Los modos de debug fijados por el compilador dependerán de los parámetros que le pasemos al compilador por línea de comandos o el tipo de compilación que definamos en el proyecto de Visual Studio.

En el caso de haber compilado con Visual Studio 2005 ó 2008 en modo Release, nos encontraremos con la siguiente línea:

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]

En caso de haber compilado en modo Debug:

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.EnableEditAndContinue | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.Default)]

Les recomiendo la lectura de la documnetación correspondiente a los valores del enumerado System.Diagnostics.DebuggableAttributes.DebuggingModes

A continuación un ejemplo de código que revela el modo de compilación:

La propiedad DebuggableAttributes.IsJITTrackingEnabled controla si en tiempo de ejecución el CLR hace un seguimiento de la información que es importante para el depurador mientras se genera el código. Esta información contribuye a que el depurador mejore la depuración.

public static bool EnsambladoCompiladoEnModoDebug(string filePath)
            var asm = Assembly.LoadFile(Path.GetFullPath(filePath));
            foreach (Attribute att in asm.GetCustomAttributes(false))
                if (att is System.Diagnostics.DebuggableAttribute)
                    var debug = ((DebuggableAttribute)att).IsJITTrackingEnabled;
                    Console.WriteLine("Modo Debug: {0}", debug);
                    if (debug) return true;
            return false;



Posted in .NET, VisualStudio | Etiquetado: , , | Leave a Comment »