What can cause Windows InstallDate to change? - windows

I was wondering if there is anything that can cause the Windows Install Date to change - specifically InstallDate from the Win32_OperatingSystem class.
We are using the ManagementObjectSearcher in C# to get various system information for licencing purposes, and on some computers, the windows install date has changed for no apparent reason.
I have been trying to find out exactly where it gets the information for the install date from in order to work out if installing a new service pack or version of .net might cause this, but to no avail.
Unfortunately we can't even see what it has changed from and to because the information is hashed (well, we might get to see what it has changed to, but we would have to bother the customer again).
I guess the other thing that might have happened is that the conversion of the date-time from one format to another might have changed for some reason, but I can't get my head around it to work out if it might. This is what we are doing:
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem");
foreach (ManagementObject wmi_Windows in searcher.Get())
{
try
{
s = wmi_Windows["InstallDate"].ToString();
DateTime dc = ToDateTime(s);
WindowsInfo.InstallDate = dc.AddTicks(-TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).Ticks).ToLocalTime().ToString();
break;
}
catch (Exception ex)
{
//stuff here
}
}

The value returned by the property InstallDate of the Win32_OperatingSystem WMI class is retrieved from the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\InstallDate Key, this windows registry value is stored as the number of seconds since January 1, 1970. if you modify that windows registry value and then run the WMI Query again you will get the value modified.

Related

Unable to change registry on Windows 10

I'm trying to change the value of the Shell registry key on Windows 10 using the following code:
Public Function overwriteStartup()
Try
Dim winlogon As RegistryKey = My.Computer.Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", True)
winlogon.SetValue("AutoRestartShell", 0, RegistryValueKind.DWord)
winlogon.SetValue("Shell", Application.ExecutablePath, RegistryValueKind.String)
winlogon.Flush()
winlogon.Close()
Return True
Catch ex As Exception
Return False
End Try
End Function
The issue is that Shell and AutoRestartShell are not changing.
If I add MessageBox.Show(My.Computer.Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon").GetValue("Shell")) between winlogon.Close() and Return True, I get a message box that shows the correct value (which means that the value was changed), but when I check regedit, it shows the original value, so it did not actually change the value.
If your app can read the registry value - You must need to provide administrative privileges before letting your app write registry values. Go to the app manifest and set the privilege to requireAdministrator then try again, it should work.
If you remove the exception handling Try Catch, then you'll get to know the exact reason.
I changed the target framework to .NET 4 and set target CPU to AnyCPU, it works now.

Is there any way to change the SMBIOSVersion value in win32_bios in windows?

As illustrated in the picture bellow, by tweaking the registry in windows 10 I was able to change the bios version but not the SMBIOSVersion, which is what i want. Is there any way to alter it? Not necessarily permanently. I don't care if the value is restored after a reboot, i just want the win32_bios containing an SMBIOSVersion that i have specified until shutdown so calls to it will return my specified version.
It's coming from WMI, and the Win32_BIOS provider is defined in c:\Windows\System32\wbem\cimwin32.mof as a dynamic provider calling from cimwin32.dll.
But it does seem to be possible to override it; create a new file somewhere, e.g. c:\user\spkone\test.mof and put this in it:
#pragma namespace ("\\\\.\\root\\CIMv2")
class Win32_BIOS
{
[key]
string SMBIOSBIOSVersion;
};
[DYNPROPS]
instance of Win32_BIOS
{
SMBIOSBIOSVersion = "wow";
};
Run an administrator command prompt or PowerShell, and run mofcomp test.mof.
Before:
After:
I got this far and then stopped, I don't know how far the change reaches, or what the implications are. It does show in another PowerShell process, anyway. I'll leave it to you to fill in the other details ;)
Quoting from the documentation (emphasis mine):
SMBIOSBIOSVersion
Data type: string
Access type: Read-only
Qualifiers: MappingStrings ("SMBIOS|Type 0|BIOS Version")
BIOS version as reported by SMBIOS.
This value comes from the BIOS Version member of the BIOS Information structure in the SMBIOS information.
Basically, this value reports information obtained from the BIOS. To modify the value you'd need to modify the BIOS, i.e. flash the chip with a new firmware.

Reading Device Manager's Property Fields in Windows 7/8

I am developing a windows application which gives the field details --> X.
Where X is -->
Right Click My Computer >
Properties >
Device Manager > (select any Item - Say KeyBoard) >
Click it > standard PS/2 KeyBoard >
double Click standard PS/2 KeyBoard >
click the Details Tab >
Under the Property there are various fields like Display Name , Problem Code,Parent Siblings, etc , etc?
I want to get their values .
Which Windows API I can use for this.
I am doing this for windows 7 as well as windows 8.I hope the API will remain the same.Also i am having 64 bit machine.
This has to be true for any device whose details I wanted to know from the Device Manager.
ALso I just want to all operations - Reading and No Set (writing) so I think I will not be having any problem with violating the Admin Rights.PLease suggest.! I have added Snapshots for reference!Say for example I want to know the current State of the HID USB Complaint Mouse(D0(Active) or D2(Sleep)).
I need to Get this Power State D0.
The question is tagged with C#, though the actual question asks for any Window API. With the Win32 API the information can be retrieved with SetupDiGetDeviceRegistryProperty(). The steps would be:
Get a device info set for the devices you're interested in via SetupDiGetClassDevs().
Iterate through the device infos via SetupDiEnumDeviceInfo().
Get the properties via calls to SetupDiGetDeviceRegistryProperty().
Destroy the device info set via SetupDiDestroyDeviceInfoList().
According to the documentation the API is available on Windows 2000 and later.
It's quite easy to get the hardware information using ManagementObjectCollection.
For instance to get all properties and values from the PC processor
var win32DeviceClassName = "win32_processor";
var query = string.Format("select * from {0}", win32DeviceClassName);
using (var searcher = new ManagementObjectSearcher(query))
{
ManagementObjectCollection objectCollection = searcher.Get();
foreach (ManagementBaseObject managementBaseObject in objectCollection)
{
foreach (PropertyData propertyData in managementBaseObject.Properties)
{
Console.WriteLine("Property: {0}, Value: {1}", propertyData.Name, propertyData.Value);
}
}
}
The full list of WIN32 class name is available at http://msdn.microsoft.com/en-us/library/aa394084%28v=VS.85%29.aspx
Cheers.
You're going to have the easiest time (I think) doing this with PowerShell. If you are writing some C# code you can execute a PS script using types in the System.Management.Automation namespace, such as PowerShell (link: http://msdn.microsoft.com/en-us/library/system.management.automation.powershell(v=vs.85).aspx) but I would begin your testing using the PS Console.
You should first (using PowerShell) explore the WMI objects in your environments using this command
Get-WmiObject -List -namespace root\CIMV2
Then once you identify with class you are looking for you can retrieve details on that class using this command:
Get-WmiObject -namespace root\CIMV2 -class Win32_USBControllerDevice
Once you have that content you'd have to parse the text.
UPDATE: Try using this command to get the "State", "Status", and "Started" attributes of mouse drivers on your PC:
gwmi Win32_SystemDriver | where {$_.DisplayName -like "*Mouse*"}

How to fetch registry path from EventArrivedEventArgs object

I try to watch the registry events via WMI. I use the below query to watch any events inside HKLM\softwares
WqlEventQuery query = new WqlEventQuery(
"SELECT * FROM RegistryTreeChangeEvent WHERE " +
"(Hive = 'HKEY_LOCAL_MACHINE')" +
"AND Rootpath = 'Software'"
As expected it catches all events in EventArrivedEventArgs.
example: 1) if there is a newkey inside Hklm\software\microsoft, it captures
2) if there is a value change inside Hklm\software\microsoft\windows, it captures
However I need to know the registry path or key or value in which change has occured.
I dont know how to interpret the EventArrivedEventArgs object to get it.
Can anyone help me.
I don't believe this is possible. EventArrivedEventArgs will return an instance of RegistryTreeChangeEvent and the only thing you know about the event is the root path you are monitoring. You can work around this using the RegistryKeyChangeEvent class, specifying more than one key in the query Where clause. For example (not tested):
SELECT * FROM RegistryKeyChangeEvent
WHERE Hive='HKEY_LOCAL_MACHINE' AND
(KeyPath='SOFTWARE\Microsoft' OR
KeyPath='SOFTWARE\Microsoft\Windows')
In this case you would use EventArrivedEventArgs.NewEvent property to get the RegistryKeyChangeEvent instance and its Keypath property to get the registry key that was changed.
After the analysis, Its clear that Key path for subkeys couldnot be obtained through registry events. Because Regkeychangeevent could not monitor subkeys and reg treechange event monitors subkeys which would not give the key path, the change has occured. Hence preimage post image's diff should be the only solution so far.

DSOFramer closing Excel doc in another window. If unsaved data in file, dsoframer fails to open with "Attempt to access invalid address"

I'm using Microsoft's DSOFramer control to allow me to embed an Excel file in my dialog so the user can choose his sheet, then select his range of cells; it's used with an import button on my dialog.
The problem is that when I call the DSOFramer's OPEN function, if I have Excel open in another window, it closes the Excel document (but leaves Excel running). If the document it tries to close has unsaved data, I get a dialog boxclosing Excel doc in another window. If unsaved data in file, dsoframer fails to open with a messagebox: Attempt to access invalid address.
I built the source, and stepped through, and its making a call in its CDsoDocObject::CreateFromFile function, calling BindToObject on an object of class IMoniker. The HR is 0x8001010a The message filter indicated that the application is busy. On that failure, it tries to InstantiateDocObjectServer by classid of CLSID Microsoft Excel Worksheet... this fails with an HRESULT of 0x80040154 Class not registered. The InstantiateDocObjectServer just calls CoCreateInstance on the classid, first with CLSCTX_LOCAL_SERVER, then (if that fails) with CLSCTX_INPROC_SERVER.
I know DSOFramer is a popular sample project for embedding Office apps in various dialog and forms. I'm hoping someone else has had this problem and might have some insight on how I can solve this. I really don't want it to close any other open Excel documents, and I really don't want it to error-out if it can't close the document due to unsaved data.
Update 1: I've tried changing the classid that's passed in to Excel.Application (I know that class will resolve), but that didn't work. In CDsoDocObject, it tries to open key HKEY_CLASSES_ROOT\CLSID\{00024500-0000-0000-C000-000000000046}\DocObject, but fails. I've visually confirmed that the key is not present in my registry; The key is present for the guide, but there's no DocObject subkey. It then produces an error message box: The associated COM server does not support ActiveX document embedding. I get similar (different key, of course) results when I try to use the Excel.Workbook programid.
Update 2: I tried starting a 2nd instance of Excel, hoping that my automation would bind to it (being the most recently invoked) instead of the problem Excel instance, but it didn't seem to do that. Results were the same. My problem seems to have boiled down to this: I'm calling the BindToObject on an object of class IMoniker, and receiving 0x8001010A (RPC_E_SERVERCALL_RETRYLATER) The message filter indicated that the application is busy. I've tried playing with the flags passed to the BindToObject (via the SetBindOptions), but nothing seems to make any difference.
Update 3: It first tries to bind using an IMoniker class. If that fails, it calls CoCreateInstance for the clsid as a fallback method. This may work for other MS Office objects, but when it's Excel, the class is for the Worksheet. I modified the sample to CoCreateInstance _Application, then got the workbooks, then called the Workbooks::Open for the target file, which returns a Worksheet object. I then returned that pointer and merged back with the original sample code path. All working now.
#Jinjin
You can use the #import directive to import your Excel's OLB file. this should generate (and automatically include an Excel .tlh file which contains the structures for _Application (and the rest you need)). Ideally, you should find an OLB file that matches the earliest Excel version that you wish to support. The one on your local system is probably in c:\Program Files\Microsoft Office\Office12 (presuming you have Office 2007 installed). It may be named Excel.olb, or XL5EN32.OLB (different, obviously if you haven't installed the US English verion of Excel.
So, copy the .olb file to your project source directory, then at the top of the source file, add a line for #import "XL5EN32.olb".
Yes, opens older versions. Best way to guarantee that this will be the case is to find an OLB file (mentioned in item 1 above) that is from an installation of Excel that is the earliest version you wish to support. I use an Excel9.olb from Office 2000. Works fine with my testing of Excel versions all the way to the latest from Office 2007.
Yes, you should use dsoframer normally after making these changes.
I'm afraid I probably can't do that due to restrictions of my employer. However, if you take the "stock" dsoframer project, make the changes described in part 1 of this post, and the changes I described in my earlier post, you have pretty much recreated exactly what I have.
#Jinjin: did you put the import statement (#import "XL5EN32.olb") in the cpp file where you are using the Excel::_Application? If not, do that... can't just add it to the project. If you have already done that, try also adding this statement to the cpp file where you are using those mappings #import "Debug\XL5EN32.tlh". The tlh file is a header that is generated by running the #import; you should find it in your Debug directory (presuming you're performing a Debug build).
Renaming _Application to Application (and the others) is not the right way to go. The _Application structure is the one that has the mappings. That is why you are not finding the app->get_Workbooks.
What file are you looking in that you are finding Application but not _Application?
Assuming you are using the DSOFRAMER project, you need to add this code to dsofdocobj.cpp in the CreateFromFile function, at around line 348:
CLSID clsidExcelWS;
hr = CLSIDFromProgID(OLESTR("Excel.Sheet"),clsidExcelWS);
if (FAILED(hr)) return hr;
if (clsid == clsidExcelWS)
{
hr = InstantiateAndLoadExcel(pwszFile, &pole);
if (FAILED(hr)) return hr;
}
else
{
<the IMoniker::BindToObject call and it's failure handling from the "stock" sample goes here>
}
Then, define the following new member function in CDsoDocObject:
////////////////////////////////////////////////////////////////////////
// CDsoDocObject::InstantiateAndLoadExcel (protected)
//
// Create an instance of Excel and load the target file into its worksheet
//
STDMETHODIMP CDsoDocObject::InstantiateAndLoadExcel(LPWSTR pwszFile, IOleObject **ppole)
{
IUnknown *punkApp=NULL;
Excel::_Application *app=NULL;
Excel::Workbooks *wbList=NULL;
Excel::_Workbook *wb;
CLSID clsidExcel;
HRESULT hr = CLSIDFromProgID(OLESTR("Excel.Application"), &clsidExcel);
if (FAILED(hr))
return hr;
hr = CoCreateInstance(clsidExcel, NULL, CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&punkApp);
if (SUCCEEDED(hr))
{
hr = punkApp->QueryInterface(__uuidof(Excel::_Application),(LPVOID *)&app);
if (SUCCEEDED(hr))
{
hr = app->get_Workbooks(&wbList);
VARIANT vNoParam;
VariantInit(&vNoParam);
V_VT(&vNoParam) = VT_ERROR;
V_ERROR(&vNoParam) = DISP_E_PARAMNOTFOUND;
VARIANT vReadOnly;
VariantInit(&vReadOnly);
V_VT(&vReadOnly) = VT_BOOL;
V_BOOL(&vReadOnly) = VARIANT_TRUE;
BSTR bstrFilename = SysAllocString(pwszFile);
hr = wbList->Open(bstrFilename, vNoParam,vNoParam,vNoParam,vNoParam,vReadOnly,vNoParam,vNoParam,vNoParam,vNoParam,vNoParam,vNoParam,vNoParam,0,&wb);
if (SUCCEEDED(hr))
hr = wb->QueryInterface(IID_IOleObject, (void**)ppole);
VariantClear(&vReadOnly);
VariantClear(&vNoParam);
SysFreeString(bstrFilename);
}
}
if (wb != NULL) wb->Release();
if (wbList != NULL) wbList->Release();
if (app != NULL) app->Release();
if (punkApp != NULL) punkApp->Release();
return hr;
}

Resources