Проект за настройка на .NET - Промяна на настройките на системния регистър

Имам клас, който променя ключовете на системния регистър ProxyEnable и ProxyServer на Internet Settings.

Ако използвам този клас в конзолно приложение и го стартирам, стойността се променя и мога да видя промените с помощта на regedit.

Сега частта, която не работи, е, че се опитвам да използвам този клас в клас на инсталатор, така че ключовете в системния регистър да се променят по време на инсталирането на моето приложение.

Ето кода за класа:

public class ProxySettings {
    [DllImport("wininet.dll")]
    public static extern bool InternetSetOption(IntPtr hInternet, int dwOption,
        IntPtr lpBuffer, int dwBufferLength);
    public const int INTERNET_OPTION_SETTINGS_CHANGED = 39;
    public const int INTERNET_OPTION_REFRESH = 37;
    static bool settingsReturn, refreshReturn;

    public void EnableProxy(string proxy) {
        RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
        registry.SetValue("ProxyEnable", 1);
        registry.SetValue("ProxyServer", proxy);

        settingsReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED,
            IntPtr.Zero, 0);
        refreshReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);
    }

    public void DisableProxy() {
        RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
        registry.SetValue("ProxyEnable", 0);
        registry.DeleteValue("ProxyServer", false);

        settingsReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED,
            IntPtr.Zero, 0);
        refreshReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);
    }
}

Ето моя клас на инсталатор:

[RunInstaller(true)]
public class WindowsServiceInstaller : Installer {
    public WindowsServiceInstaller() {
        ServiceProcessInstaller serviceProcessInstaller =
                           new ServiceProcessInstaller();
        ServiceInstaller serviceInstaller = new ServiceInstaller();

        //# Service Account Information
        serviceProcessInstaller.Account = ServiceAccount.LocalSystem;
        serviceProcessInstaller.Username = null;
        serviceProcessInstaller.Password = null;

        //# Service Information
        serviceInstaller.DisplayName = "Client Service";
        serviceInstaller.StartType = ServiceStartMode.Automatic;

        //# This must be identical to the WindowsService.ServiceBase name
        //# set in the constructor of WindowsService.cs
        serviceInstaller.ServiceName = "Client Service";

        this.Installers.Add(serviceProcessInstaller);
        this.Installers.Add(serviceInstaller);
    }

    public override void Commit(System.Collections.IDictionary savedState) {
        base.Commit(savedState);

        ServiceController controller = new ServiceController("Client Service");
        if(controller.Status != ServiceControllerStatus.Running) {
            controller.Start();
        }

        ProxySettings proxy = new ProxySettings();
        proxy.EnableProxy("127.0.0.1:8889");
    }

    public override void Uninstall(System.Collections.IDictionary savedState) {
        base.Uninstall(savedState);

        ProxySettings proxy = new ProxySettings();
        proxy.DisableProxy();
    }
}

При отмяната на Commit стартирам услугата, която работи добре, но по някаква причина не виждам промените в системния регистър.

Просто се уверете, че класът се инициализира и задейства, добавих

System.Diagnostics.Process.Start("http://www.microsoft.com");

към методите EnableProxy и DisableProxy. По време на инсталирането уебсайтът се отвори, а също и по време на деинсталирането, но регистърът остана непроменен.

какво правя грешно Защо ще работи като конзолно приложение, но не и в инсталатор?


person modernzombie    schedule 15.01.2010    source източник


Отговори (2)


Не мога да кажа със сигурност защо работи в приложението Console, а не в инсталатора, но забелязвам, че нито изхвърляте, нито изтривате директно ключа на системния регистър.

Опитайте да замените кода във вашия EnableProxy с този (и по подобен начин с DisableProxy) и вижте какво ще се случи:

using (RegistryKey registry = Registry.CurrentUser.OpenSubKey(
    "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true))
{
    registry.SetValue("ProxyEnable", 1);
    registry.SetValue("ProxyServer", proxy);
}

(Това е една от многото причини, поради които винаги трябва да изхвърляте IDisposable)

person Aaronaught    schedule 18.01.2010
comment
Благодаря за предложението Това обаче не направи разлика. - person modernzombie; 18.01.2010

Добре, разбрах какво става.

Бях настроил инсталатора да инсталира за всички. Опитах да инсталирам и избрах Just Me и се получи.

Предполагам, че има смисъл, тъй като задавах ключ на системния регистър за текущия потребител, но инсталирах за всички. Звучи ли правилно?

Както и да е, сега трябва да направя още малко тестове, за да видя дали софтуерът ще функционира правилно, ако е инсталиран за Just Me. Приложението е услуга на Windows.

person modernzombie    schedule 18.01.2010
comment
Това има смисъл - когато инсталирате За всеки, той ще се инсталира под профила на всички потребители, а не в текущия потребителски профил, така че Registry.CurrentUser не отива там, където искате. - person Aaronaught; 18.01.2010