1

我正在尝试手动调用Installer.Install :

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>和其他参数,但没有一个有效。该文档没有帮助。期望什么?

4

1 回答 1

2

通过 .NET Reflector 运行 System.Configuration.Install.Installer 类会显示 Install 方法的以下内部实现:

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 传递给 base.Install 方法?

IDictionary dictionary = new Hashtable();

希望其中一些可以为您指明正确的方向。

于 2013-03-25T07:32:57.403 回答