Archives pour la catégorie Visual Studio

C# 7.3 : les nouveautés

Petite évolution de C# 7.3 qui mérite notre attention, à nous fans de C#, du framework .NET et de ses apports. Microsoft a en effet apporté une attention particulière à la performance du code en mode sécurisé, à une amélioration substantielle de fonctionnalités existantes mais aussi deux nouvelles options de compilateur qui vont ravir ceux qui aiment l’opensource.

Que devons-nous retenir ?

Amélioration des performances du code sécurisé

L’indexation des champs fixed ne nécessite plus un second fixed

Vous le savez probablement, même si on en parle peu, même si on l’utilise peu, C# nous permet la création de code en mode non sécurisé. Cette écriture est très pratique pour ceux qui travaillent sur des fonctionnalités pointues où les performances sont essentielles. L’apport de C# 7.3 est de faciliter le contexte entre code sécurisé et code non-sécurisé afin que les développeurs aient justement moins accès au code non sécurisé. En effet, moins les développeurs passent de temps en code non sécurisé, plus leur code est stabilisé et sûr.

Observer par exemple dans le code ci-dessous la différence entre un code pré-C# 7.3 et un code C# 7.3. Dans cet exemple, vous devez accéder à un élément d’un tableau d’entier à l’intérieur d’une structure « unsafe »

unsafe struct S
{
   public fixed int myFixedField[10];
}

//Avant c# 7.3
class Avant
{
   static S s = new S();

   unsafe public void MaMethod()
   {
      fixed (int* ptr = s.myFixedField)
      {
         int p = ptr[5];
      }
   }
}

//Apres c# 7.3
class Apres
{
   static S s = new S();

   unsafe public void MaMethod()
   {
      int p = s.myFixedField[5];
   }
}

Avec C# 7.3, il n’y a plus besoin d’épingler avec fixed un pointeur complémentaire vers l’élément ; il y a a toutefois toujours besoin d’un contexte unsafe.

L’utilisation de fixed est étendue

L’instruction fixed, qui se limitait à un nombre limite de types est étendu à tout type contenant une méthode GetPinnableReference() qui retoure un ref T ou ref readonly T. L’instruction fixed est par exemple utilisable avec System.Span<T>.

Initialiseurs sur stackalloc

A l’image des initialiseurs sur les tableaux « classiques », il est possible d’utiliser la syntaxe suivante avec stackalloc (allocation d’un bloc mémoire sur la pile)

int* pArr = stackalloc int[3] {1, 2, 3};
int* pArr2 = stackalloc int[] {1, 2, 3};
Span arr = stackalloc [] {1, 2, 3};

Réaffectation des variables locales ref

Très pratique, les variables locales ref peuvent être réaffectées ; ce qui était auparavant impossible.

ref MaStructure  a = ref Structure1;
a = ref Structure2; //réassignation

Quelques nouveautés

Comparaisons et différences sur les tuples

Tous d’abord les tuples prennent désormais en charge les comparaisons et les différences. Je vous invite vivement à lire ce document Microsoft, mais voici en résumé le comportement : les tuples peuvent se comparer grâce à une comparaison dans l’ordre des membres de gauche à ceux de droites, les comparaisons s’arrêtant dès qu’une paire n’est pas égale.

var left = (a: 5, b: 10);
var right = (a: 5, b: 10);
Console.WriteLine(left == right); // affiche 'true'

De nombreuses choses se passent de façon transparente, notamment des conversions implicites comme dans l’exemple ci-dessous où la comparaison de int à long se fait implicitement

(long a, int b) longFirst = (5, 10);
(int a, long b) longSecond = (5, 10);
Console.WriteLine(longFirst == longSecond); // Affiche vrai

Des conversions « lifted », grosso modo des conversions qui gère le cas des comparaisons de type Nullable s’opèrent également

var left = (a: 5, b: 10);
(int? a, int? b) nullableMembers = (5, 10);
Console.WriteLine(left == nullableMembers); // Vrai

 Les contraintes « where » sur les génériques sont améliorées

Qu’il est pratique ce « where » sur les génériques ; il permet de spécifier l’héritage mais également s’il est possible de créer une instance comme dans l’exemple suivant où le type T doit implémenter IComparable mais également avoir un constructeur accessible sans paramètre.

public class MyGenericClass where T : IComparable, new()
{
// La ligne suivante est impossible sans la contrainte new():
T item = new T();
}

Vous connaissez et probablement utilisez déjà les contraintes de type struct ou class comme dans l’exemple suivant.

class MyClass<T, U>
where T : class
where U : struct
{ }

Ils sont en revanche nouveaux grâce à C# 7.3, ce sont les contraintes de type Enum, Delegate ou MulticastDelegate .

public class UsingEnum where T : System.Enum { }

public class UsingDelegate where T : System.Delegate { }

public class Multicaster where T : System.MulticastDelegate { }

Avec C# 7.3 est égaleemnt ajouté les types non managés, c’est à dire les type qu’on ne sont pas un type référence et ne contiennent aucun champ de type référencé à tous les niveaux d’imbrication

class UnManagedWrapper
where T : unmanaged
{ }

Cibles d’attribut

La cible d’un attribut est l’entité à laquelle il s’applique. Les cibles peuvent être assembly, module, field, event, method, param, propery, return ou type. Il est désormais possible d’écrire :

[field: InformationSurLeFieldAttribute]
public int Couleur { get; set; }
{ }

Nouvelles options du compilateur

Signature publique/opensource

Il est désormais possible de signer un assembly avec une clé publique grâce à

-publicsign. 

L’assembly est ainsi identifié comme « signée » (grâce à un bit dans l’assembly) mais provient d’une clé publique. Ceci permet la génération d’assembly à partir de clé publique opensource.

pathmap

L’option

pathmap

 contrôle le chemin des sources écrits dans les fichiers PDB ou CallerFilePathAttribute. Il est ainsi possible d’indiquer au compilateur de remplacer les chemins sources de l’environnement de build par ceux mappés.

Cet article s’est focalisé sur les améliorations les plus parlantes, la liste complète de toutes les fonctionnalités est disponible  dans la documentation Microsoft.

 

C# 7.1 – Les nouveautés

Les nouveautés de C# 7.1 sont subtiles mais intéressante. Tout d’abord la sélection de la version du langage se fait dans les paramètres avancés du build. En effet, par défaut la version C# 7.1 n’est pas sélectionnée par défaut.

Il est également possible de modifier directement le fichier csproj en ajoutant un propertygroup approprié.

Async Main

Evolution, il est désormais possible d’utiliser le mot clé await dans la méthode Main. Il était en effet autrefois nécessaire d’encapsuler le retour d’une tâche asynchrone pour attendre le retour. Plusieurs techniques existaient entre la preview de l’Async CTP avec « GeneralThreadAffineContext », l’ « AsyncContext » du packge NuGet Nito.AsyncEX, c’est bien celle proposé par Microsoft la plus usité :

class Program
{
    static void Main(string[] args)
    {
        MainAsync(args).GetAwaiter().GetResult();
    }

    static async Task MainAsync(string[] args)
    {
        Bootstrapper bs = new Bootstrapper();
        var list = await bs.GetList();
    }
}

Avec C# 7.1, l’appel est nettement plus simple

class Program
{
    static async Task Main(string[] args)
    {
        Bootstrapper bs = new Bootstrapper();
        var list = await bs.GetList();
    }
}

Literal «default » et inférence de type

Le mot clé « default » est déjà particulièrement utile pour affecter une valeur par défaut à un géneric de type T dont on ne sait d’avance si c’est un type référence ou valeur. Ce mot clé peut par ailleurs être utilisé avec n’importe quel type managé comme default(string), default(int) ou default(int ?)

Avec C# 7.1, « default » peut être utilisé comme littéral si le compilateur peut faire un inférence de type. Autrement dit, au lieu d’écrire « default(T) », on peut littéralement écrire « defaut » si le compilateur a suffisamment d’information. Le code devient ainsi plus concis et clair ; cela marchant pour de nombreux cas comme la déclaration de valeurs par défaut de paramètre optionnel, le retour de méthodes, l’initialisation ou assignation de variables, etc .

public class Point
{
    public double X { get; }
    public double Y { get; }

    public Point(double x, double y)
    {
        X = x;
        Y = y;
    }
}

public class LabeledPoint
{
    public double X { get; private set; }
    public double Y { get; private set; }
    public string Label { get; set; }

    // Providing the value for a default argument:
    public LabeledPoint(double x, double y, string label = default)
    {
        X = x;
        Y = y;
        this.Label = label;
    }

    public static LabeledPoint MovePoint(LabeledPoint source,
        double xDistance, double yDistance)
    {
        // return a default value:
        if (source == null)
            return default;

        return new LabeledPoint(source.X + xDistance, source.Y + yDistance,
        source.Label);
    }

    public static LabeledPoint FindClosestLocation(IEnumerable<LabeledPoint> sequence,
        Point location)
    {
        // initialize variable:
        LabeledPoint rVal = default;
        double distance = double.MaxValue;

        foreach (var pt in sequence)
        {
            var thisDistance = Math.Sqrt((pt.X - location.X) * (pt.X - location.X) +
                (pt.Y - location.Y) * (pt.Y - location.Y));
            if (thisDistance < distance)
            {
                distance = thisDistance;
                rVal = pt;
            }
        }

        return rVal;
    }

    public static LabeledPoint ClosestToOrigin(IEnumerable<LabeledPoint> sequence)
        // Pass default value of an argument.
        => FindClosestLocation(sequence, default);
}

Inférence du nom des éléments dans un type.

C# 7.0. a introduit les tuples. Lors de leur initialisation d’un tuple, les noms souhaités pour ses éléments sont généralement ceux des variables utilisés comme dans l’exemple suivant

string nom = "Fabrice JEAN-FRANCOIS";
int age = 26;
var personne = (nom: nom, age: age);

 

Avec C# 7.1, les noms d’éléments de tuple peuvent désormais être déduits à partir de variables utilisés :

string nom = "Fabrice JEAN-FRANCOIS";
int age = 26;
var personne = (nom, age); // le nom des elements du tuple seront « nom » et « age »

Génération d’assembly de référence

Le compilateur peut générer des assemblies de référénce uniquement via /refout et refonly.

Visual Studio 2015, Windows 10 et Universal Apps

C’est officiel, Windows 10 sera releasé le 29 juillet dans 190 pays, quelle bonne nouvelle.
Mais cette nouvelle ne vient pas seule. La version 2015 de Visual Studio est prévue pour le 20 juillet.

Equipé du fringant C# 6 (cf. Post sur les nouveautés C# 6), du beau Framework .NET 4.6 c’est tout un nouveau monde qui s’offre aux développeurs.

Pour ceux qui n’auraient pas suivi, voilà à quoi vous attendre.

En gestation depuis des années, nous aurons enfin droit au compilateur Roslyn. La Rolls de ce qui est faisable en matière de compilateur, les développeurs Java/Oracle ont de quoi être jaloux. Les programmeurs auront non seulement un accès réel au compilateur, pourront imaginer les choses les plus folles avec ses arbres d’expression et offres fonctionnalités, mais pourront aussi avoir des possibilités de refactoring très puissante. La fonctionnalité est d’ailleurs désormais prise en charge pour VB.NET

Azure, vous aimez ? Comment développez-vous pour Azure ? Avec un Visual Studio classique ou avec la version Online Monaco » ? Application en ASP.NET, PHP, NodeJS, TypeScript, Visual Studio Monaco c’est déjà tout cela.
La version 2015 reposant sur Roslyn, les modifications de code permettront une visualisation immédiate dans le navigateur sans nécessiter une compilation ; de quoi espérer une généralisation de l’IDE pour le développement Cloud.

Visual Studio 2015, c’est aussi l’amélioration de la création des Universal Apps. Vous savez, ces applications que vous codez une fois et qui peuvent se déployer aussi bien sur Windows Phone que sur tablette/ordinateur Windows ; leur création est grandement facilitée grâce au couple Windows 10/Visual Studio 2015.

Chez Microsoft, on parle désormais d’UWP pour Universal Windows Plateform. Autrement dit une plateforme de développement commune à tous les Windows, c’est à dire PC, Phone, tablette et même XBOX.

UWP permettra de faire fonctionner des applications universelles identifiées par le sigle UAP (Universal Application).

Un seul core dans l’OS, donc un seul store (jusqu’alors les stores étaient distincts) et des applications communes. Pour que vous compreniez bien, l’UAP doit être considéré comme un super ensemble de WinRT que vous deviez connaître jusqu’alors pour le développement d’application 8.1
Grâce à l’UAP et à UWP, les développeurs peuvent simplement cibler un grand nombre de plateforme et devicesc car l’UAP permet la mise en commun des fonctionnalités métiers aisi que des interfaces graphiques.

J’imagine la question… Mais les tailles d’écran ne sont pas les mêmes, comment est-ce possible ? Microsoft propose une nouvelle fonctionnalité, l’Adaptative UX (User Experience).

Adaptative UX est un ensemble de contrôles qui s’adaptent du plus petit au plus grand écran, tout en gérant souris, clavier et écran tactile et interaction utilisateur. Autrement dit, en fonction de l’appareil et du type d’action, l’expérience utilisateur n’est pas la même.

Windows 10 propose par ailleurs les API contracts. Lesquels permettent de savoir quelles fonctionnalités sont disponibles sur un appareil donné ce qui peut s’avérer fort pratique pour proposer des fonctionnalités adaptables en fonction des devices.

Mais ce n’est pas tout, Windows 10 étant gratuit pour ceux possédant un Windows 7, 8, 8.1 ou un Windows Phone 8.1, le nombre d’appareils équipés de Windows devrait avoisiner les 1 milliard selon Microsoft. Or beaucoup de personnes se plaignent du store Microsoft qui ne serait pas assez fourni en termes de logiciels.
Ce n’est pas la faute de l’éditeur qui poussent les développeurs sur sa plateforme (le prix d’inscription est nettement inférieur à ceux de Google et surtout Apple) et pour remédier au problème, la solution choisie laisse rêveur : des outils pouvant permettre aux éditeurs et développeurs d’application de convertir du code existant , y-compris sur d’autres plateforme, en code pour plateforme universelle.

Il y a ainsi Centennial pour convertir des applications Win32 et Win64 classiques en applications universelles. Il y a aussi Islandwoods qui convertit des applications iOS (Microsoft a fait la conversion de Candy Crush en live devant un public médusé), ainsi qu’Astoria, pour Android.

Les Tools for Apache Cordova intégrés dans Visual 2015 RC

Complètement génial. Les Tools for Apache Cordova seront intégrés dans VS 2015 Release Candidate !

Cela signifie quoi ? Tout simplement que vous pourrez créer des applications compatibles iPhone, Android, Windows Phone, BlackBerry, Bada, WebOS, etc à partir de Visual Studio.

Pour ceux qui ne connaissent pas Cordova, c’est un concurrent de notre cher Xamarin, sauf qu’on y code exclusivement en HTML, CSS  et Javascript (avec tous les frameworks qui vont avec).

Plus d’information sur le site de microsoft

Visual Studio Code

Quel passionné de code Microsoft n’a pas dans des temps reculés rêvé de répondre à un aficionados Java que lui aussi, son code pouvait tourner ailleurs que sur environnement Microsoft ?

Qui se rappelle du début du millénaire où noyer dans du COM on espérait la venu de .NET. Que de chemin parcouru depuis cette époque. La CLI a permis à .NET ne tourner sur d’autres plateformes, comme Linux grâce à Mono.

Et désormais, c’est officiel, le nouveau venu « Visual Studio Code » permettra l’édition de code sous environnement Windows, Linux et également OS X.

Certes, toutes les fonctionnalités de Visual Studio ne seront pas présentes, mais c’est bien une démonstration d’ouverture totale de l’éditeur. L’effet « Azure », où l’on peut choisir son OS, utilisé des outils tiers, y est assurément pour quelque chose.

Visual Studio 2012 et C++ 11 (C++0x)

C++0x a mis du temps a sortir puis l’année dernière en août, grande nouvelle, approuvé unanimement. Portant désormais le nom de C++11 il apporte de grand changement par rapport à l’ancienne norme (datant de 2003).

Nouveautés dans le langage, nouveautés dans la bibliothèque standard mais également  les bibliothèques du technical report 1 (Kisako ? Le technical report 1 est un document proposant des additions à la bibliothèque standard : has tables, expressions régulières, smart pointers, etc. Sorti en 2003, nombre de ces additions ont été implémentées par les vendeurs au point où la plupart font désormais partis du standard officiel C++11).

Pourquoi ce post ? Parce ce que Visual Studio 2012 (anciennement nommé VS 2011) est en release candidate et qu’il apporte des nouveautés à l’implémentation partielle de C++11  sous VS2010 !!

Voici la liste, probablement non exhaustive de ces nouveautés conformes à C++ 11 :

*       rvalue references en version 2.1 <http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1138>  par rapport à la 2.0
*       lambdas en version 1.1 <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2927.pdf>  par rapport à la 1.0.
*       decltype en version 1.1 <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3276.pdf>  par rapport à la 1.0

*       Amélioration d’Alignment (mais non complet) <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf>
*       Enumérateurs fortement typés <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf>
*       Forward declared enums <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2764.pdf>
*       Standard layout and trivial types <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm>
*       Atomics <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html>
*       Strong compare and exchange <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2748.html>
*       Bi-directional fences <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2752.htm>
*       Data-dependency ordering <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2664.htm>
*       Range-based for loop <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2930.html>

Gérer les hiérarchies de branches dans Visual Studio

Afin de gérer les hiérarchies de branches dans Visual Studio, après toute opération de Branch, il faut penser à convertir le dossier.

Imaginons un Team Project ARCHITECTURE ayant une application dénommée Magma ayant un répertoire Main contenant le tronc commun de développement.

Imaginons par ailleurs que vous ayez un autre répertoire Magma/Branches et que vous souhaitiez créer la branche v5.7.0 à partir du Main et l’apercevoir sous forme de hiérarchie.

Il suffit d’appliquer la méthode suivante :

1 – A partir du Source Control Explorer, aller sur $/ ARCHITECTURE/MAGMA/Main, bouton droit -> Branching and Merging -> Branch

2 – Dans Target indiquer $/ARCHITECTURE/MAGMA/Branches/v5.7.0, cliquer sur OK

3 – Faire un check-in:commit

4 – Une fois l’opération effectuée, aller sur $/ ARCHITECTURE/MAGMA/Branches/v5.7.0, bouton droit -> Branching and Merging -> Convert to Branch

Idéalement, faire cette opération également sur $/ ARCHITECTURE/MAGMA/Main.

Désormais lors d’un bouton droit-> Branching and Merging, on a désormais le menu View Hierarchy ; -)

Debogage à distance avec VS 2010

Les fonctionnalités de Débogage à distance sont véritablement pratiques pour savoir ce qui se passe sur un poste distant. Microsoft fournit l’installation d’un Remote Debuger (http://www.microsoft.com/downloads/fr-fr/details.aspx?familyid=60ec9d08-439b-4986-ae43-0487eb83c09e), une version « light » de ce que propose Visual Studio, pour permettre de déboguer des machines distantes, notamment des serveurs.

L’installation est on ne peut plus simple; on a le choix d’exécuter le Remote Debugger sous la forme d’un service (tournant sur un compte et pouvant aller jusqu’à accepter tout type d’utilisateur distant. Dans ce dernier mode, on ne peut toutefois que faire du debugage natif) ou sous la forme d’un programme.

Nous conseillons vivement cette dernière option pour du debugage sur des serveurs car cela ne devrait être que très occasionnel.

 

Configuration du Remote Debuger

 

Lors de l’installation/configuration, une seule option est disponible: configurer ou non le Remote Debugger en tant que service. Dans ce mode, le Remote Debugger est toujours actif et accessible à distance.

Le compte par défaut proposé est LocalSystem, ce qui est judicieux mais en même temps très ouvert.

Local System est un compte Built-In donnant des privilèges élevés sur l’ordinateur local et qui permet d’agir sur le réseau comme s’il s’agissait de l’ordinateur lui-même. Il n’y a pas besoin de mot de passe.

Lors de la configuration, il vous est possible de configurer un autre compte mais ses privilèges doivent avoir « Ouvrir une session en tant que service ». Microsoft propose par ailleurs que ce compte soit membre du groupe Administrateurs.

 

Options du Remote Debuger

Lancer le programme manuellement, puis allez dans Options. Le serveur porte un nom de la forme user@machine, plus précisément le user précise un domaine.

En mode Authentification Windows, on peut se permettre n’importe quel type de débugage ; le bouton « Autorisations » permet d’indiquer les comptes ayant le droit de deboguer.

Vous noterez l’option « Aucune authentification (natif uniquement) » et « Permettre à tous les utilisateurs de déboguer » qui permet à n’importe qui se connecter et deboguer, mais des applications natives seulement. Ce mode est à proscrire, d’autant plus que votre machine peut se trouver, pardonnez l’expression, en milieu « hostile » et soumise à attaque (en clair, faîtes cela chez vous, pas dans votre entreprise).

Par ailleurs, comme son nom l’indique, le debogage en mode natif

Classiquement, le compte qui debug sur une machine A en remote sur la machine B doit être le même… si possible. Malheureusement, ce n’est absolument pas le cas si A est dans un domaine et B dans un autre.

 

Debogage en interdomaine

Les choses se compliquent lorsque l’on veut déboguer à distance une machine hébergée dans un différent domaine. Rajoutons une contrainte qui a son importance, lorsque les deux domaines en question ne sont pas approuvés. Ce cas de figure qui peut vous sembler bizarre arrive bien plus fréquemment qu’on ne le croit.

Imaginons un environnement de test ou recette possédant son propre domaine, son propre AD, ses propres contraintes de sécurité ; ceci afin d’éviter tout télescopage possible. Il n’y a aucune raison de faire un domaine de production approuver un domaine de test/recette. Mais il est en revanche possible d’imaginer un développeur sur son réseau de développement (donc un environement réel, d’entreprise) nécessitant un débugage sur le domaine test/recette car un bug ne se produit que dans cet environement. Sans cette capacité de débogage, son bug ne peut être résolu et son application ne vas pas en prod.

Bref, lorsque les domaines ne sont pas approuvés, on peut choisir le débogage natif (non intéressant pour du débogage managé) mais celui-ci exige, pour des actions interdomaines de permettre à tout le monde de pouvoir se connecter à machine créant ainsi un trou de sécurité.

Il existe néanmoins une solution, ou plutôt 2 solutions.

Option 1

La première exige de jouer avec les Local Security Policy (Stratégie de sécurité locale). Dans le panneau de configuration, outils d’administration, si on lance l’application, il nous est possible (pour peu que l’on possède les droits suffisants) de changer la façon dont un compte local s’expose à l’extérieur en terme de sécurité.

Dans la section « Local Policies », « Security Options », changer la clé « Network access: sharing and security model for local accounts » de « Guest only – local users authentivcate as Guest » à « Classic – local users authenticate as themselves ».

En faisant ce réglage, on indique qu’un compte local à la machine sur un réseau se présente en tant que lui-même. Cette option est classique lorsque vous faite un Workgroup de machine et non pas un domaine. Pour permettre à un compte d’accéder à un partage par exemple, il suffit de dupliquer ce compte ; même user, même password; pour que l’accès soit autorisé

Le Remote Debuging exigeant une communication dans les deux sens, il vous faut faire ce réglage sur les 2 machines impliquées dans la communication.

Cette option fonctionne bien mais souffre d’une grosse limitation… On se retrouve à modifier des réglages de sécurité sur les 2 machines impliquées. Lorsque l’une d’en être elle est une serveur, c’est une sacré limitation car on augmente la surface d’attaque. Des problèmes peuvent surgir au niveau partage et DCOM et quelqu’un à distance peut s’authentifier avec votre compte plutôt qu’en Guest. Par ailleurs, il faut se soucier d’avoir un compte en double avec un mot de passe similaire pour que cela fonctionne (on peut faire correspondre un compte de domaine, même user/password, à un compte local).

Option 2

L’option 2 est beacoup plus belle… Et beaucoup plus simple aussi (sauf si l’on se met à déplacer le répertoire utilisateur AppData sur le réseau. Nous préciseronts ce point par la suite).

L’astuce consiste à utiliser une seule et unique commande : un runas ! Mais attention, ce runas est lancé dans un mode spécial.

Pour rappel, le runas permet l’exécution d’un programme sous le compte d’un autre utilisateur. Il suffirait a priori de faire un runas en précisant Visual Studio et banco, le remote debugger et VS 2010 se retrouve dans le même domaine et, comme dirait Dora, c’est gagné !!

Malheureusement, ce n’est pas aussi simple. Si on effectue un runas classique en précisant un user sur un autre domaine, malheureusement l’application que l’on lance va s’exécuter avec un compte… d’un autre domaine… et ceci en local .

Bref, vous l’aurez compris, ce n’est pas possible puisque votre machine locale respectera les contraintes de son propre domaine et n’autorisera pas un compte extérieur d’un autre domaine à lancer un programme sur votre machine.

Nous souhaiterions non seulement pourvoir utiliser notre poste local, dans son domaine et ses crédentials, tout en faisant en sorte que les communications réseaux s’effectuent sous l’identité d’un autre compte.

Si nous vous disions que la commande runas a été modifiée en ce sens par Microsoft en lui attribuant l’option netonly ?

Pour preuve, notez l’appel suivant (ligne de commande) qui permet de lancer Visual Studio sous le compte local de l’utilisateur et qui fait en sorte que les appels réseaux s’effectuent avec un autre compte sous un autre domaine.

 

runas /netonly /user:domain\user « C:\localapp\Apps\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe »

Le programme vous lancera une invite de commande vous permettant d’indiquer le mot de passe.

Votre Visual Studio va se lancer sous votre propre compte, mais tout appel réseau se déroulera sous le compte/domaine ayant été précisé via la balise netonly.

 

Attention, un bug peut se produire.

Ce bug peut se produire si votre ordinateur local, un ordinateur d’entreprise, a été configuré pour que votre profil soit sauvegardé sur le réseau. Dans ce cas de figure spécifique, Visual Studio se connectera au partage réseau avec le compte fourni par /netonly et pas votre compte de domaine.

Il en résultera l’erreur suivante :

 

Don’t panic… Là aussi il y a une astuce, modifier dans la registry le répertoire AppData

Dans « HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders », il suffit de renseigner un répertoire local temporaire de votre machine. Pensez bien à modifier cette clé de registre après coup….

Pourquoi choisir l’option 2 vis-à-vis de l’option 1 ? Ou l’inverse ?

Parce que vous ne créez pas un deuxième compte et parce que vous ne modifiez pas les stratégies de sécurité locale des machines que vous souhaitez déboguer, l’option 2 est nettement plus intéressante que l’option 1. Une simple ligne de commande…

Toutefois, dans le cas d’un répertoire AppData sauvegardé sur le réseau, c’est une histoire de préférence car les 2 solutions ont leurs inconvénients et avantages. L’option 2 reste locale mais exige des modifications de clé de registre (ce qui est sensible pour un non averti). L’option 1 demande des modifications de part et d’autre, augmente le risque de sécurité, mais aucune action sensible en base de registre n’est requise… A vous de juger.

 

Comment deboguer à distance

Toute les possibilités de debug à distance sont maintenant activées.

Lancez Visual Studio, puis vous pouvez par exemple cliquer sur Debug, puis Attach To Process

 

 

Noter le qualifier. Il correspond au compte et à l’adresse de la machine sur laquelle on souhaite se connecter.

Plus précisément, on notera qu’il s’agit de l’adresse proposée par le msvmon (le remote debugger).