Comment commencer un processus 32 bits en C # sans utiliser d'exécuter shell sur la machine 64 bits?

StackOverflow https://stackoverflow.com/questions/5812598

Question

J'ai une application Web .NET ASP sur une machine 64 bits qui a besoin d'exécuter une application legacy reporting 32 bits.

Quand je lance le programme avec UseShellExecute = false, le programme se termine avec le code de sortie:

-1073741502

Je ne peux pas utiliser Exécuter Shell parce que je dois exécuter le processus en tant qu'utilisateur différent. Pourtant, lorsque Shell Execute est vrai, le processus fonctionnera bien (même si je dois changer l'utilisateur que ASP .NET est en cours d'exécution sous).

Comment puis-je commencer à ce programme 32 bits en utilisant C # sans shell utilisation exécuter?

Voici le code que j'ai en ce moment:

var pxs = new ProcessStartInfo
{
    Arguments = arguments,
    CreateNoWindow = true,
    Domain = ConfigurationManager.AppSettings["reportUserDomain"],
    UserName = ConfigurationManager.AppSettings["reportUserName"],
    Password = GetSecureString(ConfigurationManager.AppSettings["reportUserPassword"]),
    LoadUserProfile = true,
    FileName = ConfigurationManager.AppSettings["reportRuntime"],
    UseShellExecute = false             

};

var px = new Process
{
    StartInfo = pxs
};

px.Start();
px.WaitForExit();
Était-ce utile?

La solution

What if you surrounded your code, including UseShellExecute = true, with the windows native "LogonUser" method? I've used this successfully in a few projects to do something similar.

[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern bool LogonUser(String lpszUserName, String lpszDomain,
    String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken

Fresh Click Media did an article about this and wrote a sample Impersonate class: --> http://www.freshclickmedia.com/blog/2008/11/programmatic-impersonation-in-c/

But for completeness, here's my version of it:

public class Impersonator : IDisposable
{
    private WindowsImpersonationContext _impersonatedUser = null;
    private IntPtr _userHandle;

    // constructor for a local account. username and password are arguments.
    public Impersonator(string username, string passwd)
    {
        _userHandle = new IntPtr(0);

        string user = username;
        string userDomain = "."; // The domain for a local user is by default "."
        string password = passwd;

        bool returnValue = LogonUser(user, userDomain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref _userHandle);

        if (!returnValue)
            throw new ApplicationException("Could not impersonate user");

        WindowsIdentity newId = new WindowsIdentity(_userHandle);
        _impersonatedUser = newId.Impersonate();
    }

    // constructor where username, password and domain are passed as parameters
    public Impersonator(string username, string passwd, string domain)
    {
        _userHandle = new IntPtr(0);

        string user = username;
        string userDomain = domain;
        string password = passwd;

        bool returnValue = LogonUser(user, userDomain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref _userHandle);

        if (!returnValue)
            throw new ApplicationException("Could not impersonate user");

        WindowsIdentity newId = new WindowsIdentity(_userHandle);
        _impersonatedUser = newId.Impersonate();
    }

    public void Dispose()
    {
        if (_impersonatedUser != null)
        {
            _impersonatedUser.Undo();
            CloseHandle(_userHandle);
        }
    }

    public const int LOGON32_LOGON_INTERACTIVE = 2;
    public const int LOGON32_LOGON_SERVICE = 3;
    public const int LOGON32_PROVIDER_DEFAULT = 0;

    [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
    public static extern bool LogonUser(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public extern static bool CloseHandle(IntPtr handle);
}

Using it in your case would be:

var domain = ConfigurationManager.AppSettings["reportUserDomain"];
var username = ConfigurationManager.AppSettings["reportUserName"];
var password = ConfigurationManager.AppSettings["reportUserPassword"];

using (Impersonator impersonator = new Impersonator(username, password, domain))
{
    var pxs = new ProcessStartInfo
    {
        Arguments = arguments,
        CreateNoWindow = true,
        LoadUserProfile = true,
        FileName = ConfigurationManager.AppSettings["reportRuntime"],
        UseShellExecute = true
    };

    var px = new Process
    {
        StartInfo = pxs
    };

    px.Start();
    px.WaitForExit();
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top