3

I have a function in C# that displays a form. I have exposed the function using Unmanaged Exports and calling it from C++ in credential provider sample on a command link. The form does not display (nothing happens). However, when I call the same C# form using C++ console application, the form displays without any issue. What could be the difference that C++ console application is loading it but C++ credential provider code is not loading it?

C++ Code:

using CSharpForm = void(__stdcall *)(wchar_t* message);
int _tmain(int argc, _TCHAR* argv[])
{
HMODULE mod = LoadLibraryA("CSharp.dll");
CSharpForm form = reinterpret_cast<CSharpForm>(GetProcAddress(mod, "form1"));
form(L"This is a c# form");
getchar();
return 0;
}

C# Code:

[DllExport(ExportName = "form1", CallingConvention = CallingConvention.StdCall)]
public static void showForm([MarshalAs(UnmanagedType.LPWStr)]string message)
{
    Form_Test form = new Form_Test();
    form.Text = message;
    form.ShowDialog();
}
Lauren Rutledge
  • 1,195
  • 5
  • 18
  • 27
js.hrt
  • 159
  • 2
  • 14
  • Hello, I try to develop a custom C# credential provider as well. When i call OnWindowCreating method, It gives me an exception. Can you provide me some information about getting parentHwnd? Thanks. – candogg Jan 15 '23 at 15:37

1 Answers1

2

Try this out:

Call ICredentialProviderCredentialEvents::OnCreatingWindow method

HRESULT OnCreatingWindow(
    HWND *phwndOwner
);

to get window handle, pass additional parameter into your library and use overloaded method ShowDialog.

public DialogResult ShowDialog(
    IWin32Window owner
);

You may pass HWND out paramemter valie as IntPtr and convert it using public static System.Windows.Forms.NativeWindow FromHandle(IntPtr handle).

Alexander
  • 1,232
  • 1
  • 15
  • 24
  • Thanks. How should I pass the handle to C# code? Like, to receive string I am doing "[MarshalAs(UnmanagedType.LPWStr)]string message" in c#. How will I marshal the handle? – js.hrt Aug 30 '18 at 10:12
  • 1
    You may pass `HWND` as `IntPtr` ant there convert it using `public static System.Windows.Forms.NativeWindow FromHandle (IntPtr handle);` – Alexander Aug 30 '18 at 13:49
  • Have a look onto this [post](https://stackoverflow.com/questions/2481835/convert-an-intptr-window-handle-to-iwin32window) – Alexander Aug 30 '18 at 13:53
  • Thank you so much. It is working now! I'll mark that answer. Thanks again – js.hrt Aug 30 '18 at 15:24
  • One thing more, if I use Show(owner) instead of ShowDialog(owner) so that the code moves forward after displaying the form, can this be done? Because when I do this, the form does not display properly (it becomes unclickable and hung) – js.hrt Sep 01 '18 at 09:03
  • In this case you have to create separate thread and run your windows inside it. Main thread of logon UI thinks that you have finished your work and stops serving child windows. – Alexander Oct 01 '18 at 13:07