unhandle exception for normal user click not for admin user

abbas shaikh 1 Reputation point
2021-07-29T07:56:06.02+00:00

Hi,

I had popup a UI using win32 api creaprocessasuser. It works as I use admin user login. but it give two exception

  1. unhandled exception (in event handler)as a normal user try to launch pop UI.

Description: The process was terminated due to an unhandled exception.
Exception Info: System.ObjectDisposedException
at System.Windows.Forms.Control.CreateHandle()
at System.Windows.Forms.Form.CreateHandle()
at System.Windows.Forms.Control.get_Handle()
at System.Windows.Forms.ContainerControl.FocusActiveControlInternal()
at System.Windows.Forms.Form.SetVisibleCore(Boolean)
at System.Windows.Forms.Control.set_Visible(Boolean)
at System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext)
at System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext)
at System.Windows.Forms.Application.Run(System.Windows.Forms.Form)
at WinFormPrintDriverApp.Program.Main(System.String[])

Faulting application name: myapplication.exe, version: 1.0.0.0, time stamp: 0xab4b49da
Faulting module name: KERNELBASE.dll, version: 6.3.9600.19671, time stamp: 0x5e67335c
Exception code: 0xe0434352
Fault offset: 0x00013d28
Faulting process id: 0x1d84
Faulting application start time: 0x01d77a36c724e6f6
Faulting application path: c:\testpath\myapplication.exe
Faulting module path: C:\Windows\SYSTEM32\KERNELBASE.dll
Report Id: 0ae714c2-e62a-11eb-8106-0050568ffd89
Faulting package full name:
Faulting package-relative application ID:

what might be issue? Any help appreciated to resolve this isue.

Windows development | Windows API - Win32
Windows for business | Windows Server | User experience | Other
{count} votes

1 answer

Sort by: Most helpful
  1. abbas shaikh 1 Reputation point
    2021-07-29T12:28:19.323+00:00

    my code:

    public static bool StartProcessAsCurrentUser(string appPath, string cmdLine, string currentUserName, string workDir = null, bool visible = true)
    {
    var hUserToken = IntPtr.Zero;
    var startInfo = new STARTUPINFO();
    var procInfo = new PROCESS_INFORMATION();
    var pEnv = IntPtr.Zero;
    int iResultOfCreateProcessAsUser;

            startInfo.cb = Marshal.SizeOf(typeof(STARTUPINFO));
    
    
            try
            {
    
                if (!GetSessionUserToken(ref hUserToken, currentUserName))
                  {
                        throw new Exception("StartProcessAsCurrentUser: GetSessionUserToken failed.");
                    }
    
                uint dwCreationFlags = CREATE_UNICODE_ENVIRONMENT | (uint)(visible ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW);
                startInfo.wShowWindow = (short)(visible ? SW.SW_SHOW : SW.SW_HIDE);
                startInfo.lpDesktop = "winsta0\\default";
    
    
                if (!CreateEnvironmentBlock(ref pEnv, hUserToken, false))
                {
                    throw new Exception("StartProcessAsCurrentUser: CreateEnvironmentBlock failed.");
                }
    
    
                if (!CreateProcessAsUser(hUserToken,
                    appPath, // Application Name
                    cmdLine, // Command Line
                    IntPtr.Zero,
                    IntPtr.Zero,
                    false,
                    dwCreationFlags,
                    pEnv,
                    workDir, // Working directory
                    ref startInfo,
                    out procInfo))
                {
                    iResultOfCreateProcessAsUser = Marshal.GetLastWin32Error();
                    throw new Exception("StartProcessAsCurrentUser: CreateProcessAsUser failed.  Error Code -" + iResultOfCreateProcessAsUser);
                }
    
                iResultOfCreateProcessAsUser = Marshal.GetLastWin32Error();
            }
            catch(Exception ex)
            { 
                log.Info("StartProcessAsCurrentUser exeption msg:"+ex.Message +" stacktrace:"+ex.StackTrace); 
            }
            finally
            {
                CloseHandle(hUserToken);
                if (pEnv != IntPtr.Zero)
                {
                    DestroyEnvironmentBlock(pEnv);
                }
                CloseHandle(procInfo.hThread);
                CloseHandle(procInfo.hProcess);
            }
    

    return true;
    }
    }

    private static bool GetSessionUserToken(ref IntPtr phUserToken, string currentUserName)
    {

            var bResult = false;
            var hImpersonationToken = IntPtr.Zero;
            var activeSessionId = INVALID_SESSION_ID;
            try
            {
                ITerminalServicesManager manager = new TerminalServicesManager();
    
                using (ITerminalServer server = manager.GetLocalServer())
                {
                    server.Open();
                    foreach (ITerminalServicesSession session in server.GetSessions())
                    {
                        if (session.UserName.ToUpper() == currentUserName.ToUpper())
                        {
                            activeSessionId = (uint)session.SessionId;
    
                            break;
                        }
    
                    }
                }
    
    
                // If enumerating did not work, fall back to the old method
                if (activeSessionId == INVALID_SESSION_ID)
                {
                    activeSessionId = WTSGetActiveConsoleSessionId();
                }
                log.Info("Method GetSessionUserToken:  activeSessionId:" + activeSessionId);
                if (WTSQueryUserToken(activeSessionId, ref hImpersonationToken) != 0)
                {
                    // Convert the impersonation token to a primary token
                    bResult = DuplicateTokenEx(hImpersonationToken, 0, IntPtr.Zero,
                        (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, (int)TOKEN_TYPE.TokenPrimary, ref phUserToken);
    
                    CloseHandle(hImpersonationToken);
                }
                log.Info("GetSessionUserToken ends.");
            }
            catch(Exception ex)
            {
                log.Info("GetSessionUserToken exception:." + ex.Message);
            }
                return bResult;
        }
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.