9

CodeProject でこの記事を見つけました: http://www.codeproject.com/Articles/512956/NET-Shell-Extensions-Shell-Context-Menus

試してみるといいと思いましたが、F# で. そこで、次のコードを思いつきました。

open System
open System.IO
open System.Text
open System.Runtime.InteropServices
open System.Windows.Forms
open SharpShell
open SharpShell.Attributes
open SharpShell.SharpContextMenu

[<ComVisible(true)>]
[<COMServerAssociation(AssociationType.ClassOfExtension, ".txt")>]
type CountLinesExtension() =
    inherit SharpContextMenu.SharpContextMenu()

    let countLines =
        let builder = new StringBuilder()
        do 
            base.SelectedItemPaths |> Seq.iter (fun x -> builder.AppendLine(sprintf "%s - %d Lines" (Path.GetFileName(x)) (File.ReadAllLines(x).Length)) |> ignore  )
            MessageBox.Show(builder.ToString()) |> ignore

    let createMenu =
        let menu = new ContextMenuStrip()
        let itemCountLines = new ToolStripMenuItem(Text = "Count Lines")
        do
            itemCountLines.Click.Add (fun _ -> countLines)
            menu.Items.Add(itemCountLines) |> ignore
        menu

    override this.CanShowMenu() = true
    override this.CreateMenu() = createMenu

ただし、VS2012 では F# アセンブリへの署名がサポートされていないことに気付きました (記事のステップ 4.)。そのためには、キーを手動で作成し (コマンド プロンプトに「sn -k keyName.snk」と入力)、「プロジェクト プロパティ -> ビルド -> その他のフラグ」にフラグを追加する必要があることを学びました ( --keyfile:keyName.snk)。

私はまだこれをうまく実行できませんでした。さらに、作成者のアプリケーション (「シェル拡張機能のデバッグ」セクション) を使用すると、アセンブリに COM サーバーが含まれていないというエラーが表示されます。

コンポーネントの署名に何か問題があると思います。これを実行するのを手伝ってくれませんか?

4

2 に答える 2

15

F# アセンブリに署名する 1 つの方法は、AssemblyFileKeyAttribute属性を使用することです。

新しいモジュールを作成し、その中に入れます:

module AssemblyProperties

open System
open System.Reflection;
open System.Runtime.InteropServices;

[<assembly:AssemblyKeyFileAttribute("MyKey.snk")>]

do()

"MyKey.snk"プロジェクトディレクトリに対するキーへの相対パスはどこにありますか。

別の方法として、このMicrosoft Connectのバグ レポートにあるように、タブのフィールドに追加--keyfile:MyKey.snkする方法があります。Other FlagsProperties --> Build

いずれかのアプローチを使用します。runningsn -v myfsharpassembly.dllは、アセンブリがコンパイル後に有効であることをアサートします。

于 2013-08-10T17:35:39.323 に答える
0

おそらく問題は、アセンブリが「ComVisible」ではないことですか?

このライブラリを F# で次のように使用しています。

[<assembly:ComVisible(true)>]
[<assembly:AssemblyKeyFile("Key.snk")>]
do
   ()

つまり、最上位の do ブロックでアセンブリ レベルの属性を指定します。

于 2013-10-03T18:46:23.343 に答える