Набор 'запускает параметры' на сервисной установке с.Net ServiceInstaller?

Строка

Cells(NextRow, "E").Value = olApt.recipients.Address 

должна быть заменена на

.Cells(NextRow, "E").Value = recip.Address 

Также имейте в виду, что Outlook Security может блокировать доступ к таким свойствам, как SenderEmailAddress или Recipients, если антивирусное приложение не установлено или устарело. См. https://docs.microsoft.com/en-us/office/vba/outlook/how-to/security/security-behavior-of-the-outlook-object-model

9
задан Jörg Battermann 17 March 2009 в 00:38
поделиться

5 ответов

Я нашел способ добавления параметров старта на сервисном установке:

Я бегаю как сервис

2
ответ дан 4 December 2019 в 10:34
поделиться

Это не возможно сделать в управляемом коде.

Но существует одно достойное решение все же. Если все, что Вы хотите, имеет тот же исполняемый файл для сервиса окон и GUI (наиболее распространенный сценарий). Вам даже не нужны параметры. Просто регистрация Основного метода для System.Environment.UserInteractive свойство и решает, что сделать...

static void Main(string[] args)
{
    if (System.Environment.UserInteractive)
    {
        // start your app normally
    }
    else
    {
        // start your windows sevice
    }
}
1
ответ дан 4 December 2019 в 10:34
поделиться

Параметры могут быть установлены P/Invoking ChangeServiceConfig API. Они появляются после заключенного в кавычки пути и имени файла к Вашему исполняемому файлу в lpBinaryPathName аргументе.

Параметры будут сделаны доступными для Вашего сервиса, когда он запустится через Основной метод:

static void Main(string[] args)

(Основной традиционно расположен в файле по имени Program.cs).

Следующие шоу, как Вы могли бы изменить установщик для вызова этого API после нормальных сервисных выполнений логики установки. Части этого, что, скорее всего, необходимо будет изменить, находятся в конструкторе.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration.Install;
using System.ComponentModel;
using System.Configuration.Install;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.ServiceProcess;
using System.Text;

namespace ServiceTest
{
    [RunInstaller(true)]
    public class ProjectInstaller : Installer
    {
        private string _Parameters;

        private ServiceProcessInstaller _ServiceProcessInstaller;
        private ServiceInstaller _ServiceInstaller;

        public ProjectInstaller()
        {
            _ServiceProcessInstaller = new ServiceProcessInstaller();
            _ServiceInstaller = new ServiceInstaller();

            _ServiceProcessInstaller.Account = ServiceAccount.LocalService;
            _ServiceProcessInstaller.Password = null;
            _ServiceProcessInstaller.Username = null;

            _ServiceInstaller.ServiceName = "Service1";

            this.Installers.AddRange(new System.Configuration.Install.Installer[] {
                _ServiceProcessInstaller,
                _ServiceInstaller});

            _Parameters = "/ThisIsATest";
        }

        public override void Install(IDictionary stateSaver)
        {
            base.Install(stateSaver);

            IntPtr hScm = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);
            if (hScm == IntPtr.Zero)
                throw new Win32Exception();
            try
            {  
                IntPtr hSvc = OpenService(hScm, this._ServiceInstaller.ServiceName, SERVICE_ALL_ACCESS);
                if (hSvc == IntPtr.Zero)
                    throw new Win32Exception();
                try
                {
                    QUERY_SERVICE_CONFIG oldConfig;
                    uint bytesAllocated = 8192; // Per documentation, 8K is max size.
                    IntPtr ptr = Marshal.AllocHGlobal((int)bytesAllocated); 
                    try
                    {
                        uint bytesNeeded;
                        if (!QueryServiceConfig(hSvc, ptr, bytesAllocated, out bytesNeeded))
                        {
                            throw new Win32Exception();
                        }
                        oldConfig = (QUERY_SERVICE_CONFIG) Marshal.PtrToStructure(ptr, typeof(QUERY_SERVICE_CONFIG));
                    }
                    finally
                    {
                        Marshal.FreeHGlobal(ptr);
                    }

                    string newBinaryPathAndParameters = oldConfig.lpBinaryPathName + " " + _Parameters;

                    if (!ChangeServiceConfig(hSvc, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE,
                        newBinaryPathAndParameters, null, IntPtr.Zero, null, null, null, null))
                        throw new Win32Exception();
                }
                finally
                {
                    if (!CloseServiceHandle(hSvc))
                        throw new Win32Exception();
                }
            }
            finally
            {
                if (!CloseServiceHandle(hScm))
                    throw new Win32Exception();
            }
        }

        [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
        private static extern IntPtr OpenSCManager(
            string lpMachineName,
            string lpDatabaseName,
            uint dwDesiredAccess);

        [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
        private static extern IntPtr OpenService(
            IntPtr hSCManager,
            string lpServiceName,
            uint dwDesiredAccess);

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
        private struct QUERY_SERVICE_CONFIG {
            public uint dwServiceType;   
            public uint dwStartType;
            public uint dwErrorControl;
            public string lpBinaryPathName;
            public string lpLoadOrderGroup;
            public uint dwTagId;
            public string lpDependencies;
            public string lpServiceStartName;
            public string lpDisplayName;
        }

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool QueryServiceConfig(
            IntPtr hService,
            IntPtr lpServiceConfig,
            uint cbBufSize,
            out uint pcbBytesNeeded);

        [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool ChangeServiceConfig(
            IntPtr hService,
            uint dwServiceType,
            uint dwStartType,
            uint dwErrorControl,
            string lpBinaryPathName,
            string lpLoadOrderGroup,
            IntPtr lpdwTagId,
            string lpDependencies,
            string lpServiceStartName,
            string lpPassword,
            string lpDisplayName);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CloseServiceHandle(
            IntPtr hSCObject);

        private const uint SERVICE_NO_CHANGE = 0xffffffffu;
        private const uint SC_MANAGER_ALL_ACCESS = 0xf003fu;
        private const uint SERVICE_ALL_ACCESS = 0xf01ffu;
    }
}
7
ответ дан 4 December 2019 в 10:34
поделиться

По какой-то странной причине моя структура QUERY_SERVICE_CONFIG не получала полное значение lpBinaryPathName, только первый символ. Изменение его на класс ниже, похоже, решило проблему. Полный код находится на http://www.pinvoke.net/default.aspx/advapi32/QueryServiceConfig.html

Изменить: Также обратите внимание, что это устанавливает «Путь к исполняемому файлу» службы Windows, но не устанавливает «Параметры запуска» службы Windows.

[StructLayout(LayoutKind.Sequential)]
public class QUERY_SERVICE_CONFIG
{
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
    public UInt32 dwServiceType;
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
    public UInt32 dwStartType;
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
    public UInt32 dwErrorControl;
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
    public String lpBinaryPathName;
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
    public String lpLoadOrderGroup;
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
    public UInt32 dwTagID;
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
    public String lpDependencies;
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
    public String lpServiceStartName;
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
    public String lpDisplayName;
}
1
ответ дан 4 December 2019 в 10:34
поделиться

Существует управляемый способ добавления параметров запуска к службам (не в разделе «Параметры запуска» / «Параметры запуска» консоли управления (services.msc), но в «Путь к исполняемому файлу» / «Pfad zur EXE-Datei», как это делают все собственные службы Windows).

Добавьте следующий код в свой подкласс System.Configuration.Install.Installer: (в C # -дружественном VB- Код)

'Just as sample
Private _CommandLineArgs As String() = New String() {"/Debug", "/LogSection:Hello World"}

''' <summary>Command line arguments without double-quotes.</summary>
Public Property CommandLineArgs() As String()
  Get
    Return _CommandLineArgs
  End Get
  Set(ByVal value As String())
    _CommandLineArgs = value
  End Set
End Property

Public Overrides Sub Install(ByVal aStateSaver As System.Collections.IDictionary)
  Dim myPath As String = GetPathToExecutable()
  Context.Parameters.Item("assemblypath") = myPath
  MyBase.Install(aStateSaver)
End Sub

Private Function GetPathToExecutable() As String
  'Format as something like 'MyService.exe" "/Test" "/LogSection:Hello World'
  'Hint: The base class (System.ServiceProcess.ServiceInstaller) adds simple-mindedly
  '      a double-quote around this string that's why we have to omit it here.
  Const myDelimiter As String = """ """ 'double-quote space double-quote
  Dim myResult As New StringBuilder(Context.Parameters.Item("assemblypath"))
  myResult.Append(myDelimiter)
  myResult.Append(Microsoft.VisualBasic.Strings.Join(CommandLineArgs, myDelimiter))
  Return myResult.ToString()
End Function

Удачи!

чха

3
ответ дан 4 December 2019 в 10:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: