none
Convert C# code to powershell code, no effect RRS feed

  • Question

  • I tried to convert C# code to powershell code, but it didn't work. Any suggestions are welcome

    //C# code

    //using System.Runtime.InteropServices; [DllImport("user32.dll", EntryPoint = "SendMessageW", CharSet = CharSet.Unicode)] internal static extern IntPtr SendMessageS(IntPtr hWnd, int Msg, uint wParam, string lParam); [DllImport("user32.dll", EntryPoint = "FindWindowW", CharSet = CharSet.Unicode)] internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName); static void TestQm2SendMessage() { var hwnd = FindWindow("QM_Editor", null); if(hwnd == default(IntPtr)) return; SendMessageS(hwnd, 12, 1, "Q ' M 'Macro295'"); }

    #powershell code

    $code = @' [DllImport("user32.dll", EntryPoint = "SendMessageW", CharSet = CharSet.Unicode)] public static extern IntPtr SendMessageS(IntPtr hWnd, int Msg, uint wParam, string lParam); [DllImport("user32.dll", EntryPoint = "FindWindowW", CharSet = CharSet.Unicode)] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); '@ $myAPI = Add-Type -MemberDefinition $code -Name myAPI -PassThru $myAPI::SendMessageS($myAPI::FindWindow("QM_Editor", $Null), 12, 1, "Q ' M 'Macro295'");




    • Edited by winps Saturday, May 11, 2019 1:26 AM
    Saturday, May 11, 2019 1:25 AM

Answers

  • "SendMessage" requires a handle to a Window. 

    "FindWindow" requires a window class.  The Window class must have been previously registered.  This call also requires a pointer to a string.  Handing a basic PowerShell string will not help.

    Here is how to find a windows with that API call: https://stackoverflow.com/questions/25780138/how-to-find-a-desktop-window-by-window-name-in-windows-8-1-update-2-os-using

    The NULL you are looking for is a "zero" value of an "IntPtr".  See the link for a compete example.

    If you are going to code in languages you don't know it will help if you learn to search for examples. 

    Search for "powershell findwindow" and you will find hundreds of examples.


    \_(ツ)_/

    • Marked as answer by winps Sunday, May 12, 2019 12:05 AM
    Saturday, May 11, 2019 11:41 PM

All replies

  • What does "didn't work" mean.


    \_(ツ)_/

    Saturday, May 11, 2019 1:56 AM
  • #'

    $code = @' using System; using System.Runtime.InteropServices; public class Mystuff{ [DllImport("user32.dll", EntryPoint = "SendMessageW", CharSet = CharSet.Unicode)] internal static extern IntPtr SendMessageS(IntPtr hWnd, int Msg, uint wParam, string lParam); [DllImport("user32.dll", EntryPoint = "FindWindowW", CharSet = CharSet.Unicode)] internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName); public static void TestQm2SendMessage() { var hwnd = FindWindow("QM_Editor", null); if (hwnd == default(IntPtr)) return; SendMessageS(hwnd, 12, 1, "Q ' M 'Macro295'"); } } '@
    #'

    Add-Type $code [Mystuff]::TestQm2SendMessage OverloadDefinitions ------------------- static void TestQm2SendMessage()



    \_(ツ)_/



    • Edited by jrv Saturday, May 11, 2019 2:03 AM
    Saturday, May 11, 2019 2:02 AM
  • Hello, thank you for your reply,

    I use your code and still have no effect

    No effect means different results than executing C# code
    Saturday, May 11, 2019 2:21 AM
  • I need to use powershell to send a message to quickmacros to run a macro or function.
    Source code in the link below

    http://www.quickmacros.com/forum/showthread.php?tid=6471&pid=32622#pid32622

    Saturday, May 11, 2019 2:27 AM
  • Use the code below to send a message to Notepad's window, but I don't know how to send a message to quickmacros

    function Out-Notepad
    {
      param
      (
        [Parameter(Mandatory=$true, ValueFromPipeline=$true)]
        [String]
        [AllowEmptyString()]
        $Text
      )
     
      begin
      {
        $sb = New-Object System.Text.StringBuilder
      }
     
      process
      {
        $null = $sb.AppendLine($Text)
      }
      end
      {
        $text = $sb.ToString()
     
        $process = Start-Process notepad -PassThru
        $null = $process.WaitForInputIdle()
     
     
        $sig = '
          [DllImport("user32.dll", EntryPoint = "FindWindowEx")] public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
          [DllImport("User32.dll")] public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);
        ' 
     
        $type = Add-Type -MemberDefinition $sig -Name APISendMessage -PassThru
        $hwnd = $process.MainWindowHandle
        [IntPtr]$child = $type::FindWindowEx($hwnd, [IntPtr]::Zero, "Edit", $null)
        $null = $type::SendMessage($child, 0x000C, 0, $text)
      }
    } 
    
    #Get-Process | Out-String | Out-Notepad 

    Saturday, May 11, 2019 2:36 AM
  • It is not possible to know what you are expecting.  If you need to do something you need to ask a complete question.  I showed you how to compile your code.  Beyond that we cannot be of much help.


    \_(ツ)_/

    Saturday, May 11, 2019 2:37 AM
  • You will have to contact "quickmacros" to learn how to use there software.  The issue is beyond the scope of this forum.


    \_(ツ)_/

    Saturday, May 11, 2019 2:38 AM
  • Thank you for your help, I don’t know much about c#, I just learned programming.
    Saturday, May 11, 2019 2:39 AM
  • Hello, I use the following code, it can run successfully, but I have to set the title text, but in C# code, it can be null, how should I modify the code, can you help me, thank you very much

    title text:  Quick Macros - Main - [func8]

    $code = @'
    [DllImport("user32.dll", EntryPoint = "SendMessageW", CharSet = CharSet.Unicode)] public static extern IntPtr SendMessageS(IntPtr hWnd, int Msg, uint wParam, string lParam);
    [DllImport("user32.dll", EntryPoint = "FindWindowW", CharSet = CharSet.Unicode)] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    '@
    $myAPI = Add-Type -MemberDefinition $code -Name API -PassThru
    $myAPI::SendMessageS($myAPI::FindWindow("QM_Editor", "Quick Macros - Main - [func8]"), 12, 1, "Q ' M 'func8'");


    • Edited by winps Saturday, May 11, 2019 11:16 PM
    Saturday, May 11, 2019 11:15 PM
  • For help with C# code you will have to post in the C# forum.  This is a scripting forum.  We cannot help you with compiled languages or with direct access to the Win32 API via P/Invoke calls.

    Please understand that the code as compiled works as defined. You will need to learn about how basic Win32 API clls to Windows functions are intended to work.  The C# forum will help you to find the correct information needed to call Win32 API functions.

    As a starter The "SendMessage"  call requires a window handle or a Window class..  You are just using strings.  Nether call can use a string.


    \_(ツ)_/

    Saturday, May 11, 2019 11:22 PM
  • My question involves a lot of programming languages, and the forums for each language don't give explanations. Like a ball, kick and kick.
    Anyway, thank you for your help.
    Saturday, May 11, 2019 11:30 PM
  • "SendMessage" requires a handle to a Window. 

    "FindWindow" requires a window class.  The Window class must have been previously registered.  This call also requires a pointer to a string.  Handing a basic PowerShell string will not help.

    Here is how to find a windows with that API call: https://stackoverflow.com/questions/25780138/how-to-find-a-desktop-window-by-window-name-in-windows-8-1-update-2-os-using

    The NULL you are looking for is a "zero" value of an "IntPtr".  See the link for a compete example.

    If you are going to code in languages you don't know it will help if you learn to search for examples. 

    Search for "powershell findwindow" and you will find hundreds of examples.


    \_(ツ)_/

    • Marked as answer by winps Sunday, May 12, 2019 12:05 AM
    Saturday, May 11, 2019 11:41 PM
  • Thanks for your reminder, the problem has been resolved, modified to the following code and parameters

    IntPtr lpWindowName

    [IntPtr]::Zero

    Sunday, May 12, 2019 12:03 AM
  • The easiest way to get a windows handle is like this:

     Get-Process PowerShell | select MainWindowTitle,MainWindowHandle


    \_(ツ)_/

    Sunday, May 12, 2019 12:19 AM
  • Is there a simpler way to get the handle of a control? Below is the code of C#.

            var hwnd = FindWindow("QM_Editor", null);



    • Edited by winps Sunday, May 12, 2019 12:31 AM
    Sunday, May 12, 2019 12:30 AM
  • I modified the code, but it didn't work successfully. Can you point out the error? thank you very much

    Sometimes, because QM starts slow, the code behind does not execute.

    I need to wait for the QM to run completely and execute the code that sends the message.

    Start-Process qm -PassThru
    $hwnd=Get-Process qm | select MainWindowTitle,MainWindowHandle
    $code = @'
    [DllImport("user32.dll", EntryPoint = "SendMessageW", CharSet = CharSet.Unicode)] public static extern IntPtr SendMessageS(IntPtr hWnd, int Msg, uint wParam, string lParam);
    [DllImport("user32.dll", EntryPoint = "FindWindowW", CharSet = CharSet.Unicode)] public static extern IntPtr FindWindow(string lpClassName, IntPtr lpWindowName);
    '@
    $API = Add-Type -MemberDefinition $code -Name API -PassThru
    $API::SendMessageS($hwnd, 12, 1, "Q ' M 'func8'");


    • Edited by winps Sunday, May 12, 2019 12:42 AM
    Sunday, May 12, 2019 12:37 AM
  • You need to stop and take some time to learn how to write code.  You are just copying anf guessing with everything.

    There is no substitute fore real knowledge.  You cannot learn computers by guessing.


    \_(ツ)_/

    Sunday, May 12, 2019 12:44 AM
  • You can start ere to learn basic PowerShell: Microsoft Virtual   Academy - Getting Started with Microsoft PowerShell

    This will help you to get started learning how to write and understand code.  Without some ability to understand what you are working with will just cause you to waste time and get frustrated.


    \_(ツ)_/

    Sunday, May 12, 2019 12:51 AM
  • My English is not very good. The major I study is literature.

    If you can tell me the answer above, I might learn faster.
    Sunday, May 12, 2019 1:00 AM
  • You have to use the window handle and not the process object that is returned.  Do the tutorial and it will explain how to use PowerShell to get what you need.

    Note that this is not a free script writing forum.  It is aa forum for technicians who are using PowerShell in their work.  No-techs should contact a consultant to help them or take the time to learn the technology.

    I answered your original question.  We will not incrementally provide code.  Either learn PowerShell or contact a trained professional to help you.


    \_(ツ)_/

    Sunday, May 12, 2019 2:14 AM
  • I am only interested in the simpler method you mentioned, so I want to ask you to provide the code.

    I didn't guess the code, probably because my programming ability is limited.

    I don't want to learn programming, because this code has been able to complete my work, I don't want to spend too much time on it.

    Anyway, the problem has been solved in stackoverflow, thanks for your help and reminders
    Sunday, May 12, 2019 5:02 AM