Best windows questions in April 2012

Vista Exception in VB .NET Application "Exception Processing Message"

8 votes

Background : I have built a VB .NET application on the 4.0 Framework, part of the primary functionality is the built in AxWMPLib.AxWindowsMediaPlayer which allows us to pass a file path as a URL to the player and then play it through the built in media player. My Development Platform is VS 2010 Pro on Windows 7.

Problem: We have recently moved to testing this application on multiple OS's. The Application runs fine on Win 7 on multiple win7 machines, some used for development others not. The problem is when we run the application on Vista. the very first time the application tries to play a file after it has been opened it will throw an error

enter image description here

It does this the majority of times, but not always, and I have been unable to establish a pattern for the few times it has not thrown the error. Additionally, it only does this for the first file it plays not for subsequent files. And it eludes Try catches for error handling.

Research: I have done a good bit of research on this issue. I have found it seems to plague other media players and websites, even WMP on some machines. Some articles point to specific Windows KB updates, others suggest running a repair disk to repair potentially bad dlls. I have tried many of these unsuccessfully, as the issue persists on the two Vista machines I have to test with.

Code : here is the method that is called when this error occurs

Public Sub playSelected(ByVal fileStr As String)
    If File.Exists(fileStr) Then
        Debugging.DebugPrint(" Play: " & fileStr)
        MediaPlayer.URL = fileStr
        Try
            MediaPlayer.Ctlcontrols.play()
        Catch ex As Exception
            MessageBox.Show("Could Not play the selected File please try again.  Exception : " + ex.Message)
        End Try
    Else
        Debugging.DebugPrint(" File Does not Exist: " & fileStr)
    End If 
End Sub

Purpose: I am hoping to find a way to handle this exception through code, potential previewing or sniping it if it is being thrown from one of the .NET controls i'm using. I would rather handle this via code if possible. If someone also has additional information on this specific error that would be welcome as well.

Resolution:

With credit to jornare for the information and push in the right direction I will explain my resolution, and the code behind it below, hope it helps.

First I had to modify the recommended answer, in a few distinct ways. The following two lines are declared in the class that calls the playSelected method above.

Public Declare Function SetErrorMode Lib "kernel32.dll" (ByVal uMode As System.UInt32) As System.UInt32
Private Const SEM_FAILCRITICALERRORS As System.UInt32 = &H1

you'll see the addition of the Const variable named SEM_FAILCRITICALERRORS, this is necessary to set the value of the variable to 1, in this case the name of the variable is very specific as it matches a flag var name in the SetErrorMode method, when set to true this flag disables CriticalErrors from showing. I also added the .dll ext to the Lib call, though it may not be necessary.

Below is my new playSelected method

Public Sub playSelected(ByVal fileStr As String)
    If File.Exists(fileStr) Then
        If isVista Then
            oldErrMode = SetErrorMode(SEM_FAILCRITICALERRORS)
        End If
        Debugging.DebugPrint(" Play: " & fileStr)
        MediaPlayer.URL = fileStr
        Try
            MediaPlayer.Ctlcontrols.play()
        Catch ex As Exception
            MessageBox.Show("Could Not play the selected File please try again.  Exception : " + ex.Message)
        End Try
        If isVista Then
            criticalFailureTimer.Interval = 2000
            criticalFailureTimer.AutoReset = False
            criticalFailureTimer.Start()
        End If
    Else
        Debugging.DebugPrint(" File Does not Exist: " & fileStr)
    End If

End Sub

now this is important! Initially I SetErrorMode back to the oldErrMode after the ctlcontrols.play call, but found this did not prevent the error. I set my VS in debug mode on my win7 machine and stepped through the code line by line. I found the code did not actually try to play the file until after the sub ended. This is why you see the timer calls. I set a 2 second timer to give myself a buffer so it could start the playing process with the Error Mode set correctly. below is the code I used for the timer elapsed event

'in my Constructor
If My.Computer.Info.OSFullName.Contains("Vista") Then
    isVista = True
    AddHandler criticalFailureTimer.Elapsed, AddressOf criticalTimerExpired
End If
'end of Constructor portion

Private Sub criticalTimerExpired(sender As Object, e As ElapsedEventArgs)
    SetErrorMode(oldErrMode)
End Sub

One last caveat I will give for this. This process to my understanding disables Critical Errors from being displayed, so be careful, in my case I was unable to find any specific error or system instability caused by the error thrown, so I temporarily disable this to add to usability of the program. I do not recommend doing this everytime you have a system error as often that error points to a flaw/bug in the program that should be fixed. Additionally, in my opinion you should never need to turn off critical errors permanently, meaning make sure you turn them back on when you're done. I hope this information helps and appreciate the time and knowledge of those who answered or up-voted the question.

From what I find on the net it could be caused by a faulty WMP plugin, codek or display drivers. Found also that you should be able to suppress this error by calling the Windows API function SetErrorMode(SEM_FAILCRITICALERRORS) before WMP starts loading the media file.

So, for Vb something like:

'declare
Private Declare Function SetErrorMode Lib "kernel32" (ByVal wMode As Long) As Long

'call it
Dim oldErrMode  As Long
oldErrMode = SetErrorMode(SEM_FAILCRITICALERRORS)

'Do your stuff here

'Set it back
SetErrorMode(oldErrMode )

I haven't tested this, so let me know if this helps.

How can I learn about the Win32 API?

8 votes

I want to learn how to be able to use the Win32 API, since recently I've got a lot of tasks I need to do which requires functions from user32.dll, so I'm trying to learn and I googled but the thing is: every tutorial there is about it, just tells you how to do a certain thing. like show a MessageBox through the Win32 API, but you can't actually learn the library.

So how do you actually learn it? How do you know all the functions? with managed libraries it's quite easily, especialy in VS with the Object Browser (which lets you see all the namespaces, classes, interfaces, etc.) but this thing is so messy (at least with C#).

The way I've been using it until now is just searching on Google for a task and seeing that it can be done with the Win32 API (I had no idea) and just copy the function and use it (and it's horrible for me, I feel I'm missing a lot of "power"). So, how can I learn it? Thanks.

To be clear: I'm not interested in a book. as bad as it sounds I need this knowledge for a project and I just don't have the time to invest in a book. I did get my answer although. thank you all.

From MSDN you can find the WinAPI list: The following is a list of the reference content for the Windows application programming interface (API). http://msdn.microsoft.com/en-us/library/ff818516(v=vs.85).aspx

You can learn some stuff via Visual Basic Win API functions. Examples are very easy to follow and understand. Then you can translate the code to C#.

There Are 598 Visual Basic Windows API Functions in 55 Category http://www.ex-designz.net/api.asp

Why does this code enable me to detect a debugger?

8 votes

Why this assembly code is an anti-debugging tool?

l1:
call l3
l2:
;some code
l3:
mov al, 0c3h
mov edi, offset l3
or ecx, -1
rep stosb

I know that C3h is RETN and I know that stobs write the value in al as opcode according to the offset in edi and it is done for ecx times because of rep.

I also aware the fact that stobs and stosw will run if they were pre-fetched on intel architecture as their original format.

If we run the program in debugged mode the pre-fetch is irrelevant and the l2 label will run (because it is single-step) otherwise if there is no debugger it will be ping-pong between l1 and l3 am I right?

When program is debugged (i.e. single step) prefetch queue is flushed at each step (when interrupt occurs). However, when executed normally that will not happen to rep stosb. Older processors didn't flushed it even when there was memory write to the cached area, in order to support self-modifying code that was changed except rep movs and rep stosb. (IIRC it was eventually fixed in i7 processors.)

That's why if there is a debugger (single step) code will execute correctly and when rep stosb is replaced by ret l2 will be executed. When there is no debugger rep stosb will continue, since ecx is the biggest possible it will eventually write somewhere it is not supposed to write and an exception will occur.

This anti-debugging technique is described in this paper.

is there 2G limit for file reading/writing by c++ fstream?

6 votes

I am writing a c++ program to read/write a large file (probably larger than 60GB). By googling the problem, it seems that there is a 2GB limit on file io in 32 bit system (I am using windows 7 64bit but my program was compiled with mingw32). In my program, I am writing 10 integers at a time to the file and all these numbers are generated randomly based on some algorithm. It seems that the program can run even when the file size bigger than 40GB but there is no way for me to check if the data read by the program is really the one stored in the file or some junk numbers. But anyway, the program doesn't report any warning or error. Is this really possible to read/write file larger than 60GB in a 32-bit program?

There's a limit on file size (4GB max, I think) on Fat32 file system. Windows 7 definitely shouldn't be using that filesystem by default.

Also on 32bit system there's a limit on the file size you can map into memory at once using CreateFileMapping/MapViewOfFile. However, fstream doesn't use CreateFileMapping/MapViewOfFile internally, so there's no limit for file size (aside from filesystem limits). And even with CreateFileMapping you can map portion of larger file into memory, so there's no limit aside from the one imposed by filesystem.

Retrieving a complete list of Windows processes in C

6 votes

I am developing a simple process statistics collection library for Windows. I'm enumerating the processes with EnumProcesses() function, and I try to open them with OpenProcess() call with PROCESS_QUERY_INFORMATION flag. The latter one fails for a bunch of system processes, though. At the same time, I see that similar applications (sysinternals tools, task manager, etc) seem to be able to retrieve information about these processes even without requiring Administrator privileges. I tried enabling the SeDebugPrivilege privilege, but it did help only when I ran my program as an Administrator -- and still, I could not open the Idle process, the System process and the audiodg process (I would like to be able to retrieve their information for consistency as well).

So the question is: how can I get information about all the processes (I see it done by 3rd-party applications, but I don't see how)? Is it possible to do it without Administrator privileges?

Are you familiar with CreateToolhelp32Snapshot and this function as well Process32First.

I have found this code-project When I used it a while ago it helped me a lot ...

What is difference between hotkey, shortcut and accelerator key?

6 votes
  1. What is the difference about them?

  2. In Qt, if I have a hotkey for QPushButton, I can make it by "Alt + ?", but if it's for qaction, I can press "?" only

In Windows, an accelerator key is application global; e.g. Alt+F4.

A shortcut key is part of the name of a menu item or button, where it can be underlined, and is available (without modifiers) when that menu item or button is directly available.

From Microsoft:

A hot key is a key combination that the user can press to perform an action quickly. For example, a user can create a hot key that activates a given window and brings it to the top of the z-order.

which seems to indicate that hot keys are system global.

To sum up:

  • shortcut key = no modifiers, local in menu or (for button) in window
  • accelerator key = typically with modifier, application global
  • hot key = apparently system global

I don't know about specific meanings in Qt; for that see the Qt documentation.

Is .git folder crossplatform?

6 votes

If the .git folder that was created using linux is copied to windows, will it work?

Yes, it will be okay - I work like this myself - on two computers with Linux and Windows .git directory is synced by dropbox, and there are absolutely no problems at all :)

btw - .hg works equally well.

File redirection in Windows and %errorlevel%

6 votes

Lets say we want to create an empty file in windows with the following command:

type nul > C:\does\not\exist\file.txt

the directory does not exist, so we get the error:

The system cannot find the path specified

If you print out the %errorlevel% the output is:

echo %errorlevel%
0

Yet the command was not successful!

I noticed, that windows does not set the %errorlevel% of the last command if you use redirection..

Is there a way around this?

You can use the following

C:\>type nul > C:\does\not\exist\file.txt && echo ok || echo fail
The system cannot find the path specified.
fail

C:\>echo %errorlevel%
1

I always assumed the && and || operators used ERRORLEVEL, but apparantly not.

Very curious that ERRORLEVEL is set after redirection error only if you use the || operator. I never would have guessed. Nor would I ever have bothered to test if not for your excellent question.

If all you want to do is set the ERRORLEVEL upon redirection failure, then of course you can simply do:

type nul > C:\does\not\exist\file.txt || rem

How to edit the registry keys of a specific user programatically?

5 votes

I want to change a few settings of a Windows user that I created in my application. If I understand correctly, his "HKEY_CURRENT_USER" values will be under HKEY_USERS/<sid>/.... Is this correct? How can I get the sid of the user, if I know the user name and the domain?

Edit: How can I correctly edit the HKCU keys of that user, if I have the sid already?

I have a program that does exactly that. Here is the relevant part of the code:

NTAccount ntuser = new NTAccount(strUser);
SecurityIdentifier sID = (SecurityIdentifier) ntuser.Translate(typeof(SecurityIdentifier));
strSID = sID.ToString();

You will need to import two namespaces:

using System.DirectoryServices;
using System.Security.Principal;

Hope this helps.

Then use Registry.Users.SetValue with SID string\path to set the registry value.

This might not work as intended if you are editing a logged-off profile, especially a roaming profile.

Does one need to call srand() C function per thread or per process to seed the randomizer?

5 votes

The caption pretty much says it.

PS. This is for C++ Windows program.

According to this MSDN documentation (assuming you are using Microsoft's C runtime library), the seed is thread-local, so you need to call srand() for each thread that is using rand(). Note that this may not be the case in other implementations.

C#: Could not load types from assembly

5 votes

After adding Lucene.net and Lucene.net Contrib to a C# MVC3, I get the message below after the first successful run. After receiving this error, I need to completely wipe C:\Users\Me\AppData\Local\Temp\Temporary ASP.NET Files before I can run the project again.

I've tried removing the Lucene files manually (including references in my project), and reinstalling them - both with NuGet and manually - but it's always the same situation; after the project has been run once, I start getting the following errors:

Note: Contrib.Regex is part of Lucene.net Contrib.

Server Error in '/' Application.

Could not load types from assembly Contrib.Regex, Version=2.9.4.0, Culture=neutral, PublicKeyToken=85089178b9ac3181, errors:
Exception: System.IO.FileLoadException: Could not load file or assembly 'Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181'

=== Pre-bind state information ===
LOG: User = rcw7\Me
LOG: DisplayName = Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181
(Fully-specified)
LOG: Appbase = file:///C:/Development/Projects/Foobar/Foobar/
LOG: Initial PrivatePath = C:\Development\Projects\Foobar\Foobar\bin
Calling assembly : Contrib.Regex, Version=2.9.4.0, Culture=neutral, PublicKeyToken=85089178b9ac3181.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Development\Projects\Foobar\Foobar\web.config
LOG: Using host configuration file: C:\Users\Me\Documents\IISExpress\config\aspnet.config
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Post-policy reference: Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181
LOG: Attempting download of new URL file:///C:/Users/Me/AppData/Local/Temp/Temporary ASP.NET Files/root/e9b4cfa4/edfa73f8/Lucene.Net.DLL.
WRN: Comparing the assembly name resulted in the mismatch: Revision Number
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
Exception: System.IO.FileLoadException: Could not load file or assembly 'Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181'

Full output here: http://pastebin.com/Vbu4VK7B

Initially I thought this was a problem local to my development environment, but after rebuilding and copying the project to our server, I get the same errors.

Any suggestions as how to overcome this? :-)

As it turns out, the DLL hell wasn't caused by my own meddling in configurations and compiled libraries. It was in fact caused by a collision between my newly downloaded version of Lucene.NET and a somewhat dated version bundled with Examine, which in turn was bundled with Umbraco 5.

Apparently the outdated, bundled Lucene.NET ended up in the shadow cache (Temporary ASP.NET Files), so after the next compile or IIS restart, execution would break. Clearing the shadow cache would allow for one success execution.

The weird thing was, that I was unable to find any reference anywhere in the debug output that hinted to the outdated version of Lucene.NET, either with a directory path or version number. The problem was spotted by comparing the file sizes of the shadow copied version of Lucene.NET and the version I intended to use. They were off, so I did a search for Lucene.NET.dll and found the one bundled with Examine in the Umbraco tree (under \App_Plugins\Examine)

The fast solution was to simply zip the Examine plugin, so Umbraco wouldn't see it. That leaves me without the Examine plugin, but I wasn't using it anyway.

The right solution would probably be to tell the app that it should ignore previous versions of Lucene.NET, but I haven't had any luck with that so far. This is what I added to web.config:

<dependentAssembly>
    <assemblyIdentity name="Lucene.Net" publicKeyToken="85089178b9ac3181" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-2.9.4.1" newVersion="2.9.4.1" />
</dependentAssembly>

This didn't seem to have any effect, and the outdated version still ended up in the shadow cache. I've moved this question here: How do I make Umbraco 5 ignore the bundled (with Examine) Lucene.NET

Thanks for your help and suggestions - it pointed me in the right direction! :-)

How do I call .NET from c++ in as a platform-independent way as possible

5 votes

I have a C++ app from which I want to call .NET (C#) methods. I was going to use C++/CLI, but it is only supported on Windows.

Since also we support the MAC, I'd like to call .NET from C++ in a way that will work on both Windows and Mac (with Mono).

What is the best way to do this?

EDIT: I should add that the c# code we wish to call is not ours. We have no way of making any changes to it. The c++ code, of course, is ours.

The easiest way is to expose the functionality via a function pointer. Both .Net and native code can interop with C/C++ code in the form of a function pointer. Function pointers are supported on all platforms where C++ code runs hence it can be written without any understanding of .Net.