Solved

AutoHotkey ActiveX Component Error

Posted on 2016-11-14
8
86 Views
Last Modified: 2016-11-17
I am working with a very simple VB.Net winform app in which I am trying to run a AutoHotkey Hello World sub . The code is shown below. I get a cannot create ActiveX component error. Any help in resolving the error would be appreciated.

Dim ahk As Object
ahk = CreateObject("AutoHotkey.Script")
ahk.ahktextdll("MsgBox Hello World!" & Chr(13) & "ExitApp")

Open in new window

0
Comment
Question by:Mark01
  • 4
  • 4
8 Comments
 
LVL 29

Expert Comment

by:Randy Downs
ID: 41887263
Try this.

Make sure AutoHotkey.dll is  in Windows\System32\ ... otherwise you will need full path to AutoHotkey.dll.

Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Process.Start("Regsvr32 AutoHotkey.dll")
        atest()
End Sub
 
Sub atest()
        Dim AhkCom As Object
        AhkCom = CreateObject("AutoHotkey.Script")
        AhkCom.ahktextdll("MsgBox Hello World!" & Chr(13) & "ExitApp")
    End Sub
 
End Class

Open in new window

0
 

Author Comment

by:Mark01
ID: 41888883
I just checked and AutoHotkey.dll is in Windows\System32\. I received a confirmation message after AutoHotkey.dll was successfully registered.
0
 
LVL 29

Expert Comment

by:Randy Downs
ID: 41888963
Still not working?
0
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 

Author Comment

by:Mark01
ID: 41889793
No, it is not working. I registered it the first time last week and again a few minutes ago. The path to the dll is C:\Program Files\AutoHotkey. A screenshot is attached.
Successful RegistrationYou can read the details about registering it here:
https://www.experts-exchange.com/questions/28982011/Register-AutoHotkey.html
0
 

Author Comment

by:Mark01
ID: 41891653
@Randy Downs: Do you have sample code to run a script?
0
 
LVL 29

Expert Comment

by:Randy Downs
ID: 41891738
Here's a detailed description of running PowerScript.

There is a download for the VS solution.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Management.Automation;
using System.Collections.ObjectModel;

namespace PowerShellExecutionSample
{
    class Program
    {
        static void Main(string[] args)
        {
            PowerShellExecutor t = new PowerShellExecutor();
            
            // scenario 1 (synchronous execution)
            t.ExecuteSynchronously();

            // scenario 2 (asynchronous execution)
            //t.ExecuteAsynchronously();

            // scenario 3 (synchronous execution with the namespace test)
            //t.ExecuteSynchronouslyNamespaceTest();
        }
    }

    /// <summary>
    /// Test class object to instantiate from inside PowerShell script.
    /// </summary>
    public class TestObject
    {
        /// <summary>
        /// Gets or sets the Name property
        /// </summary>
        public string Name { get; set; }
    }

    /// <summary>
    /// Test static class to invoke from inside PowerShell script.
    /// </summary>
    public static class TestStaticClass
    {
        /// <summary>
        /// Sample static method to call from insider PowerShell script.
        /// </summary>
        /// <returns>String message</returns>
        public static string TestStaticMethod()
        {
            return "Hello, you have called the test static method.";
        }
    }

    /// <summary>
    /// Provides PowerShell script execution examples
    /// </summary>
    class PowerShellExecutor
    {
        /// <summary>
        /// Sample execution scenario 3: Namespace test
        /// </summary>
        /// <remarks>
        /// Executes a PowerShell script synchronously and utilizes classes in the callers namespace.
        /// </remarks>
        public void ExecuteSynchronouslyNamespaceTest()
        {
            using (PowerShell PowerShellInstance = PowerShell.Create())
            {
                // add a script that creates a new instance of an object from the caller's namespace
                PowerShellInstance.AddScript("$t = new-object PowerShellExecutionSample.TestObject;" +
                                             "$t.Name = 'created from inside PowerShell script'; $t;" +
                                             "$message = [PowerShellExecutionSample.TestStaticClass]::TestStaticMethod(); $message");

                // invoke execution on the pipeline (collecting output)
                Collection<PSObject> PSOutput = PowerShellInstance.Invoke();

                // loop through each output object item
                foreach (PSObject outputItem in PSOutput)
                {
                    if (outputItem != null)
                    {
                        Console.WriteLine(outputItem.BaseObject.GetType().FullName);

                        if (outputItem.BaseObject is TestObject)
                        {
                            TestObject testObj = outputItem.BaseObject as TestObject;
                            Console.WriteLine(testObj.Name);
                        }
                        else
                        {
                            Console.WriteLine(outputItem.BaseObject.ToString());
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Sample execution scenario 1: Synchronous
        /// </summary>
        /// <remarks>
        /// Executes a PowerShell script synchronously with input parameters and script output handling.
        /// </remarks>
        public void ExecuteSynchronously()
        {
            using (PowerShell PowerShellInstance = PowerShell.Create())
            {
                // use "AddScript" to add the contents of a script file to the end of the execution pipeline.
                // use "AddCommand" to add individual commands/cmdlets to the end of the execution pipeline.
                PowerShellInstance.AddScript("param($param1) $d = get-date; $s = 'test string value'; " +
                "$d; $s; $param1; get-service");

                // use "AddParameter" to add a single parameter to the last command/script on the pipeline.
                PowerShellInstance.AddParameter("param1", "parameter 1 value!");

                // invoke execution on the pipeline (collecting output)
                Collection<PSObject> PSOutput = PowerShellInstance.Invoke();

                // check the other output streams (for example, the error stream)
                if (PowerShellInstance.Streams.Error.Count > 0)
                {
                    // error records were written to the error stream.
                    // do something with the items found.
                }

                // loop through each output object item
                foreach (PSObject outputItem in PSOutput)
                {
                    // if null object was dumped to the pipeline during the script then a null
                    // object may be present here. check for null to prevent potential NRE.
                    if (outputItem != null)
                    {
                        //TODO: do something with the output item 
                        Console.WriteLine(outputItem.BaseObject.GetType().FullName);
                        Console.WriteLine(outputItem.BaseObject.ToString() + "\n");
                    }
                }
            }
        }

        /// <summary>
        /// Sample execution scenario 2: Asynchronous
        /// </summary>
        /// <remarks>
        /// Executes a PowerShell script asynchronously with script output and event handling.
        /// </remarks>
        public void ExecuteAsynchronously()
        {
            using (PowerShell PowerShellInstance = PowerShell.Create())
            {
                // this script has a sleep in it to simulate a long running script
                PowerShellInstance.AddScript("$s1 = 'test1'; $s2 = 'test2'; $s1; write-error 'some error';start-sleep -s 7; $s2");

                // prepare a new collection to store output stream objects
                PSDataCollection<PSObject> outputCollection = new PSDataCollection<PSObject>();
                outputCollection.DataAdded += outputCollection_DataAdded;

                // the streams (Error, Debug, Progress, etc) are available on the PowerShell instance.
                // we can review them during or after execution.
                // we can also be notified when a new item is written to the stream (like this):
                PowerShellInstance.Streams.Error.DataAdded += Error_DataAdded;

                // begin invoke execution on the pipeline
                // use this overload to specify an output stream buffer
                IAsyncResult result = PowerShellInstance.BeginInvoke<PSObject, PSObject>(null, outputCollection);

                // do something else until execution has completed.
                // this could be sleep/wait, or perhaps some other work
                while (result.IsCompleted == false)
                {
                    Console.WriteLine("Waiting for pipeline to finish...");
                    Thread.Sleep(1000);

                    // might want to place a timeout here...
                }

                Console.WriteLine("Execution has stopped. The pipeline state: " + PowerShellInstance.InvocationStateInfo.State);

                foreach (PSObject outputItem in outputCollection)
                {
                    //TODO: handle/process the output items if required
                    Console.WriteLine(outputItem.BaseObject.ToString());
                }
            }
        }

        /// <summary>
        /// Event handler for when data is added to the output stream.
        /// </summary>
        /// <param name="sender">Contains the complete PSDataCollection of all output items.</param>
        /// <param name="e">Contains the index ID of the added collection item and the ID of the PowerShell instance this event belongs to.</param>
        void outputCollection_DataAdded(object sender, DataAddedEventArgs e)
        {
            // do something when an object is written to the output stream
            Console.WriteLine("Object added to output.");
        }

        /// <summary>
        /// Event handler for when Data is added to the Error stream.
        /// </summary>
        /// <param name="sender">Contains the complete PSDataCollection of all error output items.</param>
        /// <param name="e">Contains the index ID of the added collection item and the ID of the PowerShell instance this event belongs to.</param>
        void Error_DataAdded(object sender, DataAddedEventArgs e)
        {
            // do something when an error is written to the error stream
            Console.WriteLine("An error was written to the Error stream!");
        }
    }
}

Open in new window

0
 
LVL 29

Accepted Solution

by:
Randy Downs earned 500 total points
ID: 41891836
If you just need a HotKey you could do something like this which registers multiple hotkeys Alt+D & Alt+C.

Imports System.Runtime.InteropServices
	
Public Class Form1

    Public Const MOD_ALT As Integer = &H1 'Alt key
    Public Const WM_HOTKEY As Integer = &H312

    <DllImport("User32.dll")> _
    Public Shared Function RegisterHotKey(ByVal hwnd As IntPtr, _
                        ByVal id As Integer, ByVal fsModifiers As Integer, _
                        ByVal vk As Integer) As Integer
    End Function

    <DllImport("User32.dll")> _
    Public Shared Function UnregisterHotKey(ByVal hwnd As IntPtr, _
                        ByVal id As Integer) As Integer
    End Function

    Private Sub Form1_Load(ByVal sender As System.Object, _
                        ByVal e As System.EventArgs) Handles MyBase.Load
        RegisterHotKey(Me.Handle, 100, MOD_ALT, Keys.D)
        RegisterHotKey(Me.Handle, 200, MOD_ALT, Keys.C)
    End Sub

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        If m.Msg = WM_HOTKEY Then
            Dim id As IntPtr = m.WParam
            Select Case (id.ToString)
                Case "100"
                    MessageBox.Show("You pressed ALT+D key combination")
                Case "200"
                    MessageBox.Show("You pressed ALT+C key combination")
            End Select
        End If
        MyBase.WndProc(m)
    End Sub

    Private Sub Form1_FormClosing(ByVal sender As System.Object, _
                        ByVal e As System.Windows.Forms.FormClosingEventArgs) _
                        Handles MyBase.FormClosing
        UnregisterHotKey(Me.Handle, 100)
        UnregisterHotKey(Me.Handle, 200)
    End Sub

End Class

Open in new window

0
 

Author Closing Comment

by:Mark01
ID: 41892241
Thank you, Randy.
0

Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

It is a general practice to get rid of old user profiles on a computer  in a LAN environment. As I have been working with a company in a LAN environment where users move from one place to some other place at times. This will make many user profil…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Learn the basics of strings in Python: declaration, operations, indices, and slicing. Strings are declared with quotations; for example: s = "string": Strings are immutable.: Strings may be concatenated or multiplied using the addition and multiplic…
Learn the basics of lists in Python. Lists, as their name suggests, are a means for ordering and storing values. : Lists are declared using brackets; for example: t = [1, 2, 3]: Lists may contain a mix of data types; for example: t = ['string', 1, T…

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question