Skip to content

Instantly share code, notes, and snippets.

@akrisiun
Created July 25, 2016 15:40
Show Gist options
  • Save akrisiun/0a7ec99fe167c72f2e0f0d6627941610 to your computer and use it in GitHub Desktop.
Save akrisiun/0a7ec99fe167c72f2e0f0d6627941610 to your computer and use it in GitHub Desktop.
ICatRegister cr = (ICatRegister) new StdComponentCategoriesMgr();
https://github.com/OpenLiveWriter/OpenLiveWriter/blob/69ea434f36a6f63cdc5c46286fe5ffb3279d7fee/src/managed/OpenLiveWriter.Interop/Com/ComHelper.cs
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace OpenLiveWriter.Interop.Com
{
/// <summary>
/// Helper functions for using and imlementing COM interfaces
/// </summary>
public class ComHelper
{
/// <summary>
/// Return the specified HRESULT to the caller (common HRESULT values are
/// defined in the ComTypes.HRESULT structure). The only way to do this is
/// by throwing an exception (see Nathan pg. 656 for rationale / code upon
/// which this implementation is based). Note that we could also accomplish
/// this by using [PreserveSig] in the interface definition but this would
/// make the interface definition specific to the implementation.
/// </summary>
public static void Return(int hResult)
{
throw new COMException(String.Empty, hResult);
}
public static bool SUCCEEDED(int hResult)
{
return hResult >= 0;
}
public static bool FAILED(int hResult)
{
return hResult < 0;
}
public static void Chk(int hResult)
{
if (FAILED(hResult))
Marshal.ThrowExceptionForHR(hResult);
}
/// <summary>
/// Query the specified service (which the passed source object knows about)
/// for the requested COM interface. This implementation assumes that the
/// source implements IServiceProvider, that the source knows about the
/// specified service, and that the service implements the requested
/// interface. If any of these conditions is not true the method will return
/// null and will Assert in Debug mode. This method should be used in cases
/// where the caller fully expects and assumes that it will work correctly
/// under all known scenarios.
/// </summary>
/// <param name="source">source object</param>
/// <param name="serviceID">SID of service to query</param>
/// <param name="desiredIID">requested interface</param>
/// <returns>reference to requested interface, null on failure</returns>
public static object QueryService(object source, Guid serviceID, Guid requestedIID)
{
// cast the source object to a service-provider
IServiceProvider sp =
source as IServiceProvider;
// if the source object isn't a service provider return null
if (sp == null)
{
return null;
}
// query for the requested interface
object obj = null;
try
{
sp.QueryService(ref serviceID, ref requestedIID, out obj);
}
catch (COMException e)
{
Debug.Assert(false, "QueryService failure: " + e.Message);
}
// return interface (returns null if interface not found)
return obj;
}
/// <summary>
/// Register the class as an implementor of the specified category
/// </summary>
/// <param name="guid">class guid</param>
/// <param name="categoryIID">category iid</param>
public static void RegisterImplementedCategory(
Guid clsGuid, Guid categoryIID)
{
// constants used for registration
const string CLSID = "CLSID";
const string REG_FMT = "B";
const string IMPLEMENTED_CATEGORIES = "Implemented Categories";
// create a sub-key for listing the categories we implement
RegistryKey rkCategories = Registry.ClassesRoot.CreateSubKey(
CLSID + @"\" +
clsGuid.ToString(REG_FMT) + @"\" +
IMPLEMENTED_CATEGORIES);
// write the implemented category
using (rkCategories)
rkCategories.CreateSubKey(categoryIID.ToString("B"));
/*
// "New school" COM-based method for registering as a category
// implementor. Why don't we use this? First, it is incompatible
// with Win95 and NT prior to SP3. Second, when trying to use it
// to unregister a category we got a mysterious FileNotFound exception
// that the ICatManager documentattion implies should never happen.
// This was enough to scare us off of the bus.....
//
ICatRegister cr = (ICatRegister) new StdComponentCategoriesMgr();
cr.RegisterClassImplCategories(
ref guid, 1, new Guid[] { categoryIID } );
*/
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment