6

うーん。さて、PInvokeを再訪した後、私はそれを完全には理解していないと確信しています:-/(ちょうどこの質問をしました

処理する必要のあるコードを説明しましょう。「参照の追加->COM->Microsoft Shell Controls and Automatation」を使用すると機能しますが、残念ながら、「C:\ Users \ Tim \ Documents \VisualStudio」のような参照がプロジェクトに配置されます。 2008 \ Projects \ Wing \ FileWing \ obj \ Debug \ Interop.Shell32.dll "

ごみ箱を掘り起こし、回収したいアイテムを探しています。これを成し遂げるためにPInvokeを介して戦わない方法はありますか?または、実行時にこのコードを使用できるようにするsystem32 / shell32.dllへの参照を取得するには?

private void recoverRecyclerBinEntry(string fileName, int size)
{
    try
    {
        Shell Shl = new Shell();
        Folder Recycler = Shl.NameSpace(10);

        // scans through all the recyclers entries till the one to recover has been found
        for (int i = 0; i < Recycler.Items().Count; i++)
        {
            FolderItem FI = Recycler.Items().Item(i);
            string FileName = Recycler.GetDetailsOf(FI, 0);
            if (Path.GetExtension(FileName) == "")
                FileName += Path.GetExtension(FI.Path);
            //Necessary for systems with hidden file extensions.

            string FilePath = Recycler.GetDetailsOf(FI, 1);
            string combinedPath = Path.Combine(FilePath, FileName);

            if (size == FI.Size && fileName == combinedPath)
            {
                Debug.Write("Match found. Restoring " + combinedPath + "...");
                Undelete(FI);
                Debug.WriteLine("done.");
            }
            else
            {
                Debug.WriteLine("No match");
            }
        }
    } 
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);
        Debug.WriteLine(ex.StackTrace);
    }
}

private bool Undelete(FolderItem Item)
{
    try
    {
        foreach (FolderItemVerb FIVerb in Item.Verbs())
        {
            if (
                (FIVerb.Name.ToUpper().Contains("WIEDERHERSTELLEN")) ||
                (FIVerb.Name.ToUpper().Contains("ESTORE")) ||
                (FIVerb.Name.ToUpper().Contains("NDELETE"))
                )
            {
                FIVerb.DoIt();
                return true;
            }
        }
        //execute the first one:
        Item.Verbs().Item(0).DoIt();
        return true;
    }
    catch (Exception)
    {
        Debug.WriteLine("ERROR undeleting");
        return false;
    }
}
4

1 に答える 1

7

現在、PInvokeとCOMInteropという2つの異なる概念を組み合わせています。

PInvokeを使用すると、マネージコード内からネイティブC関数にアクセスできます。これは、マネージコードでネイティブメソッドのマーシャル互換シグネチャを定義し、DllImport属性でマークすることによって機能します。ネイティブDLLへのメタデータ参照が必要ですが、持つことはできません。DLLは、Win32DLLの通常のロードルールを使用して実行時に検出されます。

COM相互運用機能を使用すると、マネージコードからCOM互換オブジェクトにアクセスできます。これは、COMインターフェイスのマーシャル互換のマネージ定義を取得し、いくつかの方法のいずれかでオブジェクトへの参照を取得することによって行われます。管理対象定義の取得は、多くの場合、COMコンポーネントのPIA(プライマリ相互運用機能アセンブリ)へのメタデータ参照を追加することによって実現されます。C#4.0までは、多くの作業を行わずにこの参照を削除することはできず、アプリケーションとともに展開する必要があります。

この特定の例では、PInvokeではなくCOM相互運用機能を使用しています。

于 2010-01-25T16:29:20.343 に答える