I am using c#.net to develop a winform application.My winform application is using the below components
1)Win 32 dlls (using System.Runtime.InteropServices)
2)Timers(3 in count) (System.Timers)
3)Excel Interop
The memory of the application is not at all coming down .As timers are running continuosly so i cannot dispose the
So would like to implement dispose patterns .
Is it necessary to dispose the win32 APIs apart from Excel interop.?
If necessary can you please suggest the best way to call and dispose the win32 APIs.
Some of the Win32 APIs Used in application are listed below.
DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern uint RegisterWindowMessage(string lpString);
[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int netConnection, int val);
[DllImport("Oleacc.dll")]
private static extern int AccessibleObjectFromWindow(IntPtr hwnd, uint dwObjectID, byte[] riid, ref Excel.Window ptr);
[DllImport("WtsApi32.dll")]
private static extern bool WTSRegisterSessionNotification(IntPtr hWnd, [MarshalAs(UnmanagedType.U4)]int dwFlags);
[DllImport("WtsApi32.dll")]
private static extern bool WTSUnRegisterSessionNotification(IntPtr hWnd);
The hWnd parameters in your function calls are all window handles. As a general rule, whenever you have finished using a window handle in the windows API, you need to explicitly release it using the CloseHandle function
Related
I'm developing a Windows Forms Application. At the startup I can choose if I want to show the console too or only the main form. This is achieved via the
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern int AllocConsole();
command. I can even dispose it via the
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern int FreeConsole();
command.
How can I determine at runtime if the console is disposed or not?
There're a lot of ways to simulate a mouse click in an inactive window. I want my program to make clicks even when it's minimized and of course without capturing the main mouse.
Specifically, my C# program will contain a Web Control displaying some flash content and this is where I want the clicks to occur.
here's the techniques I tried:
1.[DllImport("user32.dll", CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo);
2.[DllImport("user32.dll", SetLastError = true)]
public static extern bool SendMessage(int hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
Both of them did not do any good in my case. Surprisingly, I was able to use the SendMessage() function to send mouse clicks in a minimized chrome displaying some flash content. but, it doesn't seem to do that in my C# program. Is there a possibility that my program not receiving the message for some reason?
Any Hints on how can I do this?
Trying to make some basic calls to gdi32.dll functions from C# after publishing a Azure Web App and I'm having lots of problems. Is it fully supported or is there a workaround / config change I can make?
The pointers below all return non-zero values when run in Visual Studio on a standard setup, but they return 0 when running in Azure.
Created a basic ASP.NET Web Forms project and added the blow to the codebehind of Default.aspx to test:
[DllImport("gdi32.dll")]
private static extern IntPtr CreatePen(int enPenStyle, int nWidth, uint crColor);
[DllImport("gdi32.dll")]
private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
[DllImport("gdi32.dll")]
private static extern bool MoveToEx(IntPtr hdc, int X, int Y, IntPtr lpPoint);
[DllImport("gdi32.dll")]
private static extern bool LineTo(IntPtr hdc, int nXEnd, int nYEnd);
[DllImport("gdi32.dll")]
private static extern bool DeleteObject([In] IntPtr hObject);
protected void Page_Load(object sender, EventArgs e)
{
using (Bitmap bitmap = new Bitmap(100, 100))
{
using (Graphics graphics = Graphics.FromImage(bitmap))
{
IntPtr hdc = graphics.GetHdc();
IntPtr pen = CreatePen(0, (int)2, (uint)0);
IntPtr hObject = SelectObject(hdc, pen);
DeleteObject(hObject);
DeleteObject(pen);
graphics.ReleaseHdc();
Response.Write(string.Format("HDC handle: {0}", hdc));
Response.Write("<br/>");
Response.Write(string.Format("CreatePen pen: {0}", hObject));
Response.Write("<br/>");
Response.Write(string.Format("SelectObject returned: {0}", hObject));
}
}
}
Most GDI calls are explicitly blocked by the Azure App Service sandbox, so the erroneous behavior you're seeing is expected. There are no workarounds, unfortunately.
You can find more information about the sandbox and the reasoning behind this limitation here: https://github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox
For the sake of radical attack surface area reduction, the sandbox prevents almost all of the Win32k.sys APIs from being called, which practically means that most of User32/GDI32 system calls are blocked. For most applications this is not an issue since most Azure Web Apps do not require access to Windows UI functionality (they are web applications after all).
Some exceptions are made to enable popular PDF generation libraries to work. See the link above for more details.
Most of those GDI calls are now available in the windows container in azure app service. https://azure.microsoft.com/en-us/updates/app-service-announces-general-availability-of-windows-container-support/. However you need to deploy your application as a containerised one.
I am trying to call WaitForSingleObject method from C#, as documented here:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx
In order to call this function I need to create a Handle, or I need to get a Handle of type IntPtr, how can it be done?
I've tried this function that I found:
http://www.pinvoke.net/default.aspx/kernel32.WaitForSingleObject
[DllImport("coredll.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)]
public static extern IntPtr CreateEvent(HANDLE lpEventAttributes, [In, MarshalAs(UnmanagedType.Bool)] bool bManualReset, [In, MarshalAs(UnmanagedType.Bool)] bool bIntialState, [In, MarshalAs(UnmanagedType.BStr)] string lpName);
Or for instance, when I am getting handle from console:
IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;
It throws a DllNotFoundException.
What's the issue here?
I need it in order to run the process with this function call, and to take a dump form its process, for my ClrMd library learning.
Any help will be appreciated.
Code sample:
static void Main(string[] args)
{
var autoEvent = new AutoResetEvent(false);
//this is where I get the DllNotFoundException
WaitForSingleObject(autoEvent.Handle, WAIT_TIMEOUT );
}
[DllImport("kernel32.dll")]
static extern uint WaitForMultipleObjects(uint nCount, IntPtr[] lpHandles, bool bWaitAll, uint dwMilliseconds);
public const Int32 WAIT_TIMEOUT = 0x102;
I would not go through WinApi to get this from C#: you have EventWaitHandler and other synchronization objects in C#, use them:
WaitHandle wh = new EventWaitHandler();
//do whatever you need
...
WaitHandler.WaitOne(wh); // equivalent to WaitForSingleObject in WinApi
you can use wh.SafeWaitHandle if you really need to interop with WinApi
Also I suspect Process.GetCurrentProcess().MainWindowHandle cannot work in a Console Application, that has not any window at all
I want to call native method (WaitForMultipleObjects) which waits for some handle (don't really mind which one), then I want to see it on thread stack using ClrMd library, from dump file
OK, so what about new ManualResetEvent(false).WaitOne()? This should show up in the dump file. And it's reliable.
Just picking any existing handle is not reliable because it might be signaled or be destroyed at any time. Or, you might change its state by waiting. There is no need, a ManualResetEvent can create you a fresh handle.
My mistake I've posted WaitForMultipleObjects instead of WaitForSingleObject, the main issue was that WaitForSingleObject stayed with DllImport("coredll.dll"...) I don't know where did I found it but I did...
Sorry for the confusion
I want to watermark a textbox, and found several different ways of doing it, but one that I liked uses SendMessage and an external DLL. However, I think I heard somewhere that doing it this way can cause BSOD since it isn't managed. Is this true, or is it just hear-say.
http://vidmar.net/weblog/archive/2008/11/05/watermarked-textbox-in-windows-forms-on-.net.aspx
private const uint ECM_FIRST = 0x1500;
private const uint EM_SETCUEBANNER = ECM_FIRST + 1;
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, uint wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
The short answer is no. It won't cause a BSOD, although it could crash your program.
WinForms is basically built on top of Windows API calls, so when done right, custom API calls should work good as well.
One other thing to keep in mind is that if you do call the Windows API, it may create portability issues, such as when porting to Mono, as those DLLs will most likely not be available.