Equivalent code of CreateObject in C#

I have a code in VB6. Can anyone tell me how to write it in C#. This code is below:

Set Amibroker = CreateObject("Broker.Application")
Set STOCK = Amibroker.Stocks.Add(ticker)
Set quote = STOCK.Quotations.Add(stInDate)

quote.Open = stInOpen
quote.High = stInHigh
quote.Low = stInlow
quote.Close = stInYcp
quote.Volume = stInVolume


Set STOCK = Nothing
Set quote = Nothing

What is the equivalent of CreateObject in C#?. I try to add references to com object but i can't find any com object as Broker.Application or amibroker


Solution 1:

If you are using .net 4 or later, and therefore can make use of dynamic, you can do this quite simply. Here's an example that uses the Excel automation interface.

Type ExcelType = Type.GetTypeFromProgID("Excel.Application");
dynamic ExcelInst = Activator.CreateInstance(ExcelType);
ExcelInst.Visible = true;

If you can't use dynamic then it's much more messy.

Type ExcelType = Type.GetTypeFromProgID("Excel.Application");
object ExcelInst = Activator.CreateInstance(ExcelType);
ExcelType.InvokeMember("Visible", BindingFlags.SetProperty, null, 
    ExcelInst, new object[1] {true});

Trying to do very much of that will sap the lifeblood from you.

COM is so much easier if you can use early bound dispatch rather than late bound as shown above. Are you sure you can't find the right reference for the COM object?

Solution 2:

If you use .NET Framework 4.0 and above, you can use this pattern:

public sealed class Application: MarshalByRefObject {

    private readonly dynamic _application;


    // Methods
    public Application() {
        const string progId = "Broker.Application";
        _application = Activator.CreateInstance(Type.GetTypeFromProgID(progId));
    }

    public Application(dynamic application) {
        _application = application;
    }

    public int Import(ImportType type, string path) {
        return _application.Import((short) type, path);
    }

    public int Import(ImportType type, string path, string defFileName) {
        return _application.Import((short) type, path, defFileName);
    }

    public bool LoadDatabase(string path) {
        return _application.LoadDatabase(path);
    }

    public bool LoadLayout(string path) {
        return _application.LoadLayout(path);
    }

    public int Log(ImportLog action) {
        return _application.Log((short) action);
    }

    public void Quit() {
        _application.Quit();
    }

    public void RefreshAll() {
        _application.RefreshAll();
    }

    public void SaveDatabase() {
        _application.SaveDatabase();
    }

    public bool SaveLayout(string path) {
        return _application.SaveLayout(path);
    }

    // Properties
    public Document ActiveDocument {
        get {
            var document = _application.ActiveDocument;
            return document != null ? new Document(document) : null;
        }
    }

    public Window ActiveWindow {
        get {
            var window = _application.ActiveWindow;
            return window != null ? new Window(window) : null;
        }
    }

    public AnalysisDocs AnalysisDocs {
        get {
            var analysisDocs = _application.AnalysisDocs;
            return analysisDocs != null ? new AnalysisDocs(analysisDocs) : null;
        }
    }

    public Commentary Commentary {
        get {
            var commentary = _application.Commentary;
            return commentary != null ? new Commentary(commentary) : null;
        }
    }

    public Documents Documents {
        get {
            var documents = _application.Documents;
            return documents != null ? new Documents(documents) : null;
        }
    }


    public string DatabasePath {
        get { return _application.DatabasePath; }
    }

    public bool Visible {
        get { return _application.Visible != 0; }
        set { _application.Visible = value ? 1 : 0; }
    }

    public string Version {
        get { return _application.Version; }
    }
}

}

Next you must wrap all AmiBroker OLE Automation classes. For example wrap Commentary class:

public sealed class Commentary : MarshalByRefObject {

    // Fields
    private readonly dynamic _commentary;


    // Methods
    internal Commentary(dynamic commentary) {
        _commentary = commentary;
    }

    public void Apply() {
        _commentary.Apply();
    }

    public void Close() {
        _commentary.Close();
    }

    public bool LoadFormula(string path) {
        return _commentary.LoadFormula(path);
    }

    public bool Save(string path) {
        return _commentary.Save(path);
    }

    public bool SaveFormula(string path) {
        return _commentary.SaveFormula(path);
    }
}

Solution 3:

Here's a snippet from the C# code I used to automate Amibroker (from when I went down that path). You'll need to reference System.Runtime.Interopservices

    System.Type objType = System.Type.GetTypeFromProgID("Broker.Application");

    dynamic comObject = System.Activator.CreateInstance(objType);

    comObject.Import(0, fileName, "default.format");

    comObject.RefreshAll();

Typing a dot won't bring up the comObject internal methods, though.

All I can say about this method is - it works, like a charm, but stay away from it, like David said. I got my inspiration for this method from:

http://www.codeproject.com/Articles/148959/How-the-new-C-dynamic-type-can-simplify-access-to

For another angle of attack, you may want to check out (I think this is early binding):

http://adamprescott.net/2012/04/05/net-vb6-interop-tutorial/

Hope at least some of this help you. I've used both these methods with Amibroker and C#, but I ended up leaving them behind. COM and Amibroker don't mix well. Even TJ says so.

Good luck anyway.