5

これは私にとってやや未知の領域であるため、私の用語がオフになっている場合はご容赦ください。

を作成する必要があるプログラムがありますFolderShortcutMicrosoft にはC++ での作成方法に関するドキュメントがあり、その指示を C# に翻訳しようとしています。説明には、CoCreateInstance関数をパラメーターとして呼び出す必要があると記載さCLSID_FolderShortcutれていますが、これは、COM オブジェクトをインスタンス化していることを意味していると推測されます。このオブジェクトの CLSID は です{0AFACED1-E828-11D1-9187-B532F1E9575D}

COM タブからShell32.dll への参照を追加しようとしましたが、FolderShortcutオブジェクトが Intellisense に表示されません (タイプライブラリにないのでしょうか?)。も考えましたDLLImportが、もちろん、それはオブジェクトではなく関数へのアクセスのみを許可します。

.Net でこのオブジェクトにアクセスするにはどうすればよいですか?

4

4 に答える 4

12

コンパイル時にクラスをインポートしたくない場合は、Simon Mourierが説明しているように、Activator.

ProgIDオブジェクトの を取得している場合は、次を使用して型を取得します

Type comType = Type.GetTypeFromProgID("MyProg.ProgId");

それ以外の場合は、次のようにタイプを取得できますCLSID

Type comType = 
    Type.GetTypeFromCLSID(new Guid("0AFACED1-E828-11D1-9187-B532F1E9575D"));

この型を使用すると、以下を使用してコクラスのインスタンスを作成できるようになりましたActivator.CreateInstance

var instance = Activator.CreateInstance(comType);

基本的に、 を使用してメソッドを呼び出すことができるようになりType.InvokeMemberました。これは、オブジェクトがインターフェイスを実装している場合にのみ機能しIDispatchます。

ただし、特定の例では、インスタンスを にキャストできる必要があります。これにより、 COM オブジェクトSystem.Runtime.InteropServices.ComTypes.IPersistFileが呼び出されます。QueryInterfaceこのインターフェイスを使用すると、 のメンバーに簡単にアクセスできますIPersistFile

ここでさらに読み進めることができます。

于 2013-03-15T09:40:43.743 に答える
6

これは、フォルダのショートカットを作成できるようにするコードです。CoCreateInstanceは、(一般に)必要なCLSIDを持つGuid属性とComImport属性で装飾された単純なクラスを宣言することで置き換えることができます。呼び出しはnewCOMマジックを自動的に実行します。このコードでは、Shell32参照も必要ありません(または、必要に応じて、そこからIShellLink宣言を再利用できます)。

使用法:

static void Main(string[] args)
{
    CreateFolderShortcut(@"c:\temp", Path.GetFullPath("Shortcut to Temp"));
}

コード:

public static void CreateFolderShortcut(string path, string shortcutPath)
{
    CreateFolderShortcut(path, shortcutPath, null);
}

public static void CreateFolderShortcut(string path, string shortcutPath, string comment)
{
    if (path == null)
        throw new ArgumentNullException("path");

    IShellLink link = (IShellLink)new ShellLinkFolder();

    if (comment != null)
    {
        link.SetDescription(comment);
    }
    link.SetPath(path);

    IPersistFile file = (IPersistFile)link;
    file.Save(shortcutPath, false);
}

[ComImport]
[Guid("00021401-0000-0000-C000-000000000046")]
private class ShellLink
{
}

[ComImport]
[Guid("0AFACED1-E828-11D1-9187-B532F1E9575D")]
private class ShellLinkFolder
{
}

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("000214F9-0000-0000-C000-000000000046")]
private interface IShellLink
{
    void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out IntPtr pfd, int fFlags);
    void GetIDList(out IntPtr ppidl);
    void SetIDList(IntPtr pidl);
    void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName);
    void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
    void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
    void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
    void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
    void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
    void GetHotkey(out short pwHotkey);
    void SetHotkey(short wHotkey);
    void GetShowCmd(out int piShowCmd);
    void SetShowCmd(int iShowCmd);
    void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon);
    void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
    void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved);
    void Resolve(IntPtr hwnd, int fFlags);
    void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
}
于 2013-03-15T09:06:56.840 に答える
1

新しい参照を追加しようとしましたか?

  1. ソリューションエクスプローラーを開く
  2. C#プロジェクトを展開する
  3. 参照ノードを右クリックして、新しいCOM参照を追加します
于 2013-03-14T19:06:40.950 に答える
0

「新しいCOM参照の追加」を使用してCOMを追加しようとしたようです。これらは私が試したいことです:

  1. 最初に行うことは、COM DLL がコンピュータに登録されていることを確認することです。そうでない場合は、登録してから、[COM] タブを使用して再度追加してみてください。

  2. 64ビットマシンで実行していますか? また、プロジェクトのプロパティが AnyCPU に設定されていることを確認して、32 ビット COM を読み取れるようにしてください。

  3. アクセスしようとしている DLL と同等の相互運用機能があることを確認してください。通常、「Interop.YourDLLName.dll」のように名前が付けられます。その DLL への参照を追加すると、動作するはずです。

于 2013-03-14T19:11:35.873 に答える