Laden...

Programmaufruf aus Prozess soll mit anderem User gestartet werden

Erstellt von neyt vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.260 Views
N
neyt Themenstarter:in
5 Beiträge seit 2018
vor 5 Jahren
Programmaufruf aus Prozess soll mit anderem User gestartet werden

Hallo,

Ich starte ein Programm als Prozess unter einem anderen User als dieser, welche gerade angemeldet ist. Aus diesem Programm heraus werden PDF Dateien geöffnet. Das PDF Programm wird nun ebenfalls mit dem im Code festgelegten User gestartet.

Problem: Das PDF Programm kennt nun nicht die lokal installierten Drucker weil diese nur für den gerade angemeldeten User installiert sind.

Gibt es eine Möglichkeit dem Prozess die Info mitzugeben, dass nur der erste Prozess unter einem andere User gestartet werden soll?


MyProcess = new Process()
            {
                StartInfo = new ProcessStartInfo()
                {
                    UseShellExecute = false,
                    WindowStyle = ProcessWindowStyle.Normal,
                    CreateNoWindow = false,
                    FileName = @"C:\Program Files (x86)\...",
                    WorkingDirectory = @"C:\Program Files (x86)\...",
                    UserName = "xxx",
                    Domain = "xxx",
                    Password = GetSecureString("xxx")
                }
            };

Viele Grüße

K
166 Beiträge seit 2008
vor 5 Jahren

Siehe WindowsImpersonationContext Class

Und

Als Admin ausführen...

Denke das ist was du suchst.

N
neyt Themenstarter:in
5 Beiträge seit 2018
vor 5 Jahren

Vielen Dank für deine Antwort.

Ich starte den Prozess nun mit folgender Methode.


ProcessImpersonator.ImpersonateProcess_WithProfile(@"C:\Program Files (x86)\...", "xxx", "xxx", "xxx");

Das Programm wird auch unter dem angegebenen User gestartet. Nur das Problem aus dem 1. Beitrag bleibt weiterhin bestehen. Es wird ein PDF Reader aus dem gestarteten Programm heraus gestartet, der aber nicht unter dem übergebenen User laufen soll, sondern unter dem User der mein C# Programm startet.

Hoffe das ist einigermaßen verständlich.


public class ProcessImpersonator
    {
        [Flags]
        enum LogonFlags
        {
            LOGON_WITH_PROFILE = 0x00000001,
            LOGON_NETCREDENTIALS_ONLY = 0x00000002
        }

        [Flags]
        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)]
        struct ProcessInfo
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public uint dwProcessId;
            public uint dwThreadId;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        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)]
        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")]
        static extern bool CloseHandle(IntPtr h);

        ///
        /// This will use the Logon_NetCredentials_only value.
        /// Usefull for inter-domain scenario without trust relationship
        /// but the system does not validate the credentials.
        ///
        public static void ImpersonateProcess_NetCredentials(string appPath, string domain,
            string user, string password)
        {
            ImpersonateProcess(appPath, domain, user, password,
             LogonFlags.LOGON_NETCREDENTIALS_ONLY);
        }

        ///
        /// This will use the Logon_With_Profile value.
        /// Useful to get the identity of an user in the same domain.
        ///
        public static void ImpersonateProcess_WithProfile(string appPath, string domain,
            string user, string password)
        {
            ImpersonateProcess(appPath, domain, user, password, LogonFlags.LOGON_WITH_PROFILE);
        }

        ///
        /// Call CreateProcessWithLogonW
        ///
        private static void ImpersonateProcess(string appPath, string domain, string user,
            string password, LogonFlags lf)
        {
            StartupInfo si = new StartupInfo();
            si.cb = Marshal.SizeOf(typeof(StartupInfo));
            ProcessInfo pi = new ProcessInfo();

            //
            if (CreateProcessWithLogonW(user, domain, password,
            lf,
            appPath, null,
            0, IntPtr.Zero, null,
            ref si, out pi))
            {
                CloseHandle(pi.hProcess);
                CloseHandle(pi.hThread);
            }
            else
            {
                throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
            }
        }
    }

T
2.219 Beiträge seit 2008
vor 5 Jahren

Ohne das im zweiten Programm ebenfalls per Impersonate gearbeitet wird, wird sich das Problem nicht lösen lassen.
Denn hier startet das OS den Reader mit dem gleichen Benutzer wie der eigentliche Prozess, der den Reader startet.
Dabei werden die Benutzer eben "vererbt".

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

N
neyt Themenstarter:in
5 Beiträge seit 2018
vor 5 Jahren

Über den Start des PDF Readers habe ich leider keine Kontrolle, da dieser normalerweise direkt über ein zu öffnendes PDF Dokument gestartet wird.

Vermutlich werde ich es dann so lösen, dass ich den PDF Reader direkt nach dem 1. Prozessaufruf und einem Userwechsel "leer" starte.