『取巧』VS2015試用期過后 繼續試用


背景:

個人電腦 安裝的 VS2015 Community 社區版。

一直用得挺好,都忘了要登錄。

 

直到近來,30天試用期過 —— VS彈窗:要登錄用戶名、密碼 才能繼續使用。

但是,輸入了無數次 郵箱,到下一步時,都彈出一個 白屏窗口 —— 死活沒法登錄成功。

 

登錄不成功,日子還得過。

尊重著作權、版權 —— 破解VS這種事,還是不做的好(雖然能力可及)。

 

另辟蹊徑:

試着通過 Win32 發送消息:關閉 彈出窗體。

但是 彈出窗體接收到 關閉消息后,整個VS 依然全部關掉了。

再嘗試了一下:

如果先 修改系統時間,讓修改后的系統時間 就是 試用期范圍 —— 再關閉彈窗,VS 主窗體 沒關閉。

 

思路明確:

> 監控系統所有窗體。

> 如果有窗體標題是 “Microsoft Visual Studio 帳戶設置” 則開始 如下操作

> 修改系統時間 到 試用期范圍。

> 發送 WM_CLOSE 消息,關閉 彈出窗體。

> 將系統時間 修改回來。

 

相關源碼 150行:

  1     class Program
  2     {
  3         /// <summary>
  4         /// Visual Studio 2015 可以正常啟用的 試用期 時間
  5         /// </summary>
  6         public static DateTime VisualStudioDate
  7         {
  8             get { return Convert.ToDateTime(ConfigurationManager.AppSettings["VisualStudioDate"] ?? "2018-05-01"); }
  9         }
 10 
 11 
 12 
 13         static void Main(string[] args)
 14         {
 15             while(true)
 16             {
 17                 List<Win32API.WindowInfo> list = Win32API.EnumWindows();
 18                 List<Win32API.WindowInfo> list2 = list.FindAll(x => x.szWindowName == "Microsoft Visual Studio 帳戶設置");
 19 
 20                 if (list2.Count >= 1)
 21                 {
 22                     //將系統時間設置為 可試用期
 23                     DateTime nowTime = DateTime.Now;
 24                     DateTime vsTime = VisualStudioDate;
 25                     double timeSpanMS = (nowTime - vsTime).TotalMilliseconds;
 26                     Win32API.SetSystemTime(vsTime);
 27 
 28                     foreach (Win32API.WindowInfo item in list2)
 29                     {
 30                         try
 31                         {
 32                             Console.WriteLine(string.Format("即將關閉 \"{0}\" 0x{1}", item.szWindowName, item.hWnd.ToString("X8")));
 33                             Win32API.SendMessage(item.hWnd, Win32API.WM_CLOSE, 0, 0);
 34                         }
 35                         catch { }
 36                     }
 37 
 38                     Thread.Sleep(2000);
 39 
 40                     //將系統時間還原為 實際日期
 41                     DateTime nowTime2 = DateTime.Now;
 42                     double timeSpanMS2 = (nowTime2 - vsTime).TotalMilliseconds;
 43                     DateTime realTime = vsTime.AddMilliseconds(timeSpanMS + timeSpanMS2);
 44                     Win32API.SetSystemTime(realTime);
 45                 }
 46 
 47                 //死循環, 休眠5秒
 48                 Thread.Sleep(5000);
 49             }
 50         }
 51 
 52 
 53 
 54 
 55     }
 56 
 57     public class Win32API
 58     {
 59         public const int WM_CLOSE = 0x0010;
 60         private delegate bool WNDENUMPROC(IntPtr hWnd, int lParam);
 61 
 62         [DllImport("User32.dll", EntryPoint = "SendMessage")]
 63         public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
 64 
 65 
 66         #region  獲取所有窗體句柄
 67 
 68         //Copyright © http://www.cnblogs.com/oraclejava/articles/1549025.html
 69 
 70         [DllImport("user32.dll")]
 71         private static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, int lParam);
 72         [DllImport("user32.dll")]
 73         private static extern int GetWindowTextW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount);
 74         [DllImport("user32.dll")]
 75         private static extern int GetClassNameW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount);
 76         public struct WindowInfo
 77         {
 78             public IntPtr hWnd;
 79             public string szWindowName;
 80             public string szClassName;
 81 
 82             public override string ToString()
 83             {
 84                 return "0x" + hWnd.ToString("X8") + " '" + szWindowName + "' '" + szClassName + "'";
 85             }
 86         }
 87 
 88         public static List<WindowInfo> EnumWindows()
 89         {
 90             List<WindowInfo> wndList = new List<WindowInfo>();
 91 
 92             EnumWindows(delegate(IntPtr hWnd, int lParam)
 93             {
 94                 WindowInfo wnd = new WindowInfo();
 95                 StringBuilder sb = new StringBuilder(256);
 96                 wnd.hWnd = hWnd;
 97                 GetWindowTextW(hWnd, sb, sb.Capacity);
 98                 wnd.szWindowName = sb.ToString();
 99                 GetClassNameW(hWnd, sb, sb.Capacity);
100                 wnd.szClassName = sb.ToString();
101                 wndList.Add(wnd);
102                 return true;
103             }, 0);
104 
105             return wndList;
106         }
107 
108         #endregion
109 
110 
111         #region  操作系統 時間修改
112 
113         public static bool SetSystemTime(DateTime newDateTime)
114         {
115             SystemTime sysTime = new SystemTime();
116             sysTime.wYear = Convert.ToUInt16(newDateTime.Year);
117             sysTime.wMonth = Convert.ToUInt16(newDateTime.Month);
118             sysTime.wDay = Convert.ToUInt16(newDateTime.Day);
119             sysTime.wHour = Convert.ToUInt16(newDateTime.Hour);
120             sysTime.wMinute = Convert.ToUInt16(newDateTime.Minute);
121             sysTime.wSecond = Convert.ToUInt16(newDateTime.Second);
122             sysTime.wMiliseconds = (ushort)newDateTime.Millisecond;
123             return SystemDateTime.SetLocalTime(ref sysTime);
124         }
125 
126         private class SystemDateTime
127         {
128             [DllImport("Kernel32.dll")]
129             public static extern bool SetLocalTime(ref SystemTime sysTime);
130 
131             [DllImport("Kernel32.dll")]
132             public static extern void GetLocalTime(ref SystemTime sysTime);
133         }
134 
135         [StructLayout(LayoutKind.Sequential)]
136         private struct SystemTime
137         {
138             public ushort wYear;
139             public ushort wMonth;
140             public ushort wDayOfWeek;
141             public ushort wDay;
142             public ushort wHour;
143             public ushort wMinute;
144             public ushort wSecond;
145             public ushort wMiliseconds;
146         }
147 
148         #endregion
149 
150     }

 

項目編譯:

新建一個 WinForm 程序。

將上面的代碼 復制替換。

編譯之后,將 exe 創建一個 快捷方式,放到 “啟動” 菜單中,開機就啟動,讓exe在后台運行即可。

 

操作爭議:

作者非常尊重 軟件著作權、版權 —— 無意傷害微軟利益。

用這種方式 延長試用,似乎有兩個爭議:修改系統時間、發送 WM_CLOSE 消息。

 

> 修改系統時間 是一種 普通操作,任何人都可以進行。【不具備爭議性】

> 發送 WM_CLOSE 消息,一個程序給另一個程序發送消息,改變另外的程序的行為【有點外掛的味道】。 —— 但仔細一想:電腦關機時,系統會給每一個程序 都發送 WM_CLOSE 消息。這樣一想,就突然不覺得侵權了。

 

 

尊重知識產權:

作者非常尊重 軟件著作權、版權 —— 如果本文的操作 損害了 微軟的利益,請及時聯系作者,刪除、修改 此文。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM