Acessing COM Interop from Python - c#

I want to acess a COM interop functionality written in c# from Python. I have the following code written in c# which defines the COM interop functionality and is compiled as a .dll and registered using regasm.exe. This seems to work fine.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace ComInteropDemo
{
/// <summary>
/// implementation of the method com interface
/// </summary>
[Guid("1C9E938A-9BF5-4A42-B795-A4AC2B1E7AC0")]
[ProgId("Test.Test.ComInteropClass")]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(IComInteropClass))]
[ComVisible(true)]
public class ComInteropClass : IComInteropClass
{
/// <summary>
/// Reads a text
/// </summary>
/// <param name="text">The text (as out parameter)</param>
/// <returns>true if successful</returns>
public bool ReadText(out string text)
{
text = "Hello from Com Interop";
return true;
}
/// <summary>
/// Writes a text to a file
/// </summary>
/// <param name="text"></param>
/// <returns>true if successful</returns>
public bool WriteText(string text)
{
string fileName = Path.Combine(Path.GetTempPath(), "ComInteropDemoOutput.txt");
try
{
File.WriteAllText(fileName, text);
}
catch (IOException)
{
return false;
}
return true;
}
}
}
The problem is, that I want to acess the COM interop functionality from python (client side), I try to use the comtypes library for that and I try to load the COM interop demo using the following code:
from comtypes.client import CreateObject
comobject = CreateObject("Test.Test.ComInteropClass")
Problem is, it throws an errors saying:
"AttributeError: module 'comtypes.gen.ComInteropDemo' has no attribute 'IComInteropClass'"
It seems I have to define the attribute IComInteropClass in the c# definition of the COM functionality, but I do not know how. Any help on this would be very much appreciated!

Related

How to generate documentation with references using docfx

I am trying to generate documentation for .net project (multi layer). But I am not able to see reference class information in generated documentation with docfx.
Eg:
using Microsoft.AspNetCore.Mvc;
using ServiceLayer;
namespace testApplication.Controllers
{
/// <summary>
/// Home COntroller
/// </summary>
public class HomeController : Controller
{
/// <summary>
/// Index Method
/// </summary>
/// <returns></returns>
public IActionResult Index()
{
Class1 cls1 = new Class1();
//calling testmethod.
string abc = cls1.testmethod("testing");
return View();
}
}
}
the above code is referencing ServiceLayer. using that I am calling testmethod. But Documentation is not showing, this class is using ServiceLayer Reference.
and is there any way to show comments in "//" also in the documentation
Check the following link: https://dotnet.github.io/docfx/spec/metadata_dotnet_spec.html
The metadata defined for .net include the declarations of:
Namespaces
Types, including class, struct, interface, enum, delegate
Type members, including field, property, method, event
All these are annotated with the /// XML comment. Since this is an api descriptor, it makes sense to include only those

Unity "Can not play a disabled audio source"

I have been trying to play an effect sound whenever the function is called, however I keep getting the notification "Cannot play a disabled audio source". I also noticed that the sound plays on awake even though I have it turned off. Here's what my EffectController class looks like
//--------------------------------------------------------------------------------------------------------------------
// <copyright file="EffectController.cs" company="ShinjiGames">
// Copyright (c) ShinjiGames LLC 2016. All rights reserved.
// </copyright>
//--------------------------------------------------------------------------------------------------------------------
namespace Assets.Scripts.Effects
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GameSettings;
using UnityEngine;
/// <summary>
/// Responsible for audio cues and other add-on effects
/// </summary>
public class EffectController : MonoBehaviour
{
/// <summary>
/// The sound that plays whenever the player hits a pickup
/// </summary>
public AudioSource PickupChime;
/// <summary>
/// The current instance of the effect controller
/// </summary>
private static EffectController instance;
/// <summary>
/// Get the instance of the effect controller
/// </summary>
/// <returns>The instance of the effect controller</returns>
public static EffectController GetInstance()
{
return EffectController.instance;
}
/// <summary>
/// When the player hits a pickup on the given position, plays the chime and add an effect
/// </summary>
/// <param name="position">The position of the collision</param>
public void PickupEffect(Vector3 position)
{
this.PickupChime.enabled = true;
this.PickupChime.PlayOneShot(this.PickupChime.clip);
}
/// <summary>
/// When the players hits a bomb, display the bomb explosion
/// </summary>
/// <param name="position">The origin of the explosion</param>
public void BombEffect(Vector3 position)
{
var explosion = GameObject.Instantiate(PrefabManager.GetIntance().BombExplosionPrefab);
explosion.GetComponent<BombExplosion>().SetOrigin(position);
}
/// <summary>
/// Initialization for the class
/// </summary>
private void Start()
{
this.PickupChime.enabled = true;
this.GetComponent<AudioSource>().enabled = true;
if (EffectController.instance != null)
{
GameObject.Destroy(EffectController.instance.gameObject);
}
EffectController.instance = this;
GameObject.DontDestroyOnLoad(this.gameObject);
}
}
}
Can anyone give me a hand? I am slowly going crazy
Edit 1: I updated the class so that instead of taking in an AudioSource, it have it's own component for AudioSource and takes in the clip to the chime instead, which solves the problem.
You may have had the Audio Source unchecked in the inspector.

deriving a class from another class causes Com registration error

I have a project that follows WPF/MVVM pattern. I have tried to derive my ViewModel class from PropertyChangedBase so that I can Notify of data changes to the view. As soon as I derive the class from PropertyChangeBase and compile, I get error saying
Error 1 Cannot register assembly "D:\Source\ArcOnline\bin\Debug\ArcOnline.dll". Could not load file or assembly 'Major, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
here is how my class is defined
using ArcOnline.WPF;
using System;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace ArcOnline.ViewModels
{
/// <summary>
/// The class handles the template for a single
/// </summary>
public class TemplatesViewModel : PropertyChangedBase
{
/// <summary>
///
/// </summary>
public ArcOnlineViewModel ArcManager { get; set; }
private string _layerID;
/// <summary>
/// Layer ID
/// </summary>
public string LayerID
{
get { return _layerID; }
set { _layerID = value; NotifyOfPropertyChange(() => LayerID); }
}
private string _title;
/// <summary>
/// Title of the layer
/// </summary>
public string Title
{
get { return _title; }
set { _title = value; NotifyOfPropertyChange(() => Title); }
}
............. More properties as above
}
and here is the how my PropertyChangedBase is defined
using Component.Linq.Expressions;
using System;
using System.Collections;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Runtime.Serialization;
using System.Xml.Serialization;
#endregion
namespace Component.ComponentModel
{
/// <summary>
/// A base class from which ViewModels can inherit to improve the quality of
/// patterns such as INotifyPropertyChanged.
/// </summary>
[DataContract]
[Serializable]
public class PropertyChangedBase : INotifyPropertyChanged, INotifyDataErrorInfo, IDataErrorInfo
{
/// <summary>
/// Initializes a new instance of the <see cref="PropertyChangedBase"/> class.
/// </summary>
public PropertyChangedBase()
{
ErrorsChanged += Notify_ErrorChanged;
}
void Notify_ErrorChanged(object sender, DataErrorsChangedEventArgs e)
{
NotifyOfPropertyChange(() => Error);
}
...... More class definition continues
}
This PropertyChangedBase is actually defined in a different Project so that is why it has all the header files included. If I copy the code of this PropertyChangedBase class and create a new class in my own Project where TemplatesViewModel is defined and then use it, it works perfectly fine.
I just want to know what is the reason for it not working in the first case?? This wasted my whole day!!
Thanks in advance

exposing .Net to COM

I have some .Net functionality I am trying to use in VB6. I have followed several tutorials. I wrote a test program with success using the formula here: http://www.codeproject.com/Articles/3511/Exposing-NET-Components-to-COM
However, when I try to do it with my actual project, my ProgId doesn't show in the registry like my test file. I made sure property ComVisible == true
using System.Runtime.InteropServices;
namespace Controls.Graph.Web
{
[Guid("5F9F6C6F-016A-4CFF-BD7A-3463761807E1")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface _GraphScript
{
[DispId(1)]
string getGraphXml();
}
[Guid("35901BC6-EFF1-490C-84FA-786E8462C553")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId(ProgIds.GraphScript)]
public class GraphScript : _GraphScript
{
protected GraphScript()
{
}
/// <summary>
///
/// </summary>
/// <returns>The graphs xml and javascript</returns>
public string getGraphXml()
{
DisplayDefaults tempDefaults;
tempDefaults = new DisplayDefaults();
GraphConstructor graph = new GraphConstructor();
graph.constructGraph();
GraphModel completedGraph = graph.Graph;
return GraphControl.RenderGraph(completedGraph, tempDefaults, 1) + GraphControl.RenderGraphScript();
}
}
}
and my progid...
using System;
namespace Controls.Graph.Web
{
/// <summary>
/// ProgID Constant
/// </summary>
public static class ProgIds
{
public const string GraphScript = "GraphData";
}
}
I'm not sure which piece of the puzzle I'm missing here
EDIT: actually the Guid shows up in the registry however the Progid still is not. Any ideas/suggestions?
also made sure to do this:
I have figured out what was wrong. I needed to change some access modifiers to PUBLIC -- including my GraphScript() constructor.

add-in for visual studio 2010 compile error Connect class

Here:
Is there a way to specify outlining defaults in Visual Studio 2008 so that a file opens up with members collapsed by default?
..I could find an example for programming addins.. but unfortunately it doesnt compile :-(
Error 1
'CollapsedMembers.Connect' does not contain a definition for
'_openHandler' and no extension method '_openHandler' accepting a
first argument of type 'CollapsedMembers.Connect' could be found
(are you missing a using directive or an assembly reference?)
D:\CollapsedMembers\Connect.cs 77 18 CollapsedMembers
In fact there is no _openHandler there.. I have already tried all the .NET Framework versions but had unfortunately no success.
In OnOpenHandler.cs I have the OnOpenHandler implemented:
namespace CollapsedMembers
{
internal class OnOpenHandler
{
DTE2 _application = null;
EnvDTE.Events events = null;
EnvDTE.DocumentEvents docEvents = null;
... and so on...
can anyone help please?
[Edit:] Connect.cs is like following:
using System;
using Extensibility;
using EnvDTE;
using EnvDTE80;
namespace CollapsedMembers
{
/// <summary>The object for implementing an Add-in.</summary>
/// <seealso class='IDTExtensibility2' />
public class Connect : IDTExtensibility2
{
/// <summary>Implements the constructor for the Add-in object. Place your initialization code within this method.</summary>
public Connect()
{
}
/// <summary>Implements the OnConnection method of the IDTExtensibility2 interface. Receives notification that the Add-in is being loaded.</summary>
/// <param term='application'>Root object of the host application.</param>
/// <param term='connectMode'>Describes how the Add-in is being loaded.</param>
/// <param term='addInInst'>Object representing this Add-in.</param>
/// <seealso class='IDTExtensibility2' />
public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
{
_applicationObject = (DTE2)application;
_addInInstance = (AddIn)addInInst;
switch (connectMode)
{
case ext_ConnectMode.ext_cm_UISetup:
case ext_ConnectMode.ext_cm_Startup:
//Do nothing OnStartup will be called once IDE is initialised.
break;
case ext_ConnectMode.ext_cm_AfterStartup:
//The addin was started post startup so we need to call its initialisation manually
InitialiseHandlers();
break;
}
}
/// <summary>Implements the OnDisconnection method of the IDTExtensibility2 interface. Receives notification that the Add-in is being unloaded.</summary>
/// <param term='disconnectMode'>Describes how the Add-in is being unloaded.</param>
/// <param term='custom'>Array of parameters that are host application specific.</param>
/// <seealso class='IDTExtensibility2' />
public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
{
}
/// <summary>Implements the OnAddInsUpdate method of the IDTExtensibility2 interface. Receives notification when the collection of Add-ins has changed.</summary>
/// <param term='custom'>Array of parameters that are host application specific.</param>
/// <seealso class='IDTExtensibility2' />
public void OnAddInsUpdate(ref Array custom)
{
}
/// <summary>Implements the OnStartupComplete method of the IDTExtensibility2 interface. Receives notification that the host application has completed loading.</summary>
/// <param term='custom'>Array of parameters that are host application specific.</param>
/// <seealso class='IDTExtensibility2' />
public void OnStartupComplete(ref Array custom)
{
InitialiseHandlers();
}
/// <summary>Implements the OnBeginShutdown method of the IDTExtensibility2 interface. Receives notification that the host application is being unloaded.</summary>
/// <param term='custom'>Array of parameters that are host application specific.</param>
/// <seealso class='IDTExtensibility2' />
public void OnBeginShutdown(ref Array custom)
{
}
private DTE2 _applicationObject;
private AddIn _addInInstance;
private void InitialiseHandlers()
{
this._openHandler = new OnOpenHandler(_applicationObject);
}
}
}
_openHandler is a member of Connect class and it isn't defined, and you are using it the
private void InitialiseHandlers()
{
this._openHandler = new OnOpenHandler(_applicationObject);
}
method you copied. You need to define a OnOpenHandler _openHandler member for Connect class.

Categories