This code that might seem useless it reproduces the problem. Another application is using
http://printqueuewatch.codeplex.com/ to be notified when a print job is sent to printer.
It works but sometimes when you send a print job it crashes here GetPrintJobInfoCollection.
I have pasted the inner exception. To reproduce I send with Notepad++ or my application a small text file about 20 times until i get a crash.
If after the crash I call GetPrintJobInfoCollection it works successfully or I retry.
Any suggestion how to fix this ?
while (true)
{
Thread.Sleep(10);
LocalPrintServer server = new LocalPrintServer();
var q = server.GetPrintQueue("vp1");
q.Refresh();
// Debug.WriteLine(q.IsBusy);
PrintJobInfoCollection infos = null;
infos = q.GetPrintJobInfoCollection();
}
Error in
System.NullReferenceException was unhandled Message=Object reference
not set to an instance of an object. Source=System.Printing
StackTrace:
at MS.Internal.PrintWin32Thunk.AttributeNameToInfoLevelMapping.InfoLevelCoverageList.Release()
at MS.Internal.PrintWin32Thunk.EnumDataThunkObject.GetPrintSystemValuesPerPrintJobs(PrintQueue
printQueue, Queue`1 printObjectsCollection, String[] propertyFilter,
UInt32 firstJobIndex, UInt32 numberOfJobs)
at System.Printing.PrintJobInfoCollection..ctor(PrintQueue printQueue, String[] propertyFilter)
at System.Printing.PrintQueue.GetPrintJobInfoCollection()
at WpfApplication7.MainWindow.button2_Click(Object sender, RoutedEventArgs e) in
According to this MSDN article you shouldn't use System.Printing namespace.
Classes within the System.Printing namespace are not supported for use
within a Windows service or ASP.NET application or service. Attempting
to use these classes from within one of these application types may
produce unexpected problems, such as diminished service performance
and run-time exceptions. If you want to print from a Windows Forms
application, see the System.Drawing.Printing namespace.
I am thinking that your problem is due to resource leak. The LocalPrintServer class seems to be an unmanaged resource and needs to be disposed.
Related
The issue:
We have an application written in C# that uses UIAutomation to get the current text (either selected or the word behind the carret) in other applications (Word, OpenOffice, Notepad, etc.).
All is working great on Windows 10, even up to 21H2, last update check done today.
But we had several clients informing us that the application is closing abruptly on Windows 11.
After some debugging I've seen some System.AccessViolationException thrown when trying to use the TextPatternRange.GetText() method:
System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
What we've tried so far:
Setting uiaccess=true in manifest and signing the app : as mentionned here https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/350ceab8-436b-4ef1-8512-3fee4b470c0a/problem-with-manifest-and-uiaccess-set-to-true?forum=windowsgeneraldevelopmentissues => no changes (app is in C:\Program Files\
In addition to the above, I did try to set the level to "requireAdministrator" in the manifest, no changes either
As I've seen that it may come from a bug in Windows 11 (https://forum.emclient.com/t/emclient-9-0-1317-0-up-to-9-0-1361-0-password-correction-crashes-the-app/79904), I tried to install the 22H2 Preview release, still no changes.
Reproductible example
In order to be able to isolate the issue (and check it was not something else in our app that was causing the exception) I quickly made the following test (based on : How to get selected text of currently focused window? validated answer)
private void btnRefresh_Click(object sender, RoutedEventArgs e)
{
var p = Process.GetProcessesByName("notepad").FirstOrDefault();
var root = AutomationElement.FromHandle(p.MainWindowHandle);
var documentControl = new
PropertyCondition(AutomationElement.ControlTypeProperty,
ControlType.Document);
var textPatternAvailable = new PropertyCondition(AutomationElement.IsTextPatternAvailableProperty, true);
var findControl = new AndCondition(documentControl, textPatternAvailable);
var targetDocument = root.FindFirst(TreeScope.Descendants, findControl);
var textPattern = targetDocument.GetCurrentPattern(TextPattern.Pattern) as TextPattern;
string text = "";
foreach (var selection in textPattern.GetSelection())
{
text += selection.GetText(255);
Console.WriteLine($"Selection: \"{selection.GetText(255)}\"");
}
lblFocusedProcess.Content = p.ProcessName;
lblSelectedText.Content = text;
}
When pressing a button, this method is called and the results displayed in labels.
The method uses UIAutomation to get the notepad process and extract the selected text.
This works well in Windows 10 with latest update, crashes immediately on Windows 11 with the AccessViolationException.
On Windows 10 it works even without the uiaccess=true setting in the manifest.
Questions/Next steps
Do anyone know/has a clue about what can cause this?
Is Windows 11 way more regarding towards UIAutomation?
On my side I'll probably open an issue by Microsoft.
And one track we might follow is getting an EV and sign the app itself and the installer as it'll also enhance the installation process, removing the big red warnings. But as this is an app distributed for free we had not done it as it was working without it.
I'll also continue testing with the reproductible code and update this question should anything new appear.
I posted the same question on MSDN forums and got this answer:
https://learn.microsoft.com/en-us/answers/questions/915789/uiautomation-throws-accessviolationexception-on-wi.html
Using IUIautomation instead of System.Windows.Automation works on Windows 11.
So I'm marking this as solved but if anyone has another idea or knows what happens you're welcome to comment!
Recently, my application has crashed when trying to display a rather lengthy (but otherwise simple) HTML e-mail.
The crash was caused by mshtml.dll getting a stack overflow (exception code 0xc00000fd). Of note here is that this didn't throw an exception but it actually just crashed the program as a whole. The error was retrieved from the Windows event log.
In the process of debugging, I created a smaller sample solution to try and narrow down the issue. However, not only does it work fine in the sample solution, it behaves completely different from the main program despite running the same code even for the simplest of HTML strings.
The code is as follows:
var webBrowser1 = new System.Windows.Forms.WebBrowser();
webBrowser1.AllowNavigation = false;
webBrowser1.AllowWebBrowserDrop = false;
webBrowser1.Navigate("about:blank");
var doc = webBrowser1.Document.OpenNew(true);
doc.Write("<HTML><BODY>This is a new HTML document.</BODY></HTML>");
var count = doc.All.Count;
var html = doc.All[0].OuterHtml;
In the sample solution this evaluates to:
count = 4; // [HTML, HEAD, TITLE, BODY]
html = "<HTML><HEAD></HEAD>\r\n<BODY>This is a new HTML document.</BODY></HTML>";
Meanwhile in the main program it comes out to:
count = 3; // [HTML, HEAD, BODY]
html = "<html><head></head><body>This is a new HTML document.</body></html>";
These are small discrepancies but that is largely due to the simple HTML used. The one that causes the crash has rather significant differences.
I am absolutely stumped as to how the result can be so vastly different.
The documentation for HtmlDocument.Write(string) states that:
It is recommended that you write an entire valid HTML document using the Write method, including HTML and BODY tags. However, if you write just HTML elements, the Document Object Model (DOM) will supply these elements for you.
But I have no idea how the DomDocument is provided nor why they would be different in the first place. Both solutions are running in x64 Debug mode and Net-Framework 4.6.2.
Both load the module: C:\WINDOWS\assembly\GAC\Microsoft.mshtml\7.0.3300.0__b03f5f7f11d50a3a\Microsoft.mshtml.dll
How is it possible that these produce different results?!
Any and all help welcome.
Thanks in advance.
The difference in behavior stems from the registry entry as proposed by Jimi and linked here
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
To reiterate, in the above registry the main program had an entry "ApplicationFileName.exe"=dword:00002af9 while my new test-application didn't.
This, in and for itself, does not explain the crashing of mshtml.dll itself but since the question was about the difference in behavior I'll post this as the answer. The crash is most likely linked to the outdated version used by Visual Studio but I haven't yet had the chance to look into some of the proposed fixes for that.
This question already has answers here:
Load WPF application from the memory
(2 answers)
Closed 6 years ago.
First of all, let me say that I've looked through this, and i still haven't been able to find a great solution to my problem. (I will elaborate in post)
Now to the point.
I have a program which I want to secure with a login.
My setup is as follows:
Login.exe
Application.exe (Gathered from server into byte[])
The user should login, and when successfully logged in, get the server file (Application.exe) and run it, however this file must not be stored locally on the users machine. Instead, this file, which is stored as a byte array, should be launched as a program, but, if possible, not with a location on the harddrive.
Here's how the user would see it:
First they'd get the login application, login and the application
would download the file from server, and execute it.
Now the main problem i've been struggling with is, that whenever i load this byte array, i get the following Exception:
System.Reflection.TargetInvocationException: The destination of an activation triggered an exception. ---> System.InvalidOperationException: Can not create more than one instance of System.Windows.Application in the same AppDomain.
I've tried with multiple ways, but I've always ended up with the following code:
Assembly a = Assembly.Load(tmpbytearray);
MethodInfo method = a.EntryPoint;
if (method != null)
{
object o = a.CreateInstance(method.Name);
method.Invoke(o, null);
}
I've also tried with
Assembly assembly = Assembly.Load(tmpsrc);
//entrypoint: MyMainApplication.App.Main
Type type = assembly.GetType("MyMainApplication.App");
var obj = Activator.CreateInstance(type);
type.InvokeMember("Main",
BindingFlags.Default | BindingFlags.InvokeMethod,
null,
obj,
null);
But still stuck with the same Exception.
As I've read through the reference (Section B and C) from the top I've also seen the usage of CreateInstanceFromAndUnwrap, but as I can't find a way to supply it with a byte array, instead of a file path, I've decided not to go that way.
Now I'm back to square one, and therefore asking here in my last hopes to sum up a solution to this project.
If i've made some misunderstandings throughout the post, feel free to ask, as I will do my best to be as clear and understandable as possible.
Thanks in advance!
UPDATE (Maybe another approach)
I've now thought of making a small console based application, which would act as a "launcher" for this application. However this also gives an exception:
System.Reflection.TargetInvocationException: The destination of an activation triggered an exception. ---> System.IO.IOException: The resource mainwindow.xaml was not found.
This exception is really weird, as the application itself works when ran. So the following:
Assembly a = Assembly.Load(tmpsrc);
MethodInfo method = a.EntryPoint;
if (method != null)
{
object o = a.CreateInstance(method.Name);
method.Invoke(o, null); //Exception.
}
Depending on what might be the most easy solution, what would you prefer, and how would you think of a possible solution to any of the approaches (The second, or first approach)?
(I cannot mark this as complete, but this question has now been solved)
So, some struggles later, I've finally managed to get this working.
I ended up trying many things, but the solution for me was based on this question.
I took the loader class in my Login Application and added the rest after the login has been authorized successfully:
var domain = AppDomain.CreateDomain("test");
domain.Load("Login");
var loader = (Loader)domain.CreateInstanceAndUnwrap("Login", "Login.Loader");
loader.Load(tmpsrc);
After that it somehow worked, which i'm quite surprised for. But anyways, thanks for the help and pinpoints into the proper subjects!
For our current project we are using DBus (1.6.n).
It is largely accessed from C++ in shared memory mode, and this works really well.
I am now trying to access the same DBus from a C# program.
In order to try things out first, I downloaded the latest version of dbus-sharp I could find, and started the daemon included in the download to see if I could connect to it from my test C# app.
Whenever I make a connection, the daemon console shows that I am communicating with it, but as soon as I try to access any methods on the connection I get the error;
'Access is denied: DBus.BusObject'
Here is the code I have tried;
DBus.Bus dBus = null;
try
{
//input address comes from the UI and ends up as "tcp:host=localhost,port=12345";
//dBus = new Bus(InputAddress.Text + inputAddressExtension.Text);
//string s = dBus.GetId();
//dBus.Close();
//DBus.Bus bus = DBus.Bus.System;
//DBus.Bus bus = Bus.Open(InputAddress.Text + inputAddressExtension.Text);
//DBus.Bus bus = DBus.Bus.Session;
//DBus.Bus bus = DBus.Bus.Starter;
var conn = Connection.Open(InputAddress.Text + inputAddressExtension.Text);
var bus = conn.GetObject<Introspectable>(#"org.freedesktop.DBus.Introspectable", new ObjectPath("/org/freedesktop/DBus/Introspectable"));
bus.Introspect();
}
finally
{
if(dBus != null)
dBus.Close();
}
The commented code produces the same error eventually too.
I have stepped through with the debugger and it always gets to the following code in the TypeImplementer.cs;
public Type GetImplementation (Type declType)
{
Type retT;
lock (getImplLock)
if (map.TryGetValue (declType, out retT))
return retT;
string proxyName = declType.FullName + "Proxy";
Type parentType;
if (declType.IsInterface)
parentType = typeof (BusObject);
else
parentType = declType;
TypeBuilder typeB = modB.DefineType (proxyName, TypeAttributes.Class | TypeAttributes.Public, parentType);
if (declType.IsInterface)
Implement (typeB, declType);
foreach (Type iface in declType.GetInterfaces ())
Implement (typeB, iface);
retT = typeB.CreateType (); <======== Fails here ==========
lock (getImplLock)
map[declType] = retT;
return retT;
}
I have not found any useful examples or documentation about accessing DBus from C#, and there seem to be few recent entries about this anywhere, so maybe no-one else is trying this.
I am running the daemon in the same folder as the test program.
As I am running on windows, the daemon is listening on the tcp setting;
string addr = "tcp:host=localhost,port=12345";
Since this is the example included with the download, I thought it would be really simple to get it going, but alas no luck yet.
Has anyone else been here and know the next piece of the puzzle?
Any ideas would be appreciated.
Having received no comment or response, I will answer the question with the information I have found since asking it.
There appears to be no useful C# interface to DBus. (By useful, I mean one that works!)
The only information or examples I could find are not up to date and no effort appears to be being expended on providing a working interface.
I have decided to interface with DBus by using a C++ implementation written as a Windows service, and my C# program will send messages to DBus via the service. This seems to work ok, so satisfies the business need.
I am disappointed not to be able to get the C# to DBus working, but there are lots of service bus implementations that work on Windows, so in future I will look at implementing those instead of DBus.
If anyone does come up with a workable, documented solution to accessing DBus from C# on Windows, I would still be interested to see it.
I had the same error when I created new test project and add dbus cs source files to it main project assembly. It was when IBusProxy type dynamically created in dynamically created assembly.
asmB = AppDomain.CurrentDomain.DefineDynamicAssembly (new AssemblyName ("NDesk.DBus.Proxies"), canSave ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Run);
modB = asmB.DefineDynamicModule ("NDesk.DBus.Proxies");
......
retT = typeB.CreateType ();
I think it was cause current running assembly isnt friendly for created assembly. And just when I add to project compiled NDesk.DBus.dll this error disappeared.
when i run this code :
CONADefinitions.CONAPI_FOLDER_INFO2 FolderInfo;
int iResult = 0;
IntPtr Buffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CONADefinitions.CONAPI_FOLDER_INFO2)));
iResult = CONAFileSystem.CONAFindNextFolder(hFindHandle, Buffer);
while (iResult == PCCSErrors.CONA_OK )
{
FolderInfo = (CONADefinitions.CONAPI_FOLDER_INFO2)Marshal.PtrToStructure(Buffer,typeof(CONADefinitions.CONAPI_FOLDER_INFO2));
//......................... i got an error msg here as follows:
// Error Messege:
FatalExecutionEngineError was detected Message: The runtime has encountered a
fatal error. The address of the error was at 0x7a0ba769, on thread 0x1294. The
error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe
or non-verifiable portions of user code. Common sources of this bug include
user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.
how to use CONADefinitions.CONAPI_FOLDER_INFO2, coz when i use CONADefinitions.CONAPI_FOLDER_INFO it only gives me the name and lable of the device
but when is use CONADefinitions.CONAPI_FOLDER_INFO2 it gives me freeSize and TotalSize
please help
I'm not sure what that error means but if you want to get the drive's size, you can use
DriveInfo di = new DriveInfo("f"); //Put your mobile drive name
long totalBytes = di.TotalSize;
long freeBytes = di.TotalFreeSpace;
It is correct that you get the exception when you try and convert the data in the buffer to a different type of structure than was originally created by CONAFileSystem.CONAFindNextFolder.
You are trying to force a data structure of type CONADefinitions.CONAPI_FOLDER_INFO into a structure of type CONADefinitions.CONAPI_FOLDER_INFO2. They almost certainly have different lengths and so on so its extremely unlikely this method would ever work.
From experience with C++ development on the Symbian OS, the pattern Nokia are likely to be using here is one where they have subsequently developed a newer version of the API and so have created a newer version of the CONADefinitions.CONAPI_FOLDER_INFO structure (i.e. CONADefinitions.CONAPI_FOLDER_INFO2).
Assuming this is correct there are 3 likelihoods:
1) There is an enum parameter to the first function which specifies which version of the output structure is to be created.
2) There is a new function which returns the new structure e.g. CONAFileSystem.CONAFindFirstFolder2, CONAFileSystem.CONAFindNextFolder2
3) Nokia have developed the new version internally but not yet released it publicly.