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パラメーターには、文字列intKeyValuePairと文字列IDicitionary[]KeyValuePairが内部的に渡されているようです。

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

それがどのように管理されているのか正確にはわかりません。おそらく、ベースに渡すIDictionaryを初期化しているためです。ハッシュテーブルとしてメソッドをインストールしますか?

IDictionary dictionary = new Hashtable();

うまくいけば、これのいくつかはあなたを正しい方向に向けることができます。

于 2013-03-25T07:32:57.403 に答える