1

I tried to run clac.exe process before(or exactly when) windows(7 and xp) logon screen is shown.

I tried the gpedit.msc method(add calc.exe to Startup), onLogin/onLogout works only.

Then I created a new windows service,

code (most of my code from: Running a Form in Windows Logon Screen C#):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Runtime.InteropServices;

namespace WindowsService2
{
    public partial class Service1 : ServiceBase
    {
        public Service1()
        {
            InitializeComponent();
        }
        [DllImport("Kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.U4)]
        public static extern int WTSGetActiveConsoleSessionId();

        [DllImport("wtsapi32.dll", SetLastError = true)]
        static extern bool WTSQueryUserToken(UInt32 sessionId, out IntPtr Token);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private extern static bool DuplicateTokenEx(
            IntPtr hExistingToken,
            uint dwDesiredAccess,
            ref SECURITY_ATTRIBUTES lpTokenAttributes,
            SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
            TOKEN_TYPE TokenType,
            out IntPtr phNewToken);

        [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern bool CreateProcessAsUser(
            IntPtr hToken,
            string lpApplicationName,
            string lpCommandLine,
            ref SECURITY_ATTRIBUTES lpProcessAttributes,
            ref SECURITY_ATTRIBUTES lpThreadAttributes,
            bool bInheritHandles,
            uint dwCreationFlags,
            IntPtr lpEnvironment,
            string lpCurrentDirectory,
            ref STARTUPINFO lpStartupInfo,
            out PROCESS_INFORMATION lpProcessInformation);     
        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool AdjustTokenPrivileges(IntPtr tokenhandle,
                                 [MarshalAs(UnmanagedType.Bool)] bool disableAllPrivileges,
                                 [MarshalAs(UnmanagedType.Struct)]ref TOKEN_PRIVILEGES newstate,
                                 uint bufferlength, IntPtr previousState, IntPtr returnlength);
        [DllImport("advapi32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool OpenProcessToken(IntPtr ProcessHandle,
            UInt32 DesiredAccess, out IntPtr TokenHandle);
        public const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000;
        public const UInt32 STANDARD_RIGHTS_READ = 0x00020000;
        public const UInt32 TOKEN_ASSIGN_PRIMARY = 0x0001;
        public const UInt32 TOKEN_DUPLICATE = 0x0002;
        public const UInt32 TOKEN_IMPERSONATE = 0x0004;
        public const UInt32 TOKEN_QUERY = 0x0008;
        public const UInt32 TOKEN_QUERY_SOURCE = 0x0010;
        public const UInt32 TOKEN_ADJUST_PRIVILEGES = 0x0020;
        public const UInt32 TOKEN_ADJUST_GROUPS = 0x0040;
        public const UInt32 TOKEN_ADJUST_DEFAULT = 0x0080;
        public const UInt32 TOKEN_ADJUST_SESSIONID = 0x0100;
        public const UInt32 TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
        public const UInt32 TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY |
            TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE |
            TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT |
            TOKEN_ADJUST_SESSIONID);
        [StructLayout(LayoutKind.Sequential)]
        public struct SECURITY_ATTRIBUTES
        {
            public int nLength;
            public IntPtr lpSecurityDescriptor;
            public int bInheritHandle;
        }
        enum SECURITY_IMPERSONATION_LEVEL
        {
            SecurityAnonymous,
            SecurityIdentification,
            SecurityImpersonation,
            SecurityDelegation
        }

        public enum TOKEN_TYPE
        {
            TokenPrimary = 1,
            TokenImpersonation
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct TOKEN_PRIVILEGES
        {
            public UInt32 PrivilegeCount;
            public LUID Luid;
            public UInt32 Attributes;
            public LUID_AND_ATTRIBUTES[] Privileges;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct LUID
        {
            public uint LowPart;
            public int HighPart;
        }
        [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool LookupPrivilegeValue(string lpSystemName, string lpName,
            out LUID lpLuid);
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        struct STARTUPINFO
        {
            public Int32 cb;
            public string lpReserved;
            public string lpDesktop;
            public string lpTitle;
            public Int32 dwX;
            public Int32 dwY;
            public Int32 dwXSize;
            public Int32 dwYSize;
            public Int32 dwXCountChars;
            public Int32 dwYCountChars;
            public Int32 dwFillAttribute;
            public Int32 dwFlags;
            public Int16 wShowWindow;
            public Int16 cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }
        [StructLayout(LayoutKind.Sequential)]
        internal struct PROCESS_INFORMATION
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public int dwProcessId;
            public int dwThreadId;
        }
[Flags]
    enum CreateProcessFlags : uint
    {
        DEBUG_PROCESS = 0x00000001,
        DEBUG_ONLY_THIS_PROCESS = 0x00000002,
        CREATE_SUSPENDED = 0x00000004,
        DETACHED_PROCESS = 0x00000008,
        CREATE_NEW_CONSOLE = 0x00000010,
        NORMAL_PRIORITY_CLASS = 0x00000020,
        IDLE_PRIORITY_CLASS = 0x00000040,
        HIGH_PRIORITY_CLASS = 0x00000080,
        REALTIME_PRIORITY_CLASS = 0x00000100,
        CREATE_NEW_PROCESS_GROUP = 0x00000200,
        CREATE_UNICODE_ENVIRONMENT = 0x00000400,
        CREATE_SEPARATE_WOW_VDM = 0x00000800,
        CREATE_SHARED_WOW_VDM = 0x00001000,
        CREATE_FORCEDOS = 0x00002000,
        BELOW_NORMAL_PRIORITY_CLASS = 0x00004000,
        ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000,
        INHERIT_PARENT_AFFINITY = 0x00010000,
        INHERIT_CALLER_PRIORITY = 0x00020000,
        CREATE_PROTECTED_PROCESS = 0x00040000,
        EXTENDED_STARTUPINFO_PRESENT = 0x00080000,
        PROCESS_MODE_BACKGROUND_BEGIN = 0x00100000,
        PROCESS_MODE_BACKGROUND_END = 0x00200000,
        CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
        CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
        CREATE_DEFAULT_ERROR_MODE = 0x04000000,
        CREATE_NO_WINDOW = 0x08000000,
        PROFILE_USER = 0x10000000,
        PROFILE_KERNEL = 0x20000000,
        PROFILE_SERVER = 0x40000000,
        CREATE_IGNORE_SYSTEM_DEFAULT = 0x80000000,
    }

        [StructLayout(LayoutKind.Sequential)]
        public struct LUID_AND_ATTRIBUTES
        {
            public LUID Luid;
            public UInt32 Attributes;
        }

        public class RunProcess
        {
            public void log(string error)
            {
                throw new Exception(error);
            }
            public void StartProcess(string pathOrName)
            {
                Process winLogon = null;
                foreach (Process p in Process.GetProcesses())
                {
                    if (p.ProcessName.Contains("winlogon"))
                    {
                        winLogon = p;
                        break;
                    }
                }
                // grab the winlogon's token
                IntPtr userToken = IntPtr.Zero;
                if (!OpenProcessToken(winLogon.Handle, TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_DUPLICATE, out userToken))
                {
                    log("ERROR: OpenProcessToken returned false - " + Marshal.GetLastWin32Error());
                }
                WTSQueryUserToken((uint)WTSGetActiveConsoleSessionId(), out userToken);
                // create a new token
                IntPtr newToken = IntPtr.Zero;
                SECURITY_ATTRIBUTES tokenAttributes = new SECURITY_ATTRIBUTES();
                tokenAttributes.nLength = Marshal.SizeOf(tokenAttributes);
                SECURITY_ATTRIBUTES threadAttributes = new SECURITY_ATTRIBUTES();
                threadAttributes.nLength = Marshal.SizeOf(threadAttributes);
                // duplicate the winlogon token to the new token
                if (!DuplicateTokenEx(userToken, 0x10000000, ref tokenAttributes, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
                    TOKEN_TYPE.TokenImpersonation, out newToken))
                {
                    log("ERROR: DuplicateTokenEx returned false - " + Marshal.GetLastWin32Error());
                }

                TOKEN_PRIVILEGES tokPrivs = new TOKEN_PRIVILEGES();
                tokPrivs.PrivilegeCount = 1;
                LUID seDebugNameValue = new LUID();
                if (!LookupPrivilegeValue(null, "SeDebugPrivilege", out seDebugNameValue))
                {
                    log("ERROR: LookupPrivilegeValue returned false - " + Marshal.GetLastWin32Error());
                }

                tokPrivs.Privileges = new LUID_AND_ATTRIBUTES[1];
                tokPrivs.Privileges[0].Luid = seDebugNameValue;
                tokPrivs.Privileges[0].Attributes = 0x00000002;
                if (!AdjustTokenPrivileges(newToken, false, ref tokPrivs, 0, IntPtr.Zero, IntPtr.Zero))
                {
                    log("ERROR: AdjustTokenPrivileges returned false - " + Marshal.GetLastWin32Error());
                }
                PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
                STARTUPINFO si = new STARTUPINFO();
                si.cb = Marshal.SizeOf(si);
                si.lpDesktop = "Winsta0\\Winlogon";

                // start the process using the new token
                 if (!CreateProcessAsUser(newToken, "calc.exe", null, ref tokenAttributes, ref threadAttributes,true, (uint)CreateProcessFlags.CREATE_NEW_CONSOLE | (uint)CreateProcessFlags.INHERIT_CALLER_PRIORITY, IntPtr.Zero,"C:\\Windows\\System32", ref si, out pi))
                {
                    log("ERROR: CreateProcessAsUser returned false - " + Marshal.GetLastWin32Error());
                }

                Process _p = Process.GetProcessById(pi.dwProcessId);
                if (_p != null)
                {
                    log("Process " + _p.Id + " Name " + _p.ProcessName);
                }
                else
                {
                    log("Not Found");
                }
            }
      }           
        RunProcess r = new RunProcess();
        protected override void OnStart(string[] args)
        {
            r.StartProcess("calc.exe");
        }

        protected override void OnStop()
        {
            r.log("Stoped");
        }
    }
}

I installed the service by this line:

"C:\Windows\Microsoft.NET\Framework\v4.0.30319\installutil.exe" "c:\myservice.exe"

and now I did restart.

And then I checked if the process in running when the logon screen is shown and then I found out that there is no calculator window and there is no process named calc running.

And then I saw that "WindowsService2" is not running (on the taskmgr).

So I think that it can be fixed (I will not give up so fast, i have to finish it today), the question is:

Why its not working, what i need to do now to check why its not working?

I prefer:

There is any other way(or ways) to run process before logon screen(XP and Windows 7)?

(good answer is good example plus good explanation) :)

Edit:
the solution is in the installtion,
the installation log:

Installing assembly 'c:\WindowsService2.exe'.
Affected parameters are:
   logtoconsole = 
   logfile = c:\WindowsService2.InstallLog
   assemblypath = c:\WindowsService2.exe
No public installers with the RunInstallerAttribute.Yes attribute could be found in the c:\WindowsService2.exe assembly.
Committing assembly 'c:\WindowsService2.exe'.
Affected parameters are:
   logtoconsole = 
   logfile = c:\WindowsService2.InstallLog
   assemblypath = c:\WindowsService2.exe
No public installers with the RunInstallerAttribute.Yes attribute could be found in the c:\WindowsService2.exe assembly.
Remove InstallState file because there are no installers.


cant install because:

No public installers with the RunInstallerAttribute.Yes attribute could be found in the c:\WindowsService2.exe assembly.


what should i do now? :S
(i tried public static readonly RunInstallerAttribute Yes; and i even tried to run the cmd.exe as administrator)

Community
  • 1
  • 1

1 Answers1

-1

to start your application before start up there are three options:

you can add a new registry value by using mscorlib.dll(RegistryKey Class) functions and classes:

RegistryKey add = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
add.SetValue("Your App Name", "\"" + Application.ExecutablePath.ToString() + "\"");


other locations:

HKLM\Software\Microsoft\Windows\CurrentVersion\Run
HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKLM\Software\Microsoft\Windows\CurrentVersion\RunServices
HKLM\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce
HKCU\Software\Microsoft\Windows\CurrentVersion\Run
HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnceEx 

you can add youre application manually:

gpedit.msc->windows settings->script files(startup/shutdown)->startup->add..(choose youre application assembly file)

(all gpedit values are saved in the registry, you can also add your application assembly path by using GPMGMTLib(to make youre application more convenient))

you can move or copy youre application assembly file to:

Environment.GetFolderPath(Environment.SpecialFolder.Startup)

JC1
  • 11
  • 1
  • 3