Program.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Windows.Forms;
5 using System.Threading;
6 using System.Reflection;
7 using System.IO;
8 using sage.ew.functions;
9 using sage.ew.db;
10 using sage.ew.netvfp;
11 using sage.ew.global;
13 using System.Diagnostics;
14 using System.Threading.Tasks;
15 
16 namespace sage._50
17 {
18  static class Program
19  {
20  public static int _nHandleVfp = 0;
21  public static string _cdirectoryPath = "";
22  public static string _cLicenciaSage50 = ""; // PE-100885
23  private static string _cPathLibrerias = "";
24 
25  // PE-95913. Propiedades para la carga automática de un formulario mediante acceso directo
26  public static string _cUserEurowin = "";
27  public static string _cPasswordEurowin = "";
28  public static string _cFormEurowin = "";
29  public static string _cParamsFormEurowin = ""; // PE-96522
30  public static string _cGrupoParametro = ""; //Task 195376: Forzar un grupo de arranque específico por parámetros de entrada
31 
32  // Para detectar cuando arrancamos un acceso directo / tarea automático
33  private static bool _lAutomatico = false;
34 
38  [STAThread]
39  public static void Main(string[] tcArgs)
40  {
41  bool lbRetorn = true;
42  bool llDebug = false, llSplash = true, llSplashInfo = false;
43  string lcError = "";
44  string lcNameProducto = "Sage 50"; // PE-103466
45 
46  // Comprobar ruta de las librerías. Task 143679
47  _cPathLibrerias = Application.StartupPath;
48  if (EntryControl(tcArgs))
49  {
50  // Obtener posibles parámetros. Task 143679
51  ObtenerParametros(tcArgs);
52 
53  if (lbRetorn && !Directory.Exists(_cPathLibrerias))
54  {
55  lcError += "- No existe la ruta de librerías: " + _cPathLibrerias + Environment.NewLine;
56  lbRetorn = false;
57  }
58 
59  // Comprobar ruta de inicio de la aplicación. Task 143679
60  _cdirectoryPath = Directory.GetParent(_cPathLibrerias).FullName;
61  if (string.IsNullOrWhiteSpace(_cdirectoryPath) || !Directory.Exists(_cdirectoryPath))
62  {
63  lcError += "- No existe la ruta de inicio: " + _cdirectoryPath + Environment.NewLine;
64  lbRetorn = false;
65  }
66 
67  // Comprobar ruta de las librerías
68  //_cPathLibrerias = Path.Combine(_cdirectoryPath, "Librerias\\");
69 
70  _cPathLibrerias = VersionNumber.DirectoryFullNameVersion(_cdirectoryPath);
71  if (lbRetorn && !Directory.Exists(_cPathLibrerias))
72  {
73  lcError += "- No existe la ruta de librerías: " + _cPathLibrerias + Environment.NewLine;
74  lbRetorn = false;
75  }
76 
77  // Evitar el error System.InvalidOperationException. Task 143679
78  // http://msdn.microsoft.com/es-es/library/110t3299.aspx
79  // Obtiene o establece un valor que indica si se detectaran las llamadas de un hilo a el subproceso que lo ha creado o no
80  Control.CheckForIllegalCrossThreadCalls = true;
81 
82  // Task 142425. Revisión especial para tareas con el usuario SAGESYSTEM
83  // Si las tareas estan creadas con el nuevo formato, tendran un password de 64 carácteres que hay que revisar
84  // Si el password es de 32 carácteres, es el formato antiguo. Hay que revisar los accesos del usuario SAGESYSTEM. Tampoco consumirá licencia
85  if (_cUserEurowin.ToUpper().Trim() == "SAGESYSTEM" && _cPasswordEurowin.Trim().Length >= 64)
86  {
87  // Marcar nuevo formato de password para revisar más adelante en el método frmPrincipal._Login()
88  EW_GLOBAL._lSageSystem64 = true;
89  }
90 
91  // Si no se han podido obtener los parámetros inciales correctamente, terminamos.
92  if (!lbRetorn)
93  {
94  try
95  {
96  MessageBox.Show(lcError, lcNameProducto, MessageBoxButtons.OK, MessageBoxIcon.Warning);
97  }
98  catch (InvalidOperationException)
99  {
100  //Si es InvalidOperationException es que estamos en alguna tarea programada y por tanto sin acceso a parte visual (usuario SYSTEM). No se puede lanzar un MessageBox.
101  //en este caso guardamos el error en el visor de eventos de windows ya que en este momento aun no tendremos inicializada la base de datos
102  using (System.Diagnostics.EventLog eventLog = new System.Diagnostics.EventLog("Application"))
103  {
104  eventLog.Source = "Application";
105  eventLog.WriteEntry(lcError, System.Diagnostics.EventLogEntryType.Error, 50);
106  }
107  }
108  NETVFP._CerrarHandle(_nHandleVfp); // PE-103466
109  return;
110  }
111 
112  // Iniciar estilos visuales
113  DB.Registrar_Traza("Program.cs,Main_EnableVisualStyles"); // PE-104002
114  Application.EnableVisualStyles();
115  Application.SetCompatibleTextRenderingDefault(false);
116 
117  try
118  {
119  // Asignamos la ruta de inicio de la aplicación
120  main_s50._cPathInicio = _cdirectoryPath;
121  main_s50._lEsEjecutable = true;
122 
123  // Revisar si queremos mostrar el Splash y Info de arranque
124  MostrarSplashInfo(out llSplash, out llSplashInfo, out llDebug);
125 
126  // PE-104002. Establecer modo debug
127  EW_GLOBAL._lDebugMode = llDebug;
128 
129  // Mostrar Splash. Task 143679
130  main_s50._frmSplash = new Forms.frmSplash();
131 
132  if (!_lAutomatico && llSplash)
133  {
134  main_s50._frmSplash._bMostrarInfo = llSplashInfo;
135  main_s50._frmSplash.Show();
136 
137  while (main_s50._frmSplash._IsBusy)
138  {
139  Application.DoEvents();
140  Thread.Sleep(100);
141  }
142 
143  lbRetorn = main_s50._frmSplash._Result;
144  }
145  else
146  {
147  // Validar inicio y mostrar formulario principal
148  DB.Registrar_Traza("Program.cs,Main_main_Sage_50"); // PE-104002
149  lbRetorn = main_s50._main_Sage_50();
150  }
151  }
152  catch (Exception ex)
153  {
154  main_s50._ErrorString = !string.IsNullOrEmpty(main_s50._ErrorString) ? main_s50._ErrorString + System.Environment.NewLine + ex.Message : ex.Message;
155  lbRetorn = false;
156  }
157 
158 
159  if (lbRetorn)
160  {
161  // Si hay algun mensaje en _ErrorString ahora se muestra desde frmPrincipal_Shown
162  DB.Registrar_Traza("Program.cs,Main_Run"); // PE-104002
163  _Run(); // Quitar del Main() cualquier referencia a librerias externas ya que todavía no se ha definido la ruta de librerias.
164  }
165  else
166  {
167  try
168  {
169  MessageBox.Show(main_s50._ErrorString, lcNameProducto + " - Error en la validación de inicio", MessageBoxButtons.OK, MessageBoxIcon.Error);
170  }
171  catch (InvalidOperationException)
172  {
173  //Si es InvalidOperationException es que estamos en alguna tarea programada y por tanto sin acceso a parte visual (usuario SYSTEM). No se puede lanzar un MessageBox.
174  //en este caso guardamos el error en el visor de eventos de windows
175  using (System.Diagnostics.EventLog eventLog = new System.Diagnostics.EventLog("Application"))
176  {
177  eventLog.Source = "Application";
178  eventLog.WriteEntry("Error en la validacion de inicio: " + main_s50._ErrorString, System.Diagnostics.EventLogEntryType.Error, 50);
179  }
180  }
181  main_s50._frmSplash.Close();
182  NETVFP._CerrarHandle(_nHandleVfp); // PE-103466
183  }
184  }
185  }
186 
187  private static bool EntryControl(string[] tcArgs)
188  {
189  string lcPath;
190  Process proc = null;
191  DirectoryInfo loDirLibrerias;
192 
193  //Si no podemos quitar el parametro de control, quiere decir que no viene
194  if (!ParamControl(tcArgs) && !System.Diagnostics.Debugger.IsAttached)
195  {
196  loDirLibrerias = new DirectoryInfo(_cPathLibrerias);
197  lcPath = Path.Combine(loDirLibrerias.Parent.FullName, "Sage50.exe");
198 
199  //Si existe la lanzadera
200  if (File.Exists(lcPath))
201  {
202  //Guardamos la ruta para no eliminar la carpeta
203  SaveEngagedVersion(loDirLibrerias.Name, loDirLibrerias.Parent.FullName);
204 
205  proc = new Process();
206  proc.EnableRaisingEvents = false;
207  proc.StartInfo.UseShellExecute = false;
208  proc.StartInfo.FileName = lcPath;
209  proc.StartInfo.CreateNoWindow = true;
210  proc.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
211  proc.StartInfo.Arguments = string.Join(" ", tcArgs);
212  proc.StartInfo.WorkingDirectory = loDirLibrerias.Parent.FullName;
213  proc.Start();
214 
215  return false;
216  }
217  }
218 
219  return true;
220  }
221 
222  private static void SaveEngagedVersion(string tcVersion, string tcPathConfig)
223  {
224  string lcVersions;
225 
226  ConfigINI loConfigIni = new ConfigINI();
227  loConfigIni._Load(tcPathConfig, "");
228 
229  lcVersions = loConfigIni._Propiedad("[ACCESCONTROL]").Trim();
230 
231  if(!lcVersions.Contains(tcVersion))
232  {
233  lcVersions = String.IsNullOrEmpty(lcVersions) ? tcVersion : $"{lcVersions}|{tcVersion}";
234  loConfigIni._Save("[ACCESCONTROL]", lcVersions, tcPathConfig);
235  }
236  }
237 
238  private static bool ParamControl(string[] tcArgs)
239  {
240  return tcArgs.Count() > 0 && tcArgs[tcArgs.Count() - 1] == S50UpdateLibrary.ParamControl;
241  }
242 
247  private static void MostrarSplashInfo(out bool tlMostrarSplash, out bool tlMostrarInfo, out bool tlDebug)
248  {
249  // Por defecto mostramos Splash sin Info
250  tlMostrarSplash = true;
251  tlMostrarInfo = false;
252  tlDebug = false;
253 
254  // Revisar si no queremos mostrar el Splash
255  string lcValor = Convert.ToString(FUNCTIONS.LeerConfigIni("[SPLASH]", _cdirectoryPath)).Trim().ToUpper();
256  if (lcValor == "NO")
257  tlMostrarSplash = false;
258  else
259  {
260  // En caso de mostrar Splash, revisar si queremos mostar info en el
261  lcValor = Convert.ToString(FUNCTIONS.LeerConfigIni("[SPLASH_INFO]", _cdirectoryPath)).Trim().ToUpper();
262  if (lcValor == "SI")
263  tlMostrarInfo = true;
264  }
265 
266  // Revisar si entramos en modo debug
267  lcValor = Convert.ToString(FUNCTIONS.LeerConfigIni("[SQL_LOG]", _cdirectoryPath)).Trim().ToUpper();
268  if (lcValor == "SI")
269  tlDebug = true;
270  }
271 
276  private static void ObtenerParametros(string[] tcArgs)
277  {
278  if (tcArgs != null && tcArgs.Count() > 0)
279  {
280  // Ahora tenemos todos los parámetros juntos separados por '|'
281  string lcParams = tcArgs[0].Trim().Substring(1);
282  DB.Registrar_Traza("Program.cs,Main_Parameters", lcParams);
283 
284  // Obtener parámetros por separado y recorrerlos para cargar sus valores.
285  string[] lcArgs = lcParams.Split('|');
286 
287  if (lcArgs.Count() > 2)
288  {
289  _lAutomatico = true;
290 
291  int lnArg = 0;
292  foreach (string lcArg in lcArgs)
293  {
294  // Los 3 primeros parámetros serán USUARIO, PASSWORD y FORMULARIO
295  switch (lnArg)
296  {
297  case 0:
298  _cUserEurowin = lcArgs[0];
299  break;
300 
301  case 1:
302  _cPasswordEurowin = lcArgs[1];
303  break;
304 
305  case 2:
306  _cFormEurowin = lcArgs[2];
307  break;
308  }
309 
310  // El resto de parámetros serán los posibles parámetros del FORMULARIO a ejecutar
311  if (lnArg >= 3)
312  {
313  if (!string.IsNullOrWhiteSpace(_cParamsFormEurowin) && lcArg == "ACCESODIRECTO")
314  _cParamsFormEurowin += "*";
315 
316  _cParamsFormEurowin += lcArg;
317  }
318 
319  lnArg++;
320  }
321  }
322  }
323  if (tcArgs.Count() > 1)
324  {
325  //Task 195376: Comprobar si existe un parámetro de tipo /GRUPO:0001 para forzar el arranque con un grupo
326  var result = Array.Find(tcArgs, param => param.Length == 11 && param.Substring(0, 6) == "/GRUPO");
327  if (result != null)
328  {
329  _cGrupoParametro = "COMU" + result.Substring(7);
330  }
331  }
332  }
333 
337  private static void _Run()
338  {
339  //Asignem nom
340  Thread.CurrentThread.Name = "MainThread";
341 
342  // TODO. Que fer amb els estils?
343  EW_GLOBAL._CodiPerfilCarregat = ".predet";
344 
345  // Arrancamos la pantalla principal de Sage 50
346  DB.Registrar_Traza("Program.cs,Main_frmPrincipal"); // PE-104002
347  Application.Run(new Forms.frmPrincipal());
348 
349  // Una vez cerramos sage50, hacemos una copia del config.ini
350  CopiarConfigIni();
351  }
352 
356  private static void CopiarConfigIni()
357  {
358  string lcFile = Path.Combine(main_s50._cPathInicio, "config.ini");
359  string lcFileBak = Path.Combine(main_s50._cPathInicio, "config.bak");
360 
361  try
362  {
363  if (File.Exists(lcFile))
364  File.Copy(lcFile, lcFileBak, true);
365  }
366  catch (Exception) {}
367  }
368  }
369 }
Clase para la actualización de librerias de Sage50
static string ParamControl
Parametro de control para saber si se lanza correctamente
Gestión de variables entorno del config.ini
Definition: ConfigINI.cs:10
bool _Save()
Salvar todas las etiquetas de memoria en disco en rutas por defecto
Definition: ConfigINI.cs:119
void _Load()
Cargar todas las etiquetas de memoria de disco de rutas por defecto
Definition: ConfigINI.cs:101
string _Propiedad(string key)
Devuelve el valor de la propiedad indicada
Definition: ConfigINI.cs:43