updating system time in c#
-
Am trying to update the system time using c#. Have a bit of code written in VB.NET that I’ve plundered ( from Alastair Dallas) , which works. The VB code is: _ Public Structure SYSTEMTIME Public wYear As Int16 Public wMonth As Int16 Public wDayOfWeek As Int16 Public wDay As Int16 Public wHour As Int16 Public wMinute As Int16 Public wSecond As Int16 Public wMilliseconds As Int16 End Structure Private Declare Function GetSystemTime Lib "kernel32.dll" (ByRef stru As SYSTEMTIME) As Int32 Private Declare Function SetSystemTime Lib "kernel32.dll" (ByRef stru As SYSTEMTIME) As Int32 Public Shared Sub SetWindowsClock(ByVal dt As DateTime) 'Sets system time. Note: Use UTC time; Windows will apply time zone Dim timeStru As SYSTEMTIME Dim result As Int32 timeStru.wYear = CType(dt.Year, Int16) timeStru.wMonth = CType(dt.Month, Int16) timeStru.wDay = CType(dt.Day, Int16) timeStru.wDayOfWeek = CType(dt.DayOfWeek, Int16) timeStru.wHour = CType(dt.Hour + 2, Int16) ' used to verify system time is actually changed timeStru.wMinute = CType(dt.Minute, Int16) timeStru.wSecond = CType(dt.Second, Int16) timeStru.wMilliseconds = CType(dt.Millisecond, Int16) result = SetSystemTime(timeStru) End Sub ************************************************** Have converted this to C# as follows: [StructLayout(LayoutKind.Sequential)] public struct SYSTEMTIME { public Int16 wYear; public Int16 wMonth; public Int16 wDayOfWeek; public Int16 wDay; public Int16 wHour; public Int16 wMinute; public Int16 wSecond; public Int16 wMilliseconds; } [DllImport("kernel32.dll")] public static extern int SetSystemTime(SYSTEMTIME lpSystemTime); public static void SetWindowsClock(DateTime dt) { SYSTEMTIME timeStru; int result; timeStru.wYear = ((Int16)dt.Year); timeStru.wMonth = ((Int16)dt.Month); timeStru.wDay = ((Int16)dt.Day); timeStru.wDayOfWeek = ((Int16)dt.DayOfWeek); timeStru.wHour = ((Int16)dt.Hour); timeStru.wMinute = ((Int16)dt.Minute); timeStru.wSecond = ((Int16)dt.Second); timeStru.wMilliseconds = ((Int16)dt.Millisecond); result = SetSystemTime(timeStru); } The C# code crashes on the SetSystemTime(timeStru). While tracing, the only thing I noticed which
-
Am trying to update the system time using c#. Have a bit of code written in VB.NET that I’ve plundered ( from Alastair Dallas) , which works. The VB code is: _ Public Structure SYSTEMTIME Public wYear As Int16 Public wMonth As Int16 Public wDayOfWeek As Int16 Public wDay As Int16 Public wHour As Int16 Public wMinute As Int16 Public wSecond As Int16 Public wMilliseconds As Int16 End Structure Private Declare Function GetSystemTime Lib "kernel32.dll" (ByRef stru As SYSTEMTIME) As Int32 Private Declare Function SetSystemTime Lib "kernel32.dll" (ByRef stru As SYSTEMTIME) As Int32 Public Shared Sub SetWindowsClock(ByVal dt As DateTime) 'Sets system time. Note: Use UTC time; Windows will apply time zone Dim timeStru As SYSTEMTIME Dim result As Int32 timeStru.wYear = CType(dt.Year, Int16) timeStru.wMonth = CType(dt.Month, Int16) timeStru.wDay = CType(dt.Day, Int16) timeStru.wDayOfWeek = CType(dt.DayOfWeek, Int16) timeStru.wHour = CType(dt.Hour + 2, Int16) ' used to verify system time is actually changed timeStru.wMinute = CType(dt.Minute, Int16) timeStru.wSecond = CType(dt.Second, Int16) timeStru.wMilliseconds = CType(dt.Millisecond, Int16) result = SetSystemTime(timeStru) End Sub ************************************************** Have converted this to C# as follows: [StructLayout(LayoutKind.Sequential)] public struct SYSTEMTIME { public Int16 wYear; public Int16 wMonth; public Int16 wDayOfWeek; public Int16 wDay; public Int16 wHour; public Int16 wMinute; public Int16 wSecond; public Int16 wMilliseconds; } [DllImport("kernel32.dll")] public static extern int SetSystemTime(SYSTEMTIME lpSystemTime); public static void SetWindowsClock(DateTime dt) { SYSTEMTIME timeStru; int result; timeStru.wYear = ((Int16)dt.Year); timeStru.wMonth = ((Int16)dt.Month); timeStru.wDay = ((Int16)dt.Day); timeStru.wDayOfWeek = ((Int16)dt.DayOfWeek); timeStru.wHour = ((Int16)dt.Hour); timeStru.wMinute = ((Int16)dt.Minute); timeStru.wSecond = ((Int16)dt.Second); timeStru.wMilliseconds = ((Int16)dt.Millisecond); result = SetSystemTime(timeStru); } The C# code crashes on the SetSystemTime(timeStru). While tracing, the only thing I noticed which
I don't know anything about VB but you don't have the equivalent to the CType function call in the c# code. Is that necessary?
-
I don't know anything about VB but you don't have the equivalent to the CType function call in the c# code. Is that necessary?
Pulled this description of CType from a .NET forum: Q: What are the differences between Ctype and (cint,cstr,cool,etc...) S: VB.NET A: The Ctype keyword is used to perform an explicit conversion also known as casting, the Ctype keyword when used will also check for a valid destination data type or an error will occur, such as converting a long to integer. The other keywords Cint, Cbool,etc do not check for valid data types and they are about 3 times faster than Ctype because the code is included in the MSIL. i think it is not relevant to the problem. SetSystemTime has one parameter sent to it and it is a datatype which is the structure which the program defined as SYSTEMTIME. When i trace the code stopping at the "result = SetSystemTime(timeStru);" statement in both VB and C#, i can see the data that is parsed to it. The actual time and date fields are the same. The top level of the structures are a little different though. it is easy to test my code as i pasted most of it. Only needs a few using statements and a small wrapper to get it going. i'll supply the whole lot if asked for. benny
-
Am trying to update the system time using c#. Have a bit of code written in VB.NET that I’ve plundered ( from Alastair Dallas) , which works. The VB code is: _ Public Structure SYSTEMTIME Public wYear As Int16 Public wMonth As Int16 Public wDayOfWeek As Int16 Public wDay As Int16 Public wHour As Int16 Public wMinute As Int16 Public wSecond As Int16 Public wMilliseconds As Int16 End Structure Private Declare Function GetSystemTime Lib "kernel32.dll" (ByRef stru As SYSTEMTIME) As Int32 Private Declare Function SetSystemTime Lib "kernel32.dll" (ByRef stru As SYSTEMTIME) As Int32 Public Shared Sub SetWindowsClock(ByVal dt As DateTime) 'Sets system time. Note: Use UTC time; Windows will apply time zone Dim timeStru As SYSTEMTIME Dim result As Int32 timeStru.wYear = CType(dt.Year, Int16) timeStru.wMonth = CType(dt.Month, Int16) timeStru.wDay = CType(dt.Day, Int16) timeStru.wDayOfWeek = CType(dt.DayOfWeek, Int16) timeStru.wHour = CType(dt.Hour + 2, Int16) ' used to verify system time is actually changed timeStru.wMinute = CType(dt.Minute, Int16) timeStru.wSecond = CType(dt.Second, Int16) timeStru.wMilliseconds = CType(dt.Millisecond, Int16) result = SetSystemTime(timeStru) End Sub ************************************************** Have converted this to C# as follows: [StructLayout(LayoutKind.Sequential)] public struct SYSTEMTIME { public Int16 wYear; public Int16 wMonth; public Int16 wDayOfWeek; public Int16 wDay; public Int16 wHour; public Int16 wMinute; public Int16 wSecond; public Int16 wMilliseconds; } [DllImport("kernel32.dll")] public static extern int SetSystemTime(SYSTEMTIME lpSystemTime); public static void SetWindowsClock(DateTime dt) { SYSTEMTIME timeStru; int result; timeStru.wYear = ((Int16)dt.Year); timeStru.wMonth = ((Int16)dt.Month); timeStru.wDay = ((Int16)dt.Day); timeStru.wDayOfWeek = ((Int16)dt.DayOfWeek); timeStru.wHour = ((Int16)dt.Hour); timeStru.wMinute = ((Int16)dt.Minute); timeStru.wSecond = ((Int16)dt.Second); timeStru.wMilliseconds = ((Int16)dt.Millisecond); result = SetSystemTime(timeStru); } The C# code crashes on the SetSystemTime(timeStru). While tracing, the only thing I noticed which
You have to
ref
theSYSTEMTIME
structure. VB is passing a reference to it, but you're passing its value. TheSetSystemTime
API requires aSYSTEMTIME*
(pointer to aSYSTEMTIME
struct), so your P/Invoke declaration should look like:[DllImport("kernel32.dll")]
private static extern bool SetSystemTime(ref SYSTEMTIME systime);Also, you do not typically make P/Invoke methods public because it creates holes in your application that could be used to corrupt the system or your application. Besides, do you want to create that struct every time you want to call it? A better method would be to expose a public method that takes a
DateTime
, does the conversion and calls the private P/Invoke method above. You've already done this, but you should make your P/Invoke method private, not public. It's all about encapsulation.Microsoft MVP, Visual C# My Articles
-
You have to
ref
theSYSTEMTIME
structure. VB is passing a reference to it, but you're passing its value. TheSetSystemTime
API requires aSYSTEMTIME*
(pointer to aSYSTEMTIME
struct), so your P/Invoke declaration should look like:[DllImport("kernel32.dll")]
private static extern bool SetSystemTime(ref SYSTEMTIME systime);Also, you do not typically make P/Invoke methods public because it creates holes in your application that could be used to corrupt the system or your application. Besides, do you want to create that struct every time you want to call it? A better method would be to expose a public method that takes a
DateTime
, does the conversion and calls the private P/Invoke method above. You've already done this, but you should make your P/Invoke method private, not public. It's all about encapsulation.Microsoft MVP, Visual C# My Articles
Thanks Heath, Had totally missed the ref bit. Changed the declaration to what you suggested and then there were compile errors on the SetSystemTime call. Changed it to ” result = SetSystemTime(ref timeStru);” and also changed the result from int to bool. It works now. The reason for P/Invoke being public was that I cut and pasted it from a forum. My technique in building applications is to write and test little functions separately before moulding them into the final source. So these little stubs are often a bit sloppy. Thanks again benny