Process.Start & empreint d'identité
L’objectif de ce document est d’expliquer dans un premier temps comment lancer une application externe (ou processus) à partir d’une application .NET, puis dans un second temps montrer comment lancer ce processus avec un utilisateur particulier.
1. Lancer l’application
avec l’utilisateur par défaut
//pour
lancer IE vous pouvez initialiser appPath à
"C:\Program Files\Internet //Explorer\iexplore.exe"
string appPath =
System.IO.Path.Combine(Environment.SystemDirectory,
"cmd.exe");
System.Diagnostics.Process.Start(appPath);
2. Lancer
l’application avec un utilisateur défini
Cette option peut être intéressante
dans le cas ou vous souhaitez lancer une application avez un utilisateur
privilégié ou contrer l’utilisateur par défaut ASPNET (empreint d’identité ou « impersonalisation »).
Si vous essayer par exemple de
faire System.Diagnostics.Process.Start(« une
application sécurisée »); sous ASP .NET, alors vous aurez une exception car
l’utilisateur qui sera utilisé est APSNET (droits réduits).
Vous-vous dites surement que la
solution serait donc d’utiliser la méthode « LogonUser »
de l’API « advapi32 » (cf. http://dotnet.mabulle.com/index.php/2005/12/02/24858-empreint-didentite-avec-cnet).
Si c’est le cas, alors c’est loupé, car la méthode « Process.Start »
utilise toujours le contexte de sécurité du processus parent ASP.NET. Pour résoudre cela il faudra
chercher du coté de la méthode « CreateProcessWithLogonW »
de la même API (advapi32).
- Créer une classe nommée « DLLClass » définie comme ceci :
using System;
using System.Runtime.InteropServices;
namespace WindowsApplication1
{
/// <summary>
///
Description résumée de DLLClass.
/// </summary>
public class DLLClass
{
[Flags]
public enum LogonFlags
{
LOGON_WITH_PROFILE = 0x00000001,
LOGON_NETCREDENTIALS_ONLY =
0x00000002
}
[Flags]
public enum CreationFlags
{
CREATE_SUSPENDED = 0x00000004,
CREATE_NEW_CONSOLE = 0x00000010,
CREATE_NEW_PROCESS_GROUP = 0x00000200,
CREATE_UNICODE_ENVIRONMENT
= 0x00000400,
CREATE_SEPARATE_WOW_VDM = 0x00000800,
CREATE_DEFAULT_ERROR_MODE = 0x04000000,
}
[StructLayout(LayoutKind.Sequential)]
public struct ProcessInfo
{
public IntPtr
hProcess;
public IntPtr
hThread;
public uint dwProcessId;
public uint dwThreadId;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct StartupInfo
{
public int cb;
public string
reserved1;
public string
desktop;
public string title;
public uint dwX;
public uint dwY;
public uint dwXSize;
public uint dwYSize;
public uint dwXCountChars;
public uint dwYCountChars;
public uint dwFillAttribute;
public uint dwFlags;
public ushort wShowWindow;
public short
reserved2;
public int
reserved3;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[DllImport("advapi32.dll",
CharSet=CharSet.Unicode, ExactSpelling=true, SetLastError=true)]
public static extern bool CreateProcessWithLogonW(
string principal,
string authority,
string password,
LogonFlags logonFlags,
string appName,
string cmdLine,
CreationFlags creationFlags,
IntPtr environmentBlock,
string currentDirectory,
ref StartupInfo
startupInfo,
out ProcessInfo
processInfo);
[DllImport("kernel32.dll")]
public static extern bool CloseHandle(IntPtr h);
public DLLClass()
{
//
//
TODO : ajoutez ici la logique du constructeur
//
}
}
}
- Exécuter votre application en faisant ceci au
niveau d’un click de bouton, dans la méthode Page_Load,
dans le Main ou n’importe où ;)
string strError =
"";
//DLLClass représente la class que vous avez ajoutez
DLLClass.StartupInfo _StartupInfo
= new DLLClass.StartupInfo();
DLLClass.ProcessInfo _ProcessInfo
= new DLLClass.ProcessInfo();
string strAppPath
= @"C:\Program Files\Internet Explorer\iexplore.exe";
if (DLLClass.CreateProcessWithLogonW("login",
"domain", "password",
DLLClass.LogonFlags.LOGON_WITH_PROFILE,
strAppPath, null,
0,
IntPtr.Zero, null,
ref _StartupInfo,
out _ProcessInfo))
{
DLLClass.CloseHandle(_ProcessInfo.hProcess);
DLLClass.CloseHandle(_ProcessInfo.hThread);
}
else strError
= string.Format("Code
error: {0}", Marshal.GetLastWin32Error());
/*/libre à vous d'afficher l'erreur
Console.WriteLine(strError);
//ou
label1.Text = strError;
//ou
MessageBox.Show(strError);
*/
Vous pouvez savoir qu’elle utilisateur a lancé l’application en faisant ceci :
string strUserName
= System.Security.Principal.WindowsIdentity.GetCurrent().Name;
Par dotnet, Mardi 6 Decembre 2005 à 17:01 GMT+2 dans .NET (article, RSS)





