Closed floriandevo closed 2 years ago
Thank you for the report. This exception (System.InvalidCastException: Specified cast is not valid. HResult: -2147467262) seems to be thrown from the following code.
I have never seen this exception thrown from here and so need to look into it. Then, what is your culture settings? French - France?
I tested Windows 11 with French language and culture settings but could not reproduce it.
Yep it's French - France !
I tried to change my language to english and the result is the same.
I'm wondering to install VS to check the exception.
If you can, could you test the following code on your environment and check if there is difference between GetOsVersion1 (current version) and GetOsVersion2 (slightly changed version)? https://gist.github.com/emoacht/b04be66acc9c4f43a667e8e8599dcd9a
Does this issue still persist? Otherwise, I will close this issue.
Sorry for the delay. When I start the application on VS, the exception is on this line of the GetOsVersion method :
using (var results = searcher.Get())
The detail of exception :
Managed Debugging Assistant 'DisconnectedContext'
Message=Managed Debugging Assistant 'DisconnectedContext' :
'Échec de la transition vers le contexte COM 0x10e8250 pour ce RuntimeCallableWrapper avec l'erreur suivante : Un appel sortant ne peut pas être effectué étant donné que l’application répartit un appel entrant synchrone. (Exception de HRESULT : 0x8001010D (RPC_E_CANTCALLOUT_ININPUTSYNCCALL)). Cela se produit habituellement car le contexte COM 0x10e8250 dans lequel ce RuntimeCallableWrapper a été créé a été déconnecté ou est occupé à autre chose et ne peut pas traiter la transition des contextes. Aucun proxy ne sera utilisé pour traiter la demande sur le composant COM. Cela peut entraîner des dysfonctionnements ou des pertes de données. Pour éviter ce problème, assurez-vous que tous les contextes/cloisonnements/threads COM restent actifs et sont disponibles pour la transition des contextes, tant que l'application n'en a pas terminé avec les RuntimeCallableWrappers qui représentent les composants COM qui s'y trouvent.'
The exception is the detail of the System.InvalidCastException.
I found a message that advices to take the code on Thread like this :
Version outputReturn = null;
Thread thread = new Thread(() =>
{
var query = new SelectQuery("Win32_OperatingSystem", "OSType = 18"); // WINNT
using var searcher = new ManagementObjectSearcher(query);
using var results = searcher.Get();
foreach (ManagementObject result in results)
{
using (result)
{
var input = (string)result.GetPropertyValue("Version");
if (Version.TryParse(input, out Version output))
outputReturn = output;
}
}
throw new InvalidOperationException("Failed to get OS version.");
});
thread.Start();
thread.Join(); //wait for the thread to finish
return outputReturn;
But now I have the InvalidOperationException("Failed to get OS version.");
.
The value of result
variable is : \\PC_NAME\root\cimv2:Win32_OperatingSystem=@
The first value of input
in the foreach is : 10.0.22000
.
Thanks for the report.
Before going into details, your code will never return correct version because it always go through throw new InvalidOperationException("Failed to get OS version.");
Comment that line out.
Yes, I found this few second before your message. I'm not familiar with the C# synthax. I think the throw attached after the foreach was triggered if an exception in foreach occurs.
So with this code the application work fine :
Version outputReturn = null;
Thread thread = new Thread(() =>
{
var query = new SelectQuery("Win32_OperatingSystem", "OSType = 18"); // WINNT
using (var searcher = new ManagementObjectSearcher(query))
using (var results = searcher.Get())
{
foreach (ManagementObject result in results)
{
using (result)
{
var input = (string)result.GetPropertyValue("Version");
if (Version.TryParse(input, out Version output))
{
outputReturn = output;
break;
}
}
}
}
if (outputReturn == null) throw new InvalidOperationException("Failed to get OS version.");
});
thread.Start();
thread.Join();
return outputReturn;
Okay, so it now returns 10.0.22000
, right?
Then, Monitorian still throws InvalidCastException?
Yes 10.0.22000
.
The InvalidCastException is resolved with the Thread.
I see. So could you give me the whole exception message when the exception is thrown at using (var results = searcher.Get())
? This line of code does not cast anything.
Here the detail of the exception ;
Managed Debugging Assistant 'DisconnectedContext'
Message=Managed Debugging Assistant 'DisconnectedContext' :
'Échec de la transition vers le contexte COM 0x10e8250 pour ce RuntimeCallableWrapper avec l'erreur suivante : Un appel sortant ne peut pas être effectué étant donné que l’application répartit un appel entrant synchrone. (Exception de HRESULT : 0x8001010D (RPC_E_CANTCALLOUT_ININPUTSYNCCALL)). Cela se produit habituellement car le contexte COM 0x10e8250 dans lequel ce RuntimeCallableWrapper a été créé a été déconnecté ou est occupé à autre chose et ne peut pas traiter la transition des contextes. Aucun proxy ne sera utilisé pour traiter la demande sur le composant COM. Cela peut entraîner des dysfonctionnements ou des pertes de données. Pour éviter ce problème, assurez-vous que tous les contextes/cloisonnements/threads COM restent actifs et sont disponibles pour la transition des contextes, tant que l'application n'en a pas terminé avec les RuntimeCallableWrappers qui représentent les composants COM qui s'y trouvent.'
To see the detail of the InvalidCastException I activated this :
I cannot reproduce the exception. Just to make sure, comment out the whole content of foreach loop and then InvalidCastException is still thown?
If I comment the content I don't have the InvalidCastException (but the normal InvalidOperationException).
using (var results = searcher.Get())
{
foreach (ManagementObject result in results)
{
/*using (result)
{
var input = (string)result.GetPropertyValue("Version");
if (Version.TryParse(input, out Version output))
return output;
}*/
}
throw new InvalidOperationException("Failed to get OS version.");
}
Then, if replace var input = (string)result.GetPropertyValue("Version");
with var input = result.GetPropertyValue("Version") as string;
, is there any difference?
No difference is the same. I check and If I just comment the if line if (Version.TryParse(input, out Version output)) return output;
it's ok (don't have the InvalidCastException).
I realized some test, so this code trigger the exception :
Version output = new Version("10.0.22000");
var query = new SelectQuery("Win32_OperatingSystem", "OSType = 18"); // WINNT
using (var searcher = new ManagementObjectSearcher(query))
using (var results = searcher.Get())
{
foreach (ManagementObject result in results)
{
using (result)
{
var input = (string)result.GetPropertyValue("Version");
Console.WriteLine(input);
return output;
/*if (Version.TryParse(input, out Version output))
return output;*/
}
}
throw new InvalidOperationException("Failed to get OS version.");
}
But this code work fine (the version returned is null
), the application start :
Version output = null;
var query = new SelectQuery("Win32_OperatingSystem", "OSType = 18"); // WINNT
using (var searcher = new ManagementObjectSearcher(query))
using (var results = searcher.Get())
{
foreach (ManagementObject result in results)
{
using (result)
{
var input = (string)result.GetPropertyValue("Version");
Console.WriteLine(input);
return output;
/*if (Version.TryParse(input, out Version output))
return output;*/
}
}
throw new InvalidOperationException("Failed to get OS version.");
}
How about to change if (Version.TryParse(input, out Version output))
to if (Version.TryParse(input as string, out Version output))
?
The cast is redundant because the input string is casted before. Same if I remove the cast to the top line.
So you noticed Version.TryParse method throws InvalidCastException?
Finally no, I got the idea to create a function and return the value in string and realize the cast out of the method but the code trigger the exception.
A void method like this trigger the exception :
private static void GetOsStringVersion ()
{
var query = new SelectQuery("Win32_OperatingSystem", "OSType = 18"); // WINNT
using (var searcher = new ManagementObjectSearcher(query))
using (var results = searcher.Get())
{
foreach (ManagementObject result in results)
{
using (result)
{
var input = (string)result.GetPropertyValue("Version");
}
}
}
}
If I comment the content I don't have the InvalidCastException (but the normal InvalidOperationException).
using (var results = searcher.Get()) { foreach (ManagementObject result in results) { /*using (result) { var input = (string)result.GetPropertyValue("Version"); if (Version.TryParse(input, out Version output)) return output; }*/ } throw new InvalidOperationException("Failed to get OS version."); }
I don't have the InvalidCastException here because I have the InvalidOperationException before.
Simple code like this trigger the error on the using var results = searcher.Get();
line :
private static string GetOsStringVersion ()
{
var query = new SelectQuery("Win32_OperatingSystem", "OSType = 18"); // WINNT
using var searcher = new ManagementObjectSearcher(query);
using var results = searcher.Get();
return null;
}
Make the previous code in a Thread resolve the problem.
So this does not throw InvalidCastException.
var query = new SelectQuery("Win32_OperatingSystem", "OSType = 18"); // WINNT
using (var searcher = new ManagementObjectSearcher(query))
using (var results = searcher.Get())
{
foreach (ManagementObject result in results)
{
using (result)
{
var input = (string)result.GetPropertyValue("Version");
Console.WriteLine(input);
return null;
}
}
}
But this does. It is correct understanding?
var query = new SelectQuery("Win32_OperatingSystem", "OSType = 18"); // WINNT
using (var searcher = new ManagementObjectSearcher(query))
using (var results = searcher.Get())
{
foreach (ManagementObject result in results)
{
using (result)
{
var input = (string)result.GetPropertyValue("Version");
}
}
}
Put aside Thread thing for the moment. Probably it is not the root cause.
Sorry, I was mistaken, both throw the exception. I edited my previous message to specify.
To the Thread
solution I found this here : https://stackoverflow.com/questions/44823368/call-to-managementobjectsearchert-get-crashes-with-invalidcastexception
which contain this link : https://stackoverflow.com/questions/23454396/rpc-e-cantcallout-ininputsynccall-when-trying-to-access-usb-device
I see. Before jumping to that solution without knowing the root cause, we have to think about why it happens in your environment but it does not in my environment.
Yes I don't know why it's happen on my environment. Another proposal, modify the way to get the version :
OperatingSystem os = Environment.OSVersion;
//Get version information about the os.
Version vs = os.Version;
return vs;
But I don't know if it's work for all devices currently compatible with the version.
The reason why I do not prefer Environment.OSVersion in a library is that the OS returns false information to this inquiry depending on the application manifest. It is by design.
I am still wondering why it happens on your environment. If calling in another thread helps to avoid it, it may have something to do with thead apartment. Could you upload your test project in somewhere in GitHub?
This WMI classs internally calls COM and COM has thread apartment thing that is hard to delve into. So, to save time, I am inclined to change to other method.
You still wish I upload my test project ?
I feel embarased you take time for my problem of which I am the only one to have. Thanks !
Yes, I do. There might be something interesting to me.
Hello,
I update Windows 10 to 11. I installed Windows 11 from scratch. The application worked fine in Windows 10 with my screens. But now I have an error :
I have the last version of NET Framework.
You have an idea ?