' /**
' ---------------------------------------------
' [- (A) Contenido -]
' ---------------------------------------------
' [- Versión -] = 23.10.22.1459.
' [- Nombre Clase -] = LanzarLinkProcessStartCommand.
' -------------
' [- Descripción -] =
' Esta clase esta diseñada para lanzar una dirección Url en el
' navegador por defecto instalado en el sistema operativo.
' -------------
' [- Observaciones -] =
'
' ---------------------------------------------------
' Hereda de la clase [DelegateCommand]
' Es heredada por la clase hija (derivada) [LanzarLinkProcessStartCqs]
'
' ---------------------------------------------------
' Con la actualización de Net 7.0 algunas instrucciones no funcionan
' como lo hacían antes de la actualización, una de ellas es [Process.Start]
' He tenido problemas con la clase “vieja” que usaba [Process.Start] para lanzar una Url.
'
' Un ejemplo: En Net 7.0 No funciona una instrucción del tipo:
' Process.Start("https://www.youtube.com/watch?v=P5tW-_TeC9c")
' A pesar de que la documentación de Microsoft sigue mostrando es sus ejemplos que si que funciona.
'
' Después de mirar muchas web, al final he encontrado el problema, que consiste
' en que Microsoft ha cambiado el comportamiento de [Process.Start].
' Parece ser que el objetivo es que se comporte igual en Net.7.0 y en Net.Core.
' Y también he dado con la solución, que consiste en usar la
' propiedad [UseShellExecute = True] y en usar la propiedad [FileName]
' en lugar de la propiedad [Arguments].
'
' ---------------------------------------------------
' A modo de historia de las clases anteriores
' Esta clase hay que COPIARLA en el ensamblado en la que se usa
'
' Desde [23/02/2007] hasta [23/11/2012] he tenido una clase llamada [LanzarLink]
' que contenía juntas varias funcionalidades que he separado en clases diferentes
' Tienen el prefijo Wpf porque se pueden usare en proyectos dll, Forms y Wpf
' Concretamente las nuevas clases son:
' - [WpfLanzarCalculadora]
' - [WpfLanzarNotepad]
' - [LanzarLinkProcessStartCommand]
' - [LanzarLinkProcessStartCqs]
' - [WpfLanzarNavegador]
'
' Mi clase [WpfMenuMisHerramientas] utiliza las anteriores porque
' habitualmente las incluyo en mis menus Herramientas
' ---------------------------------------------------
'
' -------------
' [- Bibliografía -] =
' ProcessStartInfo.UseShellExecute Property
' https://learn.microsoft.com/en-au/dotnet/api/system.diagnostics.processstartinfo.useshellexecute?view=net-7.0.
' -------------
' [- CodigoEjemplo -] =
' ---------------------------------------------
' El código básico es el siguiente:
' Using proceso As New System.Diagnostics.Process
' With proceso
' ' ------------
' ' OJO - NO USAR - DA PROBLEMAS
' '.StartInfo.Arguments = "www.northwindtraders.com"
' ' ------------
' .StartInfo.FileName = "http://www.microsoft.es"
' .StartInfo.UseShellExecute = True ' OJO debe ser [True]
' .StartInfo.CreateNoWindow = True
' .Start()
' End With
' End Using.
' ---------------------------------------------
' Forma de uso
' ----
' Código en el código XMAL de la ventana
'
' ----
' 1) En la definición de la ventana hay que incluir el namespace de la clase
' xmlns:localUtil="clr-namespace:WpfPruebaStarPorcess.Util.Command"
' ----
' 2) Hay que declarar en {Resources} el comando que se va a usar {LanzarLinkProcessStartCommand}
' También hay que darle un nombre que sera el que referencia en todo el código xaml,
' en este ejemplo es el indicado por {x:Key} es decir {WpfLanzarLinkCommando}
'
'
'
' Observación: también puede declararse en
' ----
'
' 3) Código en el botón que lanza la url
' - El {Command}.......... Referencia a el comando ( esta clase)
' - El {CommandParameter}. Es el parámetro que se pasa al command, concretamente la direccion url
'
' 4) Forma alternativa para un contexMenu
'
' ----
' 5) Usándola como código
' Observa que llamo a la clase comando, pero se usa como una clase normal,
' a la que se le pasa por parámetro el TextBox que vamos a borrar
' La llamo porque tiene el código que necesito usar
'
' Using objLanzador As New Util.Command.LanzarLinkProcessStartCommand()
' objLanzador.Execute("https://www.youtube.com/watch?v=jGflUbPQfW8")
' End Using
'
' ---------------------------------------------
' [- (B) Información básica -]
' ---------------------------------------------
' [- Module Name -] = LanzarLinkProcessStartCommand.vb.
' [- Propietario -] = AGUILA\Cuenta de Trabajo.
' [- Type -] = vb/file.
' [- Size -] = 25,10 KB - [25703 Bytes].
' [- Lenguaje -] = spa [es-ES] Español (España).
' -------------
' [- Fecha de creación -] = 2023-10-21 T 13:01:01.
' [- Última modificación -] = 2023-10-22 T 14:55:29.
' -------------
' [- Net Framework Release -] = Release: 4.6.1 o posterior.
' [- Net Framework Version -] = Versión: 4.0.30319.42000.
' [- Generador nombre -] = H_DocumentadorClases2022.
' [- Generador Version -] = Versión: 1.2.3.4.
' ---------------------------------------------
' [- (C) Propiedad intelectual -]
' ---------------------------------------------
' [- Autor Nombre -] = Joaquin Medina Serrano.
' [- Autor CorreoE -] = mailto:gmjms32@gmail.com.
' [- Autor Copyright -] =
' Esta obra está bajo una Licencia Creative Commons Atribución-NoComercial-SinDerivar 4.0 Internacional.
' Se puede consultar una copia de la licencia http://creativecommons.org/licenses/by-nc-nd/4.0/.
' ---------------------------------------------
' [- (D) Revisiones -]
' ---------------------------------------------
' [- Historial de revisiones -] =
' - 2023/10/21 - Creación. Actualizar una clase 'vieja' a Net 7.0.
' ---------------------------------------------
' [- /Eof -]
' */
Option Explicit On
Option Strict On
Option Infer Off
Option Compare Binary
'------------------------------------------------------------
'
Namespace Util.Command
'''
''' Esta clase esta diseñada para lanzar una dirección Url en el navegador por defecto instalado en el sistema operativo
'''
'''
'''
''' Con la actualización de Net 7.0 algunas instrucciones no funcionan como lo hacían antes de la actualización, una de ellas es [Process.Start]
''' He tenido problemas con la clase “vieja” que usaba [Process.Start] para lanzar una Url.
''' Un ejemplo: En Net 7.0 No funciona una instrucción del tipo:
''' Process.Start("https://www.youtube.com/watch?v=P5tW-_TeC9c")
''' A pesar de que la documentación de Microsoft sigue mostrando es sus ejemplos que si que funciona
''' Después de mirar muchas web, al final he encontrado el problema, que consiste en que Microsoft ha cambiado el comportamiento de [Process.Start]. Parece ser que el objetivo es que se comporte igual en Net.7.0 y en Net.Core. Y también he dado con la solución, que consiste en usar la propiedad [UseShellExecute = True] y en usar la propiedad [FileName] en lugar de la propiedad [Arguments]
'''
'''
''' ProcessStartInfo.UseShellExecute Property
''' https://learn.microsoft.com/en-au/dotnet/api/system.diagnostics.processstartinfo.useshellexecute?view=net-7.0
'''
'''
''' Un Ejemplo con el código básico
'''
'''
'''
'''
'''
''' dcterms.ISO8601
''' 2023-10-21T13:01:01
'''
'''
''' dcterms.DCSV
''' Joaquin Medina Serrano
'''
'''
Public Class LanzarLinkProcessStartCommand
Inherits DelegateCommand
Implements System.Windows.Input.ICommand
Implements IDisposable
#Region "Variables y propiedades de la clase"
'''
''' La dirección que se muestra (La última dirección Url que se muestra en el navegador )
'''
''' Una cadena con una Url, por ejemplo :[https://www.youtube.com/watch?v=P5tW-_TeC9c]
Public ReadOnly Property DireccionUrlQueSeMuestra As String
Protected WriteOnly Property SetDireccionUrlQueSeMuestra As String
Set(value As String)
_DireccionUrlQueSeMuestra = value
End Set
End Property
'''
''' Un objeto [ValidationResult] que contiene la información de lo que ha pasado en el proceso
'''
'''
''' ErrorContent - Contiene un texto que proporciona información adicional sobre lo ocurrido en la operación.
''' IsValid - Obtiene un valor [Boolean] que indica si la operación ha sido correcta [True], o no [False]
'''
Public ReadOnly Property ResultadoOperacion As System.Windows.Controls.ValidationResult
Private Property ResultadoOperacionCanExecute As System.Windows.Controls.ValidationResult
#End Region
#Region "Constructor"
'''
''' Constructor
'''
Public Sub New()
MyBase.New()
'-------------------------------
' Los parámetros de [Command]
' El [Delegado] (la Acción) que llamara al método [cmdExecute]
Dim localExcuteAction As Action(Of Object) = New Action(Of Object)(AddressOf Me.Execute)
' El [Delegado] que llamara al método [cmdCanExecute]
Dim localCanExecuteAction As Predicate(Of Object) = Function(param) CanExecute(param)
' [Opcional][Informativo] El nombre de este command (El nombre de esta clase)
Dim localNombreCommand As String = System.Reflection.MethodBase.GetCurrentMethod.DeclaringType.Name
' [Opcional][Informativo] Descripción de lo que hace este command.
Dim localDescripcion As String = "Pone en marcha la Uri recibida a través del parámetro," &
" la idea es que sea una canción, o un video."
' ¿¿ Se disparan los eventos [ExecuteStart] y [ExecuteCompleted] ??
Dim localDispararEventos As Boolean = False
'----------------------------------
' A modo de ejemplo
' [Opcional] Juego de teclas que activan el comando (P.e: Ctrl + D)
'Dim localGesture As KeyGesture = New KeyGesture(Key.Escape, ModifierKeys.Control, "Cerrar la ventana [Esc]")
'-------------------------------
' Cargar valores en la clase base
'-------------------------------
' Obligatorias
MyBase._executeAction = localExcuteAction
MyBase._canExecuteAction = localCanExecuteAction
' Opcionales
MyBase.ComandoNombre = localNombreCommand
MyBase.ComandoDescripcion = localDescripcion
MyBase.DispararEventosExecuterStartCompleted = localDispararEventos
'MyBase.KeyGesture = localGesture
End Sub
#End Region
#Region "Implements System.Windows.Input.ICommand"
#Region "Refactorizado "
' ----------------------------------------
' REFACTORIZADO
' Están en las clases derivadas
' '''
' ''' ¿ Se puede ejecutar el proceso execute? S/N
' '''
' '''
' ''' [True], el proceso se puede ejecutar. [False], pues no.
' '''
' ''' Funciona como la interface ICOMMAND, pero en sencillo y sin necesidad de un entrono gráfico (una ventana)
' Public Overloads Function CanExecute() As Boolean 'Implements ICommandSencilla.CanExecute
' Return CanExecute(Me.DireccionUrlQueSeMuestra)
' End Function
' '''
' ''' Esta función muestra la direccionnURL que se recibe por el constructor
' '''
' Public Overloads Sub Execute()
' Call Execute(Me.DireccionUrlQueSeMuestra)
' End Sub
' ----------------------------------------
' REFACTORIZADO
' Están en la clase base
'
' '''
' ''' Se dispara en cuando cambia el valor devuelto por [CanExecute]
' '''
' '''
' ''' Interfaz [System.Windows.Input.ICommand]. Evento [CanExecuteChanged]
' '''
' Public Event CanExecuteChanged As EventHandler Implements ICommand.CanExecuteChanged
'
' '''
' ''' Variable local que contiene el valor que devuelve la ejecución de la función [CanExecute]
' ''' Se usa para saber si hay que disparar el evento [CanExecuteChanged] o no
' ''' tiene el valor True, porque soy optimista y supongo que siempre se puede ejecutar
' '''
' Private campoCanExecuteAnterior As Boolean = True
'
' /Eof REFACTORIZADO
' ----------------------------------------
#End Region
'''
''' ¿ Se puede ejecutar el proceso execute? S/N
'''
''' El objeto parameter tiene que ser una cadena (obligatoriamente)
'''
''' [True], el proceso se puede ejecutar. [False], pues no.
'''
'''
''' El evento [ExecuteChanged] se dispara por la clase base
'''
Private Overloads Function CanExecute(ByVal parameter As Object) As Boolean Implements ICommand.CanExecute
'----------------------
' A) El resultado.
Dim localCanExecuteActual As Boolean = False
'----------------------
' B) Comprobación si se puede ejecutar o no
'------------------------
Try
'-----------------------------------------
' Control del parámetro
' - No puede ser NULL
' - Tiene que ser un objeto String
' - El String no puede ser Null, empty o WhiteSpace
' - Tiene que poder convertirse en una URL Valida
' - Solo entonces la dirección URL se considera correcta
' y por lo tanto el proceso se puede ejecutar
'-------------------------------------
If parameter IsNot Nothing Then
' Ver si es un objeto string
If parameter.GetType = GetType(System.String) Then
' Convertirlo en una cadena
Dim target As System.String = TryCast(parameter, String)
' Si no es NULL, vacía o espacios
If String.IsNullOrWhiteSpace(target) = False Then
' Convertirla en una url
Dim url As New System.Uri(target)
' Ver si la url es valida
localCanExecuteActual = url.IsWellFormedOriginalString
End If
End If
End If
ResultadoOperacionCanExecute = ValidationResult.ValidResult
'-----------------------------------------
Catch ex As System.Exception
' Si hay un error la cadena URL no es valida,
' el proceso no puede ejecutarse
localCanExecuteActual = False
ResultadoOperacionCanExecute = New ValidationResult(False, ex.Message)
End Try
' '----------------------
' 'C) Mirar si se dispara el evento o no
' ' OJO, se hace en la clase base
' If Boolean.Equals(campoCanExecuteAnterior, localCanExecuteActual) = False Then
' campoCanExecuteAnterior = localCanExecuteActual
' RaiseEvent CanExecuteChanged(Me, New System.EventArgs)
' End If
'----------------------
'D) Devolver el resultado
Return localCanExecuteActual
End Function
'''
''' Esta función muestra la direccionnURL que se recibe por parámetro en el navegador por defecto
'''
''' El objeto parameter tiene que ser una cadena (obligatoriamente)
Private Overloads Sub Execute(ByVal parameter As Object) Implements ICommand.Execute
Dim SemaforoTodoCorrecto As Boolean
Dim TextoWriter As String
Dim localDireccionCadena As System.String = String.Empty
Using sw As New System.IO.StringWriter(System.Globalization.CultureInfo.CurrentCulture)
sw.WriteLine()
sw.WriteLine("---")
sw.WriteLine("Ensamblado [{0}]", System.Reflection.MethodBase.GetCurrentMethod.Module.Name)
sw.WriteLine("Clase .... [{0}]", System.Reflection.MethodBase.GetCurrentMethod.DeclaringType.Name)
sw.WriteLine("Función .. [{0}]", System.Reflection.MethodBase.GetCurrentMethod.Name)
sw.WriteLine("Realiza la tarea de lanzar una dirección URL, en el navegador")
sw.WriteLine("instalado por defecto en el Sistema Operativo")
sw.WriteLine("---")
Try
'----------------------------------------
'Asegurar los valores iniciales
SemaforoTodoCorrecto = True
TextoWriter = String.Empty
localDireccionCadena = String.Empty
'-----------------------------------------
' Control del parámetro
' - No puede ser NULL
' - Tiene que contener un objeto String
' - El String no puede ser Null, empty o WhiteSpace
' - Tiene que poder convertirse en una URL Valida
' - Solo entonces la dirección URL se considera correcta
' y por lo tanto el proceso se puede ejecutar
'-------------------------------------
' comprobar si se puede ejecutar
' Devuelve [True = Si se puede ejecutar si la dirección Url es correcta
sw.WriteLine("Proceso [Start] - Comprobación parámetro - Iniciando")
If Me.CanExecute(parameter) = True Then
sw.WriteLine("Proceso [Start] - Comprobación parámetro - Finalizado OK")
sw.WriteLine("Proceso [Start] - Conversion a cadena - Iniciando")
localDireccionCadena = TryCast(parameter, String)
sw.WriteLine("Proceso [Start] - Conversion a cadena - Finalizado OK")
sw.WriteLine("Proceso [Start] - Iniciando")
'------------------------------------------
'[Process] Proporciona acceso a procesos locales y remotos,
'y permite iniciar y detener procesos del sistema local.
Using proceso As New System.Diagnostics.Process
With proceso
sw.WriteLine("Proceso [Start] - Cargando propiedades")
'------------------------------------------
'[FileName]
' Establece la aplicación o el documento que se va a iniciar
' Debe establecer al menos la FileName propiedad antes de iniciar el proceso.
' El nombre de archivo es cualquier aplicación o documento.
' Un documento se define como cualquier tipo de archivo que tenga asociada una acción abierta o predeterminada.
' Ejemplo .StartInfo.FileName = "http://www.microsoft.es"
'
' El conjunto de tipos de archivo disponibles depende en parte del valor de la
' propiedad [UseShellExecute].
' Si toma el valor [True], puede iniciar cualquier documento y realizar operaciones en el archivo, como imprimir, con el Process componente .
' Cuando toma el valor [False], solo puede iniciar ejecutables con el componente Process.
'
.StartInfo.FileName = localDireccionCadena
sw.WriteLine("Proceso [Start] - [.StartInfo.FileName = {0}] ", localDireccionCadena)
'------------------------------------------
' Apunte Táctico
' [Propiedad Arguments]
' OJO esta propiedad provoca un ERROR de fichero no encontrado
'.StartInfo.Arguments = "http://www.microsoft.es"
'------------------------------------------
' [UseShellExecute] Indica si se va a usar el shell del sistema operativo para iniciar el proceso.
.StartInfo.UseShellExecute = True
sw.WriteLine("Proceso [Start] - [.StartInfo.UseShellExecute = True] ")
'------------------------------------------
' [CreateNoWindow] Indica si el proceso se va a iniciar en una nueva ventana.
.StartInfo.CreateNoWindow = True
sw.WriteLine("Proceso [Start] - [.StartInfo.CreateNoWindow = True] ")
'------------------------------------------
' [Start] Inicia un proceso y lo asocia a un componente Process.
.Start()
sw.WriteLine("Proceso [Start] - Ejecutado")
End With
End Using
'------------------------------------------
sw.WriteLine("Proceso [Start] - Finalizado OK")
sw.WriteLine("---")
Else
sw.WriteLine("---")
sw.WriteLine("El objeto [parámetro] recibido no cumple las condiciones necesarias")
If ResultadoOperacionCanExecute.IsValid = False Then
sw.WriteLine("ERROR en el parámetro")
sw.WriteLine(Convert.ToString(ResultadoOperacionCanExecute.ErrorContent))
End If
sw.WriteLine(" - Debe ser una cadena de texto (OBLIGATORIAMENTE)")
sw.WriteLine(" - No puede ser NULL")
sw.WriteLine(" - Tiene que contener un objeto String")
sw.WriteLine(" - El String no puede ser Null, empty o WhiteSpace")
sw.WriteLine(" - Tiene que poder convertirse en una URL Valida")
sw.WriteLine()
sw.WriteLine("Proceso [Start] - Finalizado Problema con parámetro")
sw.WriteLine("Proceso [Start] - No se ejecuta")
sw.WriteLine("---")
SemaforoTodoCorrecto = False
End If
Catch ex As System.Exception
sw.WriteLine("---")
sw.WriteLine("Proceso [Start] - ERROR")
sw.WriteLine("Proceso [Start] - No se ejecuta por un error")
sw.WriteLine(ex.Message)
sw.WriteLine("---")
SemaforoTodoCorrecto = False
Finally
sw.WriteLine("/Eof")
TextoWriter = sw.ToString
End Try
End Using
' -------------------------------------
' Carga de las variables miembro con la información del proceso
_DireccionUrlQueSeMuestra = localDireccionCadena
_ResultadoOperacion = New System.Windows.Controls.ValidationResult(SemaforoTodoCorrecto, TextoWriter)
End Sub
#End Region
#Region "IDisposable Support. [Para clases derivadas] Implementación de .NET Version: [2022/03/03]"
'
'''
''' [Dispose] Código de limpieza de la clase
'''
''' [True], llama el usuario, [False], llama el sistema
'''
'''
''' Dispose (bool quienMeLLama) se ejecuta en dos escenarios distintos.
'''
'''
''' Si [quienMeLLama] es igual a true, el método ha sido llamado
''' directamente, o indirectamente, por el código de un usuario.
''' Los recursos administrados y no administrados se pueden eliminar.
'''
'''
''' Si [quienMeLLama] es igual a false, el método ha sido llamado por el
''' [runtime] desde el interior del finalizador y usted no debe hacer
''' referencia a otros objetos, ni siquiera para eliminarlos.
''' Solo los recursos no administrados pueden ser eliminados.
'''
'''
Protected Overloads Sub Dispose(paramQuienMeLLama As System.Boolean)
If MyBase.IsDisposed = False Then
If paramQuienMeLLama = True Then
'
'------------------------------------------------------------------------------------------
' 1) Liberar UNICAMENTE objetos NO administrados.
'------------------------------------------------------------------------------------------
' Call LiberarRecursosNoAdministrados()
'
'------------------------------------------------------------------------------------------
' 2) Desechar objetos SI administrados.
' Un objeto administrado es cualquier objeto de .NET
' es un objeto de .NET que maneja el motor de ejecución de NET
'------------------------------------------------------------------------------------------
If Not (ResultadoOperacion Is Nothing) Then
_ResultadoOperacion = Nothing
End If
'------------------------------------------------------------------------------------------
' 3) Establecer campos grandes como Null.
'------------------------------------------------------------------------------------------
_DireccionUrlQueSeMuestra = Nothing
'------------------------------------------------------------------------------------------
' 4) La clase base
'------------------------------------------------------------------------------------------
MyBase.Dispose(True)
'
Else
'
'------------------------------------------------------------------------------------------
' 1) Liberar UNICAMENTE los objetos NO administrados.
'------------------------------------------------------------------------------------------
' Call LiberarRecursosNoAdministrados()
End If
End If
End Sub
' '''
' ''' 1) Liberar UNICAMENTE objetos NO administrados.
' ''' Son recursos que NO administra el motor en tiempo de ejecución,
' ''' como conexiones a bases de datos
' ''' llamadas al API de Windows, etc. el Word o Excel
' '''
' '''
' ''' ATENCION - Quite los comentarios de Finalize() SOLO si el anterior Dispose(disposing As Boolean)
' ''' tiene código para liberar recursos no administrados.
' '''
' Private Sub LiberarRecursosNoAdministrados()
' ' si no hay recursos, no hacer nada
' End Sub
' '''
' ''' Permite que un objeto intente liberar recursos NO ADMINISTRADOS y realizar otras operaciones de limpieza
' ''' antes de que sea reclamado por la recolección de elementos no utilizados.
' '''
' '''
' ''' ATENCION - Quite los comentarios de Finalize() SOLO si el anterior Dispose(disposing As Boolean)
' ''' tiene código para liberar recursos no administrados.
' '''
' Protected Overrides Sub Finalize()
' 'ATENCION - Quite los comentarios de Finalize() SOLO si el anterior Dispose(disposing As Boolean)
' ' tiene código para liberar recursos no administrados.
' ' No cambie este código. Coloque el código de limpieza en el anterior Dispose(disposing As Boolean).
' Dispose(False)
' MyBase.Finalize()
' End Sub
#End Region
#Region "código Refactorizado que funciona, Guardar para consultas futuras pero no usar"
#Region "Hacer el trabajo llamando específicamente al navegador"
' ' '
' ' Esta función es la que hace el trabajo de lanzar la URL en el navegador por defecto del Sistema
' ' OBSERVACIONES
' ' La función que hace el trabajo en [Process.Start(startInfo)], en la ultima actualización que ha habido ha cambiado, y ahora exige la ruta completa (ruta + nombre + extension) del programa (del navegador) que vamos a lanzar
' '
' ' Para resolver este problema he mirado donde guarda Windows los navegadores,
' ' OJO windows 11
' ' Primero busco el programa [Edge].
' ' si no lo encuentro busco el [Iexplorer].
' ' si no lo encuentro busco el [Opera].
' ' si no lo encuentro no lanzo nada.
' ' ni disparo ningún Error
' ' Evidentemente solo busca esos dos navegadores
' '
' ' El resultado de la operación se guarda en las dos variables miembro de la clase
' '
' ' Property DireccionUrlQueSeMuestra As String
' ' que contiene La dirección que se muestra (La última dirección Url que se muestra en el navegador), Una cadena con una Url, por ejemplo :[https://www.youtube.com/watch?v=P5tW-_TeC9c]
' '
' ' Property ResultadoOperacion As System.Windows.Controls.ValidationResult
' ' que contiene Un objeto [ValidationResult] que contiene la información de lo que ha pasado en el proceso
' ' ErrorContent - Contiene un texto que proporciona información adicional sobre lo ocurrido en la operación.
' ' IsValid - Obtiene un valor [Boolean] que indica si la operación ha sido correcta [True], o no [False]
'
'
' '''
' '''
' '''
' '''
' '''
' '''
' Private Sub LanzarUrl(ByVal ParamStartInfoArgumentsObj As Object)
' '------------------------------------------------
' 'Nota
' ' La función [Process.Start(startInfo)]
' 'PROBLEMA
' ' Exige la ruta completa del programa que vamos a lanzar
' 'Por eso primero busco el programa [Edge]
' 'si no lo encuentro busco el [Iexplorer]
' 'si no lo encuentro no lanzo nada
' 'ni disparo ningún error
' ------------------------------------------------
' https://learn.microsoft.com/es-es/dotnet/api/system.diagnostics.process?view=net-7.0
' Process.Start("https://www.youtube.com/watch?v=P5tW-_TeC9c")
' o bien
' Dim startInfo As New ProcessStartInfo("IExplore.exe")
' startInfo.WindowStyle = ProcessWindowStyle.Minimized
' Process.Start(startInfo)
' startInfo.Arguments = "www.northwindtraders.com"
' Process.Start(startInfo)
' ------------------------------------------------
'
'
' Dim startInfo As ProcessStartInfo
' Dim ProcesoEjecutado As Boolean
' Dim carpetaEspecial As String
' Dim DireccionBienFormada As Boolean
' Dim localUrl As System.Uri = Nothing
'
' Dim textoMensaje As String
' Using SW As New System.IO.StringWriter(System.Globalization.CultureInfo.CurrentCulture)
'
' SW.WriteLine("Buscando un navegador en el sistema")
' 'SW.WriteLine("Para lanzar la URL [{0}]", ParamStartInfoArguments)
' 'SW.WriteLine()
'
' Try
' '------------------------------
' ' Asegurarme de que tiene este valor
' ProcesoEjecutado = False
' DireccionBienFormada = False
'
' '-------------------------------------------------
' '-------------------------------------------------
' 'A) Lo primero comprobar la dirección url
' '-------------------------------------------------
'
' Dim ParamStartInfoArguments As String
' ParamStartInfoArguments = CType(ParamStartInfoArgumentsObj, String)
'
'
' SW.WriteLine("URL - Bien formada [Comprobando]")
' If String.IsNullOrWhiteSpace(ParamStartInfoArguments) = False Then
' localUrl = New System.Uri(ParamStartInfoArguments)
' DireccionBienFormada = localUrl.IsWellFormedOriginalString
' Else
' DireccionBienFormada = False
' SW.WriteLine("URL - Tiene valor [NULL]")
' End If
' SW.WriteLine("URL - Bien formada [{0}]", DireccionBienFormada)
'
' If DireccionBienFormada = False Then
' SW.WriteLine("URL - No se incluye en el navegador", DireccionBienFormada)
' Else
' ' -----------------------------------
' ' Actualizar la propiedad miembro
' ' -----------------------------------
' _DireccionUrlQueSeMuestra = localUrl.AbsoluteUri
' End If
' SW.WriteLine()
'
' ' -------------------------------------------------------
' ' Texto con una dirección buena
' ' -------------------------------------------------------
' 'Buscando un navegador en el sistema
' 'Para lanzar la URL [http://joaquin.medina.name/]
'
' 'URL -Bien formada [Comprobando]
' 'URL -Bien formada [True]
'
' 'Navegador [Edge] - Buscando
' 'Navegador [Edge] - Encontrado
' 'Navegador [Edge] - Url Pasada
' 'Navegador [Edge] - Lanzado
' '/ Eof
'
' ' -------------------------------------------------------
' ' Texto SIN una dirección
' ' -------------------------------------------------------
' 'Buscando un navegador en el sistema
' 'Para lanzar la URL []
'
' 'URL -Bien formada [Comprobando]
' 'URL -Tiene valor [NULL]
' 'URL -Bien formada [False]
' 'URL -No se incluye en el navegador
'
' 'Navegador [Edge] - Buscando
' 'Navegador [Edge] - Encontrado
' 'Navegador [Edge] - Lanzado
' '/ Eof
'
'
' '-------------------------------------------------
' '-------------------------------------------------
' 'B) Buscando el navegador [EDGE]
' '-------------------------------------------------
' If ProcesoEjecutado = False Then
' '----------------------------------------
' ' Montar la ruta:
' ' ["C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"]
' SW.WriteLine("Navegador [Edge] - Buscando")
' carpetaEspecial = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) ' C:\Program Files (x86)
' Dim rutaMsedegeExe As String = System.IO.Path.Combine(carpetaEspecial, "Microsoft\Edge\Application\msedge.exe")
' ' Comprobar que existe
' If System.IO.File.Exists(rutaMsedegeExe) = True Then
' ' Si existe incluir un mensaje indicándolo
' SW.WriteLine("Navegador [Edge] - Encontrado")
' ' Instanciar [ProcessStartInfo]
' startInfo = New ProcessStartInfo(rutaMsedegeExe)
' startInfo.WindowStyle = ProcessWindowStyle.Normal
'
' ' Si existe la dirección y esta bien formada
' ' incluirla en [ProcessStartInfo]
' If DireccionBienFormada = True Then
' 'startInfo.Arguments = "www.northwindtraders.com"
' startInfo.Arguments = localUrl.AbsoluteUri
' SW.WriteLine("Navegador [Edge] - Url Pasada")
' End If
'
' ' Ejecutar [Process.Start]
' Process.Start(startInfo)
' ' Marcar como ejecutado
' ProcesoEjecutado = True
' ' mensaje informativo
' SW.WriteLine("Navegador [Edge] - Lanzado")
' Else
' SW.WriteLine("Navegador [msedge.exe] - NO ENCONTRADO")
' SW.WriteLine("Lo he buscado en el directorio ")
' SW.WriteLine("[{0}]", rutaMsedegeExe)
' SW.Flush()
' End If
' End If
'
'
' '-------------------------------------------------
' '-------------------------------------------------
' 'C) Buscando [IExplore] de 64 bits
' '-------------------------------------------------
' If ProcesoEjecutado = False Then
' ' Montar la ruta:
' ' 'C:\Program Files\Internet Explorer\IExplore.exe
'
' SW.WriteLine("Navegador [IExplore.exe] (X64) - Buscando")
' Dim RutaDosExplorer As String
' carpetaEspecial = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) ' C:\Program Files
' RutaDosExplorer = System.IO.Path.Combine(carpetaEspecial, "Internet Explorer\IExplore.exe")
'
' If System.IO.File.Exists(RutaDosExplorer) = True Then
' SW.WriteLine("Navegador [IExplore.exe] (X64) - encontrado")
' startInfo = New ProcessStartInfo(RutaDosExplorer)
' startInfo.WindowStyle = ProcessWindowStyle.Normal
'
' ' Si existe la dirección y esta bien formada
' ' incluirla en [ProcessStartInfo]
' If DireccionBienFormada = True Then
' 'startInfo.Arguments = "www.northwindtraders.com"
' startInfo.Arguments = localUrl.AbsoluteUri
' SW.WriteLine("Navegador [IExplore.exe] (X64) - Url Pasada")
' End If
'
' Process.Start(startInfo)
' ProcesoEjecutado = True
' SW.WriteLine("Navegador [IExplore.exe] (X64) - Lanzado")
' Else
' SW.WriteLine("Navegador [IExplore.exe] (X64) - NO ENCONTRADO")
' SW.WriteLine("Lo he buscado en el directorio ")
' SW.WriteLine("[{0}]", RutaDosExplorer)
' SW.Flush()
' End If
' End If
'
'
' '-------------------------------------------------
' '-------------------------------------------------
' 'D) Buscando [IExplore (X86)] de 32 bits
' '-------------------------------------------------
' If ProcesoEjecutado = False Then
' ' Montar la ruta:
' ' 'C:\Program Files\Internet Explorer\IExplore.exe
' SW.WriteLine("Navegador [IExplore.exe] (X86) - Buscando")
'
' Dim RutaUnoExplorer As String
' carpetaEspecial = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) ' C:\Program Files (x86)
' RutaUnoExplorer = System.IO.Path.Combine(carpetaEspecial, "Internet Explorer\IExplore.exe")
'
' If System.IO.File.Exists(RutaUnoExplorer) = True Then
' SW.WriteLine("Navegador [IExplore.exe] (X86) - Encontrado")
' startInfo = New ProcessStartInfo(RutaUnoExplorer)
' startInfo.WindowStyle = ProcessWindowStyle.Normal
'
' ' Si existe la dirección y esta bien formada
' ' incluirla en [ProcessStartInfo]
' If DireccionBienFormada = True Then
' 'startInfo.Arguments = "www.northwindtraders.com"
' startInfo.Arguments = localUrl.AbsoluteUri
' SW.WriteLine("Navegador [IExplore.exe] (X86) - Url Pasada")
' End If
'
' Process.Start(startInfo)
' ProcesoEjecutado = True
' SW.WriteLine("Navegador [IExplore.exe] (X86) - Lanzado")
' Else
' SW.WriteLine("Navegador [IExplore.exe] (X86) - NO ENCONTRADO")
' SW.WriteLine("Lo he buscado en el directorio ")
' SW.WriteLine("[{0}]", RutaUnoExplorer)
' SW.Flush()
' End If
' End If
'
' '-------------------------------------------------
' '-------------------------------------------------
' 'E) Buscando [Opera]
' '-------------------------------------------------
' If ProcesoEjecutado = False Then
' ' Montar la ruta:
' ' 'D:\Program Files (x86)\Opera\launcher.exe
' SW.WriteLine("Navegador [Opera] - Buscando")
'
' Dim RutaTresOpera As String
' carpetaEspecial = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) ' C:\Program Files (x86)
' RutaTresOpera = System.IO.Path.Combine(carpetaEspecial, "Opera\launcher.exe")
'
' If System.IO.File.Exists(RutaTresOpera) = True Then
' SW.WriteLine("Navegador [Opera] - Encontrado")
' startInfo = New ProcessStartInfo(RutaTresOpera)
' startInfo.WindowStyle = ProcessWindowStyle.Normal
'
' ' Si existe la dirección y esta bien formada
' ' incluirla en [ProcessStartInfo]
' If DireccionBienFormada = True Then
' 'startInfo.Arguments = "www.northwindtraders.com"
' startInfo.Arguments = localUrl.AbsoluteUri
' SW.WriteLine("Navegador [Opera] - Url Pasada")
' End If
'
' Process.Start(startInfo)
' ProcesoEjecutado = True
' SW.WriteLine("Navegador [Opera] - Lanzado")
' Else
' SW.WriteLine("Navegador [Opera] - NO ENCONTRADO")
' SW.WriteLine("Lo he buscado en el directorio ")
' SW.WriteLine("[{0}]", RutaTresOpera)
' SW.Flush()
' End If
' End If
'
'
'
' '-------------------------------------------------
' 'E) Mensaje de navegadores no encontrados
' '-------------------------------------------------
' If ProcesoEjecutado = False Then
' SW.WriteLine("PROBLEMA")
' SW.WriteLine("No he encontrado ningún Navegador")
' SW.WriteLine("El proceso NO se ha ejecutado")
' End If
'
' Catch ex As System.Exception
' SW.WriteLine("PROBLEMA")
' SW.WriteLine("Ha ocurrido un error")
' SW.WriteLine("El proceso NO se ha ejecutado")
' SW.WriteLine(ex.Message)
' SW.WriteLine(ex.ToString)
' ProcesoEjecutado = False
' Finally
' '-----------------------------
' 'F) Destruir los objetos empleados
' startInfo = Nothing
' carpetaEspecial = Nothing
' End Try
'
'
' '-------------------------------------------------
' 'G) Ultima linea del texto
' SW.WriteLine("/ Eof")
'
' ' Volcar el texto en una variable
' textoMensaje = SW.ToString
'
' End Using
'
'
' '-------------------------------------------------
' 'H) Devolver el resultado
' ' Refactorizado
' ' If ProcesoEjecutado = True Then
' ' Return New ValidationResult(True, textoMensaje)
' ' Else
' ' Return New ValidationResult(False, textoMensaje)
' ' End If
' '/ Eof Refactorizado
' '-------------------------------------------------
'
'
' ' -----------------------------------
' ' H) Actualizar la propiedad miembro
' ' -----------------------------------
' _ResultadoOperacion = New ValidationResult(ProcesoEjecutado, textoMensaje)
'
' End Sub
'
#End Region
#Region "Refactorizada, CONSERVAR - Funciona usando WScript.Shell"
' '''
' ''' Esta función muestra la direccionnURL que se recibe por parámetro en el navegador por defecto
' '''
'
' Private Sub Execute(ByVal parameter As Object)
' If parameter IsNot Nothing Then
' Dim localDireccionCadena As System.String = TryCast(parameter, String)
' If localDireccionCadena IsNot Nothing Then
' If String.IsNullOrWhiteSpace(localDireccionCadena) = False Then
' ' ----------------------------------------------------
' ' 2023/10/15 Refactorizado
' ' https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.start?view = net-7.0#system-diagnostics-process-start(system-string-system-string)
' ' No funciona con net7.0
' ' System.Diagnostics.Process.Start(dirección, Nothing)
' ' He visto que funciona instanciando WScript.Shell, pero no se porque
' ' ----------------------------------------------------
' If Me.CanExecute(localDireccionCadena) = True Then
' Dim localUrl As New Uri(localDireccionCadena)
' ' Nota importante
' ' Requiere la referencia
' ' Windows Script Host Object Model
' '
' Dim oShell As IWshRuntimeLibrary.IWshShell_Class = Nothing
' Dim oShortcut As IWshRuntimeLibrary.IWshShortcut_Class = Nothing
' Try
' oShell = CType(CreateObject("WScript.Shell"), IWshRuntimeLibrary.IWshShell_Class)
' 'oShell.Run("http://joaquin.medina.name")
' 'oShell.Run(localDireccionCadena)
' 'Dim localUrl As New Uri(localDireccionCadena)
' oShell.Run(localUrl.AbsoluteUri)
' ' Actualizar la variable miembro
' Me.DireccionUrlQueSeMuestra = localDireccionCadena
' Catch ex As Exception
' ' No hacer nada
' ' No funciona y no se lanza el recurso
' Finally
' If oShell IsNot Nothing Then
' oShell = Nothing
' End If
' If oShortcut IsNot Nothing Then
' oShortcut = Nothing
' End If
' End Try
' End If
' End If
' End If
' End If
' End Sub
#End Region
#End Region
End Class
End Namespace