2013-03-25 2 views
0

Я пытаюсь вызвать Installer.Install вручную:Installer.Install (IDictionary stateSaver): Какой тип словаря ожидается?

ProjectInstaller installer = new ProjectInstaller(); 
installer.Install(new Dictionary<int, int>()); 

Проблема:

System.ArgumentException was unhandled. 
The value "_reserved_lastInstallerAttempted" is not of type "System.Int32" 
and cannot be used in this generic collection. 
     at System.ThrowHelper.ThrowWrongKeyTypeArgumentException(Object key, Type targetType) 
     at System.Collections.Generic.Dictionary`2.System.Collections.IDictionary.Add(Object key, Object value) 
     at System.Configuration.Install.Installer.Install(IDictionary stateSaver) 
     at CSShellExtContextMenuHandler.ProjectInstaller.Install(IDictionary stateSaver) in C:\Users\win7pro32bit\Documents\lab\CSShellExtContextMenuHandler\ProjectInstaller.cs:line 40 
     at Starter.Program.Main(String[] args) in C:\Users\win7pro32bit\Documents\lab\Starter\Program.cs:line 14 

В качестве параметра я попытался new Dictionary<int, int>, new Dictionary<string, string>, и другие, но ни один не работает. documentation не помогает. Что ожидается?

ответ

1

Запуск класса System.Configuration.Install.Installer через .NET Reflector показывает следующую внутреннюю реализацию метода Установка:

public virtual void Install(IDictionary stateSaver) 
{ 
    if (stateSaver == null) 
    { 
     throw new ArgumentException(Res.GetString("InstallNullParameter", new object[] { "stateSaver" })); 
    } 
    try 
    { 
     this.OnBeforeInstall(stateSaver); 
    } 
    catch (Exception exception) 
    { 
     this.WriteEventHandlerError(Res.GetString("InstallSeverityError"), "OnBeforeInstall", exception); 
     throw new InvalidOperationException(Res.GetString("InstallEventException", new object[] { "OnBeforeInstall", base.GetType().FullName }), exception); 
    } 
    int num = -1; 
    ArrayList list = new ArrayList(); 
    try 
    { 
     for (int i = 0; i < this.Installers.Count; i++) 
     { 
      this.Installers[i].Context = this.Context; 
     } 
     for (int j = 0; j < this.Installers.Count; j++) 
     { 
      Installer installer = this.Installers[j]; 
      IDictionary dictionary = new Hashtable(); 
      try 
      { 
       num = j; 
       installer.Install(dictionary); 
      } 
      finally 
      { 
       list.Add(dictionary); 
      } 
     } 
    } 
    finally 
    { 
     stateSaver.Add("_reserved_lastInstallerAttempted", num); 
     stateSaver.Add("_reserved_nestedSavedStates", list.ToArray(typeof(IDictionary))); 
    } 
    try 
    { 
     this.OnAfterInstall(stateSaver); 
    } 
    catch (Exception exception2) 
    { 
     this.WriteEventHandlerError(Res.GetString("InstallSeverityError"), "OnAfterInstall", exception2); 
     throw new InvalidOperationException(Res.GetString("InstallEventException", new object[] { "OnAfterInstall", base.GetType().FullName }), exception2); 
    } 
} 

Параметр stateSaver, кажется, получает передается строка, Int KeyValuePair и строка, IDicitionary [] KeyValuePair внутренне:

stateSaver.Add("_reserved_lastInstallerAttempted", num); 
stateSaver.Add("_reserved_nestedSavedStates", list.ToArray(typeof(IDictionary))); 

Я точно не знаю, как это управление этим. Может быть, потому, что они инициализируют IDictionary, они переходят на базу. Устанавливать метод как Hashtable?

IDictionary dictionary = new Hashtable(); 

Надеюсь, некоторые из них могут указать вас в правильном направлении.

+0

'new Hashtable()' сделал трюк, спасибо! –

+0

Добро пожаловать, рад, что это сработало. .NET Reflector делает свою магию еще раз! –

+0

Множество кода набора инструментов WiX было написано в NETFX v1.1 дня, поэтому старые классы коллекций распространены. :) –