Отправка структуры от C++ до WPF, использующего WM_COPYDATA

Да! ProcessStartInfo Имеет свойство, названное WorkingDirectory, просто используйте:

...
using System.Diagnostics;
...

var startInfo = new ProcessStartInfo();

  startInfo.WorkingDirectory = // working directory
  // set additional properties 

Process proc = Process.Start(startInfo);
7
задан skaffman 13 December 2009 в 23:41
поделиться

2 ответа

Я не уверен, что вы ошибаетесь, обязательно без дополнительной информации о вашей настройке. Я реплицировал код как мог (используя WndProc в приложении WPF, отправляя из моего собственного приложения win32), и он отлично работает для меня. Есть несколько ошибок, которые обязательно возникнут, если вы запускаете 64-битные приложения, а именно Pack = 1 приведет к смещению COPYDATASTRUCT, и чтение из указателя, вероятно, закончится болезнью.

Прохождение только int? Просмотр вашего прокомментированного кода, передающего LPWSTR или wstring, может вызвать серьезные проблемы, хотя это не должно стать очевидным, пока вы не демаршалируете отправленные данные.

Как бы то ни было, это отрывки моего кода, которые, похоже, у меня работают, включая передачу командной строки.

/* C++ code */
struct StackRecord
{
    wchar_t cmdline[128];
    int CursorX;
    int CursorY;
};

void SendCopyData(HWND hFind)
{
    COPYDATASTRUCT cp;
    StackRecord record;

    record.CursorX = 1;
    record.CursorY = -1;

    _tcscpy(record.cmdline, L"Hello World!");
    cp.cbData = sizeof(record);
    cp.lpData = &record;
    cp.dwData = 12;
    SendMessage(hFind, WM_COPYDATA, NULL, (LPARAM)&cp);
}

/* C# code */
public static readonly int WM_COPYDATA = 0x4A;

[StructLayout(LayoutKind.Sequential)]
public struct CopyDataStruct
{
    public IntPtr dwData;
    public int cbData;
    public IntPtr lpData;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct StackRecord
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)]
    public string CommandLine;
    public Int32 CursorX;
    public Int32 CursorY;
}

protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    if (msg == WM_COPYDATA)
    {
        StackRecord record = new StackRecord();
        try
        {
            CopyDataStruct cp = (CopyDataStruct)Marshal.PtrToStructure(lParam, typeof(CopyDataStruct));
            if (cp.cbData == Marshal.SizeOf(record))
            {
                record = (StackRecord)Marshal.PtrToStructure(cp.lpData, typeof(StackRecord));
            }
        }
        catch (Exception e)
        {
            System.Diagnostics.Debug.WriteLine(e.ToString());
        }
        handled = true;
    }
    else
    {
        handled = false;
    }
    return IntPtr.Zero;
}
7
ответ дан 7 December 2019 в 01:22
поделиться

Я создал пару приложений (с VC ++ и VC #, соответственно), решающих «урезанный» вариант проблемы (т.е. невозможность получить эту структуру), они кажутся работать без проблем, так что это действительно может быть что-то с вашей установкой, как говорит тиранид .

В любом случае, вот код (его должно быть достаточно, чтобы просто вставить его во вновь созданное ПРИЛОЖЕНИЕ WIN32 (для VC ++) и ПРИЛОЖЕНИЕ WINDOWS FORMS для запуска и тестирования C #):

StackProxy.cpp

#include "stdafx.h"
#include "StackProxy.h"
#include <string>


struct StackRecord {
    __int32 CursorX;
    __int32 CursorY;
};


int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
    StackRecord record;

    record.CursorX = 5;
    record.CursorY = 16;

    COPYDATASTRUCT data;

    data.dwData = 12;
    data.cbData = sizeof(StackRecord);
    data.lpData = &record;

    HWND target = FindWindow(NULL, _T("Window1"));

    if(target != NULL)
        SendMessage(target, WM_COPYDATA, (WPARAM)(HWND) target, (LPARAM)(LPVOID) &data);

    return 0;
}

Form1.cs

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public struct COPYDATASTRUCT
        {
            public System.Int32 dwData;
            public System.Int32 cbData;
            public System.IntPtr lpData;
        }

        int WM_COPYDATA = 0x4A;

        [StructLayout(LayoutKind.Sequential)]
        public struct StackRecord
        {
            public Int32 CursorX;
            public Int32 CursorY;
        }

        public Form1()
        {
            InitializeComponent();
            Text = "Window1";
        }

        protected override void WndProc(ref Message msg)
        {
            if (msg.Msg == WM_COPYDATA) {
                COPYDATASTRUCT cp = (COPYDATASTRUCT)Marshal.PtrToStructure(msg.LParam, typeof(COPYDATASTRUCT));
                StackRecord record = (StackRecord)Marshal.PtrToStructure(cp.lpData, typeof(StackRecord));
                MessageBox.Show(String.Format("X: {0}, Y: {1}, Data: {2}", record.CursorX, record.CursorY, cp.dwData));
            } 
            base.WndProc(ref msg);
        }
    }
}

Надеюсь, это поможет.

PS Я плохо разбираюсь в C # и (особенно) в взаимодействии (интересуюсь в первую очередь программированием на C ++), но никого не вижу ответ [несколько часов назад] просто подумал, что было бы неплохо попробовать эту задачу. Не говоря уже о награде :)

* в общем, я опаздываю:

3
ответ дан 7 December 2019 в 01:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: