예제 #1
0
        /// <include file='doc\ServiceBase.uex' path='docs/doc[@for="ServiceBase.Initialize"]/*' />
        /// <devdoc>
        ///     Starts the service object, creates the objects and
        ///     allocates the memory needed.
        /// </devdoc>
        /// <internalonly/>
        internal NativeMethods.ENTRY Initialize(bool multipleServices)
        {
            //Cannot register the service with NT service manatger if the object has been disposed, since finalization has been suppressed.
            if (this.disposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            if (multipleServices)
            {
                status.serviceType = NativeMethods.SERVICE_TYPE_WIN32_OWN_PROCESS;
            }
            else
            {
                status.serviceType = NativeMethods.SERVICE_TYPE_WIN32_SHARE_PROCESS;
            }
            status.currentState            = NativeMethods.STATE_START_PENDING;
            status.controlsAccepted        = 0;
            status.win32ExitCode           = 0;
            status.serviceSpecificExitCode = 0;
            status.checkPoint = 0;
            status.waitHint   = 0;

            NativeMethods.ENTRY entry = new NativeMethods.ENTRY();
            this.mainCallback      = new NativeMethods.ServiceMainCallback(this.ServiceMainCallback);
            this.commandCallback   = new NativeMethods.ServiceControlCallback(this.ServiceCommandCallback);
            this.commandCallbackEx = new NativeMethods.ServiceControlCallbackEx(this.ServiceCommandCallbackEx);
            this.handleName        = Marshal.StringToHGlobalUni(this.ServiceName);
            nameFrozen             = true;
            entry.callback         = (Delegate)mainCallback;
            entry.name             = this.handleName;
            return(entry);
        }
예제 #2
0
        /// <include file='doc\ServiceBase.uex' path='docs/doc[@for="ServiceBase.Run"]/*' />
        /// <devdoc>
        ///    <para>Provides the main entry point for an executable that
        ///       contains multiple associated services. Loads the specified services into memory so they can be
        ///       started.</para>
        /// </devdoc>
        public static void Run(ServiceBase[] services)
        {
            if (services == null || services.Length == 0)
            {
                throw new ArgumentException(Res.GetString(Res.NoServices));
            }

            // check if we're on an NT OS
            if (Environment.OSVersion.Platform != PlatformID.Win32NT)
            {
                // if not NT, put up a message box and exit.
                string cantRunOnWin9x      = Res.GetString(Res.CantRunOnWin9x);
                string cantRunOnWin9xTitle = Res.GetString(Res.CantRunOnWin9xTitle);
                LateBoundMessageBoxShow(cantRunOnWin9x, cantRunOnWin9xTitle);
                return;
            }

            IntPtr entriesPointer = Marshal.AllocHGlobal((IntPtr)((services.Length + 1) * Marshal.SizeOf(typeof(NativeMethods.ENTRY))));

            NativeMethods.ENTRY[] entries = new NativeMethods.ENTRY[services.Length];
            bool   multipleServices       = services.Length > 1;
            IntPtr structPtr = (IntPtr)0;

            for (int index = 0; index < services.Length; ++index)
            {
                entries[index] = services[index].Initialize(multipleServices);
                structPtr      = (IntPtr)((long)entriesPointer + Marshal.SizeOf(typeof(NativeMethods.ENTRY)) * index);
                Marshal.StructureToPtr(entries[index], structPtr, true);
            }

            NativeMethods.ENTRY lastEntry = new NativeMethods.ENTRY();
            lastEntry.callback = null;
            lastEntry.name     = (IntPtr)0;
            structPtr          = (IntPtr)((long)entriesPointer + Marshal.SizeOf(typeof(NativeMethods.ENTRY)) * services.Length);
            Marshal.StructureToPtr(lastEntry, structPtr, true);

            // While the service is running, this function will never return. It will return when the service
            // is stopped.
            bool res = NativeMethods.StartServiceCtrlDispatcher(entriesPointer);

            string errorMessage = "";

            if (!res)
            {
                errorMessage = new Win32Exception().Message;
                // This message will only print out if the exe is run at the command prompt - which is not
                // a valid thing to do.
                string cantStartFromCommandLine = Res.GetString(Res.CantStartFromCommandLine);

                if (LateBoundGetUserInteractive())
                {
                    string cantStartFromCommandLineTitle = Res.GetString(Res.CantStartFromCommandLineTitle);
                    LateBoundMessageBoxShow(cantStartFromCommandLine, cantStartFromCommandLineTitle);
                }
                else
                {
                    Console.WriteLine(cantStartFromCommandLine);
                }
            }
            foreach (ServiceBase service in services)
            {
                service.Dispose();
                if (!res && service.EventLog.Source.Length != 0)
                {
                    service.WriteEventLogEntry(Res.GetString(Res.StartFailed, errorMessage), EventLogEntryType.Error);
                }
            }
        }