.NET CF - MSMQ ActivateDevice() Crash - compact-framework

I have a .NET 3.5 Compact Framework application that uses MSMQ.
We are running this application on an Intermec CN3, Windows Mobile 5.0 device.
However, when our application first tries to active the MSMQ service with ActivateDevice (pinvoke), the application crashes and we get the error report message:
A problem has occuurred with myApp.exe
Please tell Microsoft about this problem, at not cost to you. ect..
What we have done is this:
Hard Reset the Device
Install NETCFv35.wm.armv4i.cab
Install msmq.arm.CAB
*Run a CF console app that sets up MSMQ and the registry
Soft reset the PDA
*Run our application which calls ActivateDevice() on startup
After doing a soft reset, the first time that ActivateDevice() is called, the application crashes.
However, now that we have called ActivateDevice(), MSMQ services are working on the device atleast until it is soft reset again.
Also, any calls to ActivateDevice() will not crash the application.
The console app that we run after a hard reset is basically this:
class InstallRegister
{
public void Main()
{
RunMsmqAdmin("install");
RunMsmqAdmin("register install");
RunMsmqAdmin("register");
SetQuotaValueRegistry("MachineQuota");
SetQuotaValueRegistry("DefaultLocalQuota");
SetQuotaValueRegistry("DefaultQuota");
RunMsmqAdmin("enable binary");
RunMsmqAdmin("enable srmp");
RunMsmqAdmin("start");
RegFlushKey(0x80000002);
}
private void SetQuotaValueRegistry(string quotaValueName)
{
Microsoft.Win32.Registry.SetValue(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSMQ\\SimpleClient\\"
, quotaValueName
, 100000);
}
private void RunMsmqAdmin(string command)
{
using (Process _process = new Process())
{
_process.StartInfo.FileName = #"\windows\msmqadm.exe";
_process.StartInfo.Arguments = command;
_process.StartInfo.UseShellExecute = true;
_process.Start();
_process.WaitForExit();
}
}
[System.Runtime.InteropServices.DllImport("CoreDll.dll", EntryPoint = "RegFlushKey", SetLastError = true)]
private static extern uint RegFlushKey(uint hKey);
}
Our applications call to ActivateDevice() is basically this:
class ActivateMSMQ
{
public void Active()
{
var handle = ActivateDevice("Drivers\\BuiltIn\\MSMQD", 0);
CloseHandle(handle);
}
[System.Runtime.InteropServices.DllImport("CoreDll.dll", SetLastError = true)]
private static extern IntPtr ActivateDevice(string lpszDevKey, Int32 dwClientInfo);
[System.Runtime.InteropServices.DllImport("CoreDll.dll", SetLastError = true)]
private extern static Int32 CloseHandle(IntPtr hProcess);
}
ActivateDevice() still causes our app the crash whenever the device is soft reset.
Has anyone else experienced this with MSMQ on the compact framework?

Yes this problem occurs. the quick and easy fix for this is to put the code into a separate executable, then on the start of you app launch this process and wait for completion. The process will terminate due to the crash but will return with your calling app still intact. Then just make sure the executable is deployed in your cab so you app can call it.

Related

Keep program going in background?

I want my program to keep sending messages to a window (AppActivate(os)) even if that program is not in the foreground. Let's my program is open and I set it to App1 to send messages over and over, and I want to browse facebook. How can I make it so my program still runs in the background and sends messages while I browse facebook?
os = combobox1.text
The combobox retrieves each window handle.
Use a thread of your function. It will not end until killed in task manager.
using System;
using System.Threading;
class Test
{
static void Main()
{
Thread newThread =
new Thread(new ThreadStart(Work.DoWork));
newThread.Start();
}
}
class Work
{
Work() {}
public static void DoWork()
{
for(;;)
{//FACEBOOK SPAMMER}
}
}
More at http://msdn.microsoft.com/en-us/library/xx3ezzs2(v=vs.110).aspx

Message Dialog not displaying on Windows 8 tablet - Caliburn.Micro/C#

Has anyone heard of any issues with MessageDialog's not displaying on Windows 8 tablets? Or more specifically Samsung 700t? It uses a regular intel process and not ARM. I built the app on a laptop and the messagedialog shows when debugging from the laptop, shows on the tablet simulator but doesn't show on the actual tablet.
I'm using the Caliburn.Micro IResult interface to display the messagedialog in the view.
Heres snippits of code that I'm using:
public IEnumerable<IResult> NavExecute(String method)
{
Windows.UI.ViewManagement.ApplicationView.TryUnsnap();
var conn = NetworkInformation.GetInternetConnectionProfile();
if (conn.GetNetworkConnectivityLevel() != NetworkConnectivityLevel.InternetAccess)
{
yield return new MessageDialogResult("Internet Connection Not Detected", "Connection Error");
netOn = false;
}
}
the above is in my view model base class, and heres the implementation of the IResult class itself:
public class MessageDialogResult : ResultBase
{
private readonly string _content;
private readonly string _title;
public MessageDialogResult(string content, string title)
{
_content = content;
_title = title;
}
public async override void Execute(ActionExecutionContext context)
{
var dialog = new MessageDialog(_content, _title);
await dialog.ShowAsync();
OnCompleted();
}
}
I doub't it's an issue with the code since I'm debugging in x86 mode on both devices (before anyone asks why I'm not debugging for all devices it's because I'm using SQLite which requires a seperate package for each arhitecture.)
I'm not sure if theres a setting somewhere in Windows 8 that disables in app popups, but I couldn't find one.
Any ideas?
Are you handling the callback of Coroutine.Execute?
The callback on Execute might be calling back with an exception thrown by the coroutine - this would silently fail if you weren't explicitly looking for it in the callback
Coroutine.Execute(YourEnumerator(), new ActionExecutionContext { Blah }, (o, e) => {
if(e.Error != null) // Something went wrong
});
Maybe the async await is throwing or something like that (can't think why!)
Edit:
Ah additionally stuff in your enumerator could also throw:
Windows.UI.ViewManagement.ApplicationView.TryUnsnap();
var conn = NetworkInformation.GetInternetConnectionProfile();
Either one could throw making the outer enumerator swallow an exception if not handled in the callback - or could be a nullref on conn?
The reason why GetInternetConnectionProfile() was returning a null ref was due to the fact that when on a laptop, if you disconnect from a wireless connection the laptop's internet connection profile defaults to ethernet, whereas the tablet (at least the Samsung 700T) doesn't have an ethernet port so it's connection profile doesn't exist if a wireless connection isn't established.
Thanks to Charleh for pointing me in the right direction.

Visual Studio IDE Crash Using IDispatch.GetTypeInfo() for Excel.Application

I am writing an application to interface with COM components and I have run into a problem when working with the Excel.Application component while running my application in the Visual Studio 10 IDE. I am getting a fatal Out of Memory error. Everything runs fine if I just run the EXE, but this severely limits my debugging capabilities. All other COM components I have accessed this way work fine, including both home-grown and commercially available components.
Here is a console app that demonstrates this crash. I have removed all error handling for simplicity's sake. Putting a try/catch block around the offending code does not help. This project requires a reference to the CustomMarshalers.dll.
class Program
{
static void Main(string[] args)
{
InstantiateCOMComponent("Excel.Application");
}
private static void InstantiateCOMComponent(string name)
{
Type typeInfo = Type.GetTypeFromProgID(name);
object instance = Activator.CreateInstance(typeInfo);
IDispatch dispatch = instance as IDispatch;
// NOTE: THIS CALL FAILS WITH Excel.Application in the IDE
// but succeeds at run-time!! (Out of Memory fatal error)
Type comTypeInfo;
dispatch.GetTypeInfo(0, 0, out comTypeInfo);
}
}
[ComImport,
Guid("00020400-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDispatch
{
void Reserved();
[PreserveSig]
int GetTypeInfo(uint nInfo, int lcid,
[MarshalAs(
UnmanagedType.CustomMarshaler,
MarshalTypeRef = typeof(TypeToTypeInfoMarshaler))]
out System.Type typeInfo);
}
I am thinking the problem is simply due to Excel's size.

Regularly invoking an interactive process (WatiN tests) via Task Scheduler

I'm using a suite of WatiN tests driving IE to do some periodic sanity checking for the purposes of monitoring a site.
The suite works fine when I invoke it interactively and/or when I configure the task in Task Scheduler to "Run only when the user is logged on".
However, when I set it to "Run whether the user is logged on or not", and check the "Run with highest privileges" option (WatiN can't talk to the browser satisfactorily under Windows Server 2008 and many other OSes without having admin privileges), WatiN can't communicate with it's iexplore.exe instances satisfactorily (they start, but I get a timeout exception as detailed in this post). I have added the site I'm hitting to the Trusted sites for both admin and non-admin contexts of IE. I've tried with and without elevation, with and without disabling ESC and with and with and without turning off Protected Mode for the internet zone. As my non-GUI tests are happy, I assume it's a limitation of the type of interactivity that's possible in the context of a non-interactive Scheduled Task, even when "Run with highest privileges".
Right now, my temporary workaround is to require a [TS] session to remain open at all times, ready to run the scheduled task.
If I was to persist with this, I'd at a minimum add a heartbeat notification to allow something to monitor that the task is actually getting to run [e.g., if someone logs the session off or reboots the box].
However, I'm looking for something more permanent -- something that is capable of regularly invoking my WatiN tests [run using xunit-console.x86.exe v 1.5] on my Windows Server 2008 [x64] box, just like Task Scheduler but with a proper Interactive session.
I'd prefer not to use psexec or remcom if possible, and can't see how creating a Windows Service would do anything other than add another point of failure but I'd be interested to hear of all proven solutions out there.
I was able to run Watin tests using Scheduled Task in the "Run whether user is logged on or not" mode.
In my case I tracked the issue down to m_Proc.MainWindowHandle being always 0 when IE is created from a scheduled task running without a logged on user.
In Watin sources this is in the IE.cs:CreateIEPartiallyInitializedInNewProcess function
My workaround is to manually enumerate top level windows and find a window with className == "IEFrame" that belongs to the process instead of using Process.MainWindowHandle property.
Here is the code snippet. All pinvoke i copied directly from Watin source.
public static class IEBrowserHelper
{
private static Process CreateIExploreInNewProcess()
{
var arguments = "about:blank";
arguments = "-noframemerging " + arguments;
var m_Proc = Process.Start("IExplore.exe", arguments);
if (m_Proc == null) throw new WatiN.Core.Exceptions.WatiNException("Could not start IExplore.exe process");
return m_Proc;
}
class IeWindowFinder
{
#region Interop
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32", EntryPoint = "GetClassNameA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
internal static extern int GetClassName(IntPtr handleToWindow, StringBuilder className, int maxClassNameLength);
#endregion
readonly Process IeProcess;
IntPtr HWnd = IntPtr.Zero;
public IeWindowFinder(Process ieProcess)
{
this.IeProcess = ieProcess;
}
public IntPtr Find()
{
EnumWindows(FindIeWindowCallback, IntPtr.Zero);
return HWnd;
}
bool FindIeWindowCallback(IntPtr hWnd, IntPtr lParam)
{
uint processId;
GetWindowThreadProcessId(hWnd, out processId);
if (processId == IeProcess.Id)
{
int maxCapacity = 255;
var sbClassName = new StringBuilder(maxCapacity);
var lRes = GetClassName(hWnd, sbClassName, maxCapacity);
string className = lRes == 0 ? String.Empty : sbClassName.ToString();
if (className == "IEFrame")
{
this.HWnd = hWnd;
return false;
}
}
return true;
}
}
public static WatiN.Core.IE CreateIEBrowser()
{
Process ieProcess = CreateIExploreInNewProcess();
IeWindowFinder findWindow = new IeWindowFinder(ieProcess);
var action = new WatiN.Core.UtilityClasses.TryFuncUntilTimeOut(TimeSpan.FromSeconds(WatiN.Core.Settings.AttachToBrowserTimeOut))
{
SleepTime = TimeSpan.FromMilliseconds(500)
};
IntPtr hWnd = action.Try(() =>
{
return findWindow.Find();
});
ieProcess.Refresh();
return WatiN.Core.IE.AttachTo<WatiN.Core.IE>(
new WatiN.Core.Constraints.AttributeConstraint("hwnd", hWnd.ToString()), 5);
}
}
then instead of new IE() use IEBrowserHelper.CreateIEBrowser()
From the command-prompt, you can schedule an interactive task like this:
C:\Users\someUser>schtasks /create /sc once /st 16:28 /tn someTask /tr cmd.exe
... where sc is the schedule, st is the start-time, tn is the taskname you choose (can be anything), and tr is the command you want to run. Obviously, for a recurring task, you would change sc to monthly, weekly, etc. Just type "schtasks /create /?" for more info.

How to start a windows service in Visual Studio 2008?

IN Visual Studio when I try to start a windows service project it tells me I cant because I have to use "NET Start" and so forth.
I remember in VS 2003 that when I pressed play it started the service and stop stopped it. Is there any way that when I press play or start for that windows service project I can have this same functionality.
What I currently do is install them using installutil and I put a pre-processor command with System.Diagnostics.Debug.Launch() when I have a compilation variable defined and when I use the service manager it shows me the window to select the debugger. Still this method is somewhat cumbersome.
For anyone else reading this, remember to try to debug ONE thread at a time.
I usually allow for a command line switch that I can pass to my service using the command line argument settings in the IDE. When this switch is on I can run my service as a regular app. The only issue here is that you need to remember that services usually run under accounts with restricted permissions, so debugging as an app in your user context may behave differently when accessing secured resources. Here is example code:
static void Main()
{
if (IsDebugMode())
{
MyService svc = new MyService();
svc.DebugStart();
bool bContinue = true;
MSG msg = new MSG();
// process the message loop so that any Windows messages related to
// COM or hidden windows get processed.
while (bContinue && GetMessage(out msg, IntPtr.Zero, 0, 0) > 0)
{
if (msg.message != WM_QUIT)
DispatchMessage(ref msg);
else
bContinue = false;
}
}
else
{
ServiceBase.Run(new MyService());
}
}
public void DebugStart()
{
this.OnStart(null);
}
static bool IsDebugMode()
{
return (System.Environment.CommandLine.IndexOf("debug") > -1);
}