elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Security Series.XSS. [Cross Site Scripting]


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  Librería de Snippets para VB.NET !! (Compartan aquí sus snippets)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: 1 ... 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 [52] 53 54 55 56 57 58 59 60 Ir Abajo Respuesta Imprimir
Autor Tema: Librería de Snippets para VB.NET !! (Compartan aquí sus snippets)  (Leído 529,041 veces)
Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.874



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #510 en: 23 Diciembre 2017, 04:19 am »

CÓMO OBTENER EL PRECIO DEL BITCOIN EN LA MONEDA QUE QUIERAS

Bueno, pues buscando alguna API gratuita y sin muchas limitaciones, encontré https://bitpay.com/api (de hecho, parece que no tiene ninguna limitación de peticiones por mes, pero no estoy completamente seguro.)

La sintaxis de la consulta es sencilla: "https://bitpay.com/api/rates/BTC/{NOMBRE_DE_MONEDA}" -así que primero creamos la siguiente enumeración con los nombres de monedas aceptados por la API (o en su defecto, un diccionario. como prefieran adaptarlo):

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Specifies the ISO-4217 3-character currency codes.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. Public Enum Currencies As Integer
  7.  
  8.    ''' <summary>
  9.    ''' UAE Dirham
  10.    ''' </summary>
  11.    AED
  12.  
  13.    ''' <summary>
  14.    ''' Afghan Afghani
  15.    ''' </summary>
  16.    AFN
  17.  
  18.    ''' <summary>
  19.    ''' Albanian Lek
  20.    ''' </summary>
  21.    ALL
  22.  
  23.    ''' <summary>
  24.    ''' Armenian Dram
  25.    ''' </summary>
  26.    AMD
  27.  
  28.    ''' <summary>
  29.    ''' Netherlands Antillean Guilder
  30.    ''' </summary>
  31.    ANG
  32.  
  33.    ''' <summary>
  34.    ''' Angolan Kwanza
  35.    ''' </summary>
  36.    AOA
  37.  
  38.    ''' <summary>
  39.    ''' Argentine Peso
  40.    ''' </summary>
  41.    ARS
  42.  
  43.    ''' <summary>
  44.    ''' Australian Dollar
  45.    ''' </summary>
  46.    AUD
  47.  
  48.    ''' <summary>
  49.    ''' Aruban Florin
  50.    ''' </summary>
  51.    AWG
  52.  
  53.    ''' <summary>
  54.    ''' Azerbaijani Manat
  55.    ''' </summary>
  56.    AZN
  57.  
  58.    ''' <summary>
  59.    ''' Bosnia-Herzegovina Convertible Mark
  60.    ''' </summary>
  61.    BAM
  62.  
  63.    ''' <summary>
  64.    ''' Barbadian Dollar
  65.    ''' </summary>
  66.    BBD
  67.  
  68.    ''' <summary>
  69.    ''' Bitcoin Cash
  70.    ''' </summary>
  71.    BCH
  72.  
  73.    ''' <summary>
  74.    ''' Bangladeshi Taka
  75.    ''' </summary>
  76.    BDT
  77.  
  78.    ''' <summary>
  79.    ''' Bulgarian Lev
  80.    ''' </summary>
  81.    BGN
  82.  
  83.    ''' <summary>
  84.    ''' Bahraini Dinar
  85.    ''' </summary>
  86.    BHD
  87.  
  88.    ''' <summary>
  89.    ''' Burundian Franc
  90.    ''' </summary>
  91.    BIF
  92.  
  93.    ''' <summary>
  94.    ''' Bermudan Dollar
  95.    ''' </summary>
  96.    BMD
  97.  
  98.    ''' <summary>
  99.    ''' Brunei Dollar
  100.    ''' </summary>
  101.    BND
  102.  
  103.    ''' <summary>
  104.    ''' Bolivian Boliviano
  105.    ''' </summary>
  106.    BOB
  107.  
  108.    ''' <summary>
  109.    ''' Brazilian Real
  110.    ''' </summary>
  111.    BRL
  112.  
  113.    ''' <summary>
  114.    ''' Bahamian Dollar
  115.    ''' </summary>
  116.    BSD
  117.  
  118.    ''' <summary>
  119.    ''' Bhutanese Ngultrum
  120.    ''' </summary>
  121.    BTN
  122.  
  123.    ''' <summary>
  124.    ''' Botswanan Pula
  125.    ''' </summary>
  126.    BWP
  127.  
  128.    ''' <summary>
  129.    ''' Belize Dollar
  130.    ''' </summary>
  131.    BZD
  132.  
  133.    ''' <summary>
  134.    ''' Canadian Dollar
  135.    ''' </summary>
  136.    CAD
  137.  
  138.    ''' <summary>
  139.    ''' Congolese Franc
  140.    ''' </summary>
  141.    CDF
  142.  
  143.    ''' <summary>
  144.    ''' Swiss Franc
  145.    ''' </summary>
  146.    CHF
  147.  
  148.    ''' <summary>
  149.    ''' Chilean Unit of Account (UF)
  150.    ''' </summary>
  151.    CLF
  152.  
  153.    ''' <summary>
  154.    ''' Chilean Peso
  155.    ''' </summary>
  156.    CLP
  157.  
  158.    ''' <summary>
  159.    ''' Chinese Yuan
  160.    ''' </summary>
  161.    CNY
  162.  
  163.    ''' <summary>
  164.    ''' Colombian Peso
  165.    ''' </summary>
  166.    COP
  167.  
  168.    ''' <summary>
  169.    ''' Costa Rican Colón
  170.    ''' </summary>
  171.    CRC
  172.  
  173.    ''' <summary>
  174.    ''' Cuban Peso
  175.    ''' </summary>
  176.    CUP
  177.  
  178.    ''' <summary>
  179.    ''' Cape Verdean Escudo
  180.    ''' </summary>
  181.    CVE
  182.  
  183.    ''' <summary>
  184.    ''' Czech Koruna
  185.    ''' </summary>
  186.    CZK
  187.  
  188.    ''' <summary>
  189.    ''' Djiboutian Franc
  190.    ''' </summary>
  191.    DJF
  192.  
  193.    ''' <summary>
  194.    ''' Danish Krone
  195.    ''' </summary>
  196.    DKK
  197.  
  198.    ''' <summary>
  199.    ''' Dominican Peso
  200.    ''' </summary>
  201.    DOP
  202.  
  203.    ''' <summary>
  204.    ''' Algerian Dinar
  205.    ''' </summary>
  206.    DZD
  207.  
  208.    ''' <summary>
  209.    ''' Egyptian Pound
  210.    ''' </summary>
  211.    EGP
  212.  
  213.    ''' <summary>
  214.    ''' Ethiopian Birr
  215.    ''' </summary>
  216.    ETB
  217.  
  218.    ''' <summary>
  219.    ''' Eurozone Euro
  220.    ''' </summary>
  221.    EUR
  222.  
  223.    ''' <summary>
  224.    ''' Fijian Dollar
  225.    ''' </summary>
  226.    FJD
  227.  
  228.    ''' <summary>
  229.    ''' Falkland Islands Pound
  230.    ''' </summary>
  231.    FKP
  232.  
  233.    ''' <summary>
  234.    ''' Pound Sterling
  235.    ''' </summary>
  236.    GBP
  237.  
  238.    ''' <summary>
  239.    ''' Georgian Lari
  240.    ''' </summary>
  241.    GEL
  242.  
  243.    ''' <summary>
  244.    ''' Ghanaian Cedi
  245.    ''' </summary>
  246.    GHS
  247.  
  248.    ''' <summary>
  249.    ''' Gibraltar Pound
  250.    ''' </summary>
  251.    GIP
  252.  
  253.    ''' <summary>
  254.    ''' Gambian Dalasi
  255.    ''' </summary>
  256.    GMD
  257.  
  258.    ''' <summary>
  259.    ''' Guinean Franc
  260.    ''' </summary>
  261.    GNF
  262.  
  263.    ''' <summary>
  264.    ''' Guatemalan Quetzal
  265.    ''' </summary>
  266.    GTQ
  267.  
  268.    ''' <summary>
  269.    ''' Guyanaese Dollar
  270.    ''' </summary>
  271.    GYD
  272.  
  273.    ''' <summary>
  274.    ''' Hong Kong Dollar
  275.    ''' </summary>
  276.    HKD
  277.  
  278.    ''' <summary>
  279.    ''' Honduran Lempira
  280.    ''' </summary>
  281.    HNL
  282.  
  283.    ''' <summary>
  284.    ''' Croatian Kuna
  285.    ''' </summary>
  286.    HRK
  287.  
  288.    ''' <summary>
  289.    ''' Haitian Gourde
  290.    ''' </summary>
  291.    HTG
  292.  
  293.    ''' <summary>
  294.    ''' Hungarian Forint
  295.    ''' </summary>
  296.    HUF
  297.  
  298.    ''' <summary>
  299.    ''' Indonesian Rupiah
  300.    ''' </summary>
  301.    IDR
  302.  
  303.    ''' <summary>
  304.    ''' Israeli Shekel
  305.    ''' </summary>
  306.    ILS
  307.  
  308.    ''' <summary>
  309.    ''' Indian Rupee
  310.    ''' </summary>
  311.    INR
  312.  
  313.    ''' <summary>
  314.    ''' Iraqi Dinar
  315.    ''' </summary>
  316.    IQD
  317.  
  318.    ''' <summary>
  319.    ''' Iranian Rial
  320.    ''' </summary>
  321.    IRR
  322.  
  323.    ''' <summary>
  324.    ''' Icelandic Króna
  325.    ''' </summary>
  326.    ISK
  327.  
  328.    ''' <summary>
  329.    ''' Jersey Pound
  330.    ''' </summary>
  331.    JEP
  332.  
  333.    ''' <summary>
  334.    ''' Jamaican Dollar
  335.    ''' </summary>
  336.    JMD
  337.  
  338.    ''' <summary>
  339.    ''' Jordanian Dinar
  340.    ''' </summary>
  341.    JOD
  342.  
  343.    ''' <summary>
  344.    ''' Japanese Yen
  345.    ''' </summary>
  346.    JPY
  347.  
  348.    ''' <summary>
  349.    ''' Kenyan Shilling
  350.    ''' </summary>
  351.    KES
  352.  
  353.    ''' <summary>
  354.    ''' Kyrgystani Som
  355.    ''' </summary>
  356.    KGS
  357.  
  358.    ''' <summary>
  359.    ''' Cambodian Riel
  360.    ''' </summary>
  361.    KHR
  362.  
  363.    ''' <summary>
  364.    ''' Comorian Franc
  365.    ''' </summary>
  366.    KMF
  367.  
  368.    ''' <summary>
  369.    ''' North Korean Won
  370.    ''' </summary>
  371.    KPW
  372.  
  373.    ''' <summary>
  374.    ''' South Korean Won
  375.    ''' </summary>
  376.    KRW
  377.  
  378.    ''' <summary>
  379.    ''' Kuwaiti Dinar
  380.    ''' </summary>
  381.    KWD
  382.  
  383.    ''' <summary>
  384.    ''' Cayman Islands Dollar
  385.    ''' </summary>
  386.    KYD
  387.  
  388.    ''' <summary>
  389.    ''' Kazakhstani Tenge
  390.    ''' </summary>
  391.    KZT
  392.  
  393.    ''' <summary>
  394.    ''' Laotian Kip
  395.    ''' </summary>
  396.    LAK
  397.  
  398.    ''' <summary>
  399.    ''' Lebanese Pound
  400.    ''' </summary>
  401.    LBP
  402.  
  403.    ''' <summary>
  404.    ''' Sri Lankan Rupee
  405.    ''' </summary>
  406.    LKR
  407.  
  408.    ''' <summary>
  409.    ''' Liberian Dollar
  410.    ''' </summary>
  411.    LRD
  412.  
  413.    ''' <summary>
  414.    ''' Lesotho Loti
  415.    ''' </summary>
  416.    LSL
  417.  
  418.    ''' <summary>
  419.    ''' Libyan Dinar
  420.    ''' </summary>
  421.    LYD
  422.  
  423.    ''' <summary>
  424.    ''' Moroccan Dirham
  425.    ''' </summary>
  426.    MAD
  427.  
  428.    ''' <summary>
  429.    ''' Moldovan Leu
  430.    ''' </summary>
  431.    MDL
  432.  
  433.    ''' <summary>
  434.    ''' Malagasy Ariary
  435.    ''' </summary>
  436.    MGA
  437.  
  438.    ''' <summary>
  439.    ''' Macedonian Denar
  440.    ''' </summary>
  441.    MKD
  442.  
  443.    ''' <summary>
  444.    ''' Myanma Kyat
  445.    ''' </summary>
  446.    MMK
  447.  
  448.    ''' <summary>
  449.    ''' Mongolian Tugrik
  450.    ''' </summary>
  451.    MNT
  452.  
  453.    ''' <summary>
  454.    ''' Macanese Pataca
  455.    ''' </summary>
  456.    MOP
  457.  
  458.    ''' <summary>
  459.    ''' Mauritanian Ouguiya
  460.    ''' </summary>
  461.    MRO
  462.  
  463.    ''' <summary>
  464.    ''' Mauritian Rupee
  465.    ''' </summary>
  466.    MUR
  467.  
  468.    ''' <summary>
  469.    ''' Maldivian Rufiyaa
  470.    ''' </summary>
  471.    MVR
  472.  
  473.    ''' <summary>
  474.    ''' Malawian Kwacha
  475.    ''' </summary>
  476.    MWK
  477.  
  478.    ''' <summary>
  479.    ''' Mexican Peso
  480.    ''' </summary>
  481.    MXN
  482.  
  483.    ''' <summary>
  484.    ''' Malaysian Ringgit
  485.    ''' </summary>
  486.    MYR
  487.  
  488.    ''' <summary>
  489.    ''' Mozambican Metical
  490.    ''' </summary>
  491.    MZN
  492.  
  493.    ''' <summary>
  494.    ''' Namibian Dollar
  495.    ''' </summary>
  496.    NAD
  497.  
  498.    ''' <summary>
  499.    ''' Nigerian Naira
  500.    ''' </summary>
  501.    NGN
  502.  
  503.    ''' <summary>
  504.    ''' Nicaraguan Córdoba
  505.    ''' </summary>
  506.    NIO
  507.  
  508.    ''' <summary>
  509.    ''' Norwegian Krone
  510.    ''' </summary>
  511.    NOK
  512.  
  513.    ''' <summary>
  514.    ''' Nepalese Rupee
  515.    ''' </summary>
  516.    NPR
  517.  
  518.    ''' <summary>
  519.    ''' New Zealand Dollar
  520.    ''' </summary>
  521.    NZD
  522.  
  523.    ''' <summary>
  524.    ''' Omani Rial
  525.    ''' </summary>
  526.    OMR
  527.  
  528.    ''' <summary>
  529.    ''' Panamanian Balboa
  530.    ''' </summary>
  531.    PAB
  532.  
  533.    ''' <summary>
  534.    ''' Peruvian Nuevo Sol
  535.    ''' </summary>
  536.    PEN
  537.  
  538.    ''' <summary>
  539.    ''' Papua New Guinean Kina
  540.    ''' </summary>
  541.    PGK
  542.  
  543.    ''' <summary>
  544.    ''' Philippine Peso
  545.    ''' </summary>
  546.    PHP
  547.  
  548.    ''' <summary>
  549.    ''' Pakistani Rupee
  550.    ''' </summary>
  551.    PKR
  552.  
  553.    ''' <summary>
  554.    ''' Polish Zloty
  555.    ''' </summary>
  556.    PLN
  557.  
  558.    ''' <summary>
  559.    ''' Paraguayan Guarani
  560.    ''' </summary>
  561.    PYG
  562.  
  563.    ''' <summary>
  564.    ''' Qatari Rial
  565.    ''' </summary>
  566.    QAR
  567.  
  568.    ''' <summary>
  569.    ''' Romanian Leu
  570.    ''' </summary>
  571.    RON
  572.  
  573.    ''' <summary>
  574.    ''' Serbian Dinar
  575.    ''' </summary>
  576.    RSD
  577.  
  578.    ''' <summary>
  579.    ''' Russian Ruble
  580.    ''' </summary>
  581.    RUB
  582.  
  583.    ''' <summary>
  584.    ''' Rwandan Franc
  585.    ''' </summary>
  586.    RWF
  587.  
  588.    ''' <summary>
  589.    ''' Saudi Riyal
  590.    ''' </summary>
  591.    SAR
  592.  
  593.    ''' <summary>
  594.    ''' Solomon Islands Dollar
  595.    ''' </summary>
  596.    SBD
  597.  
  598.    ''' <summary>
  599.    ''' Seychellois Rupee
  600.    ''' </summary>
  601.    SCR
  602.  
  603.    ''' <summary>
  604.    ''' Sudanese Pound
  605.    ''' </summary>
  606.    SDG
  607.  
  608.    ''' <summary>
  609.    ''' Swedish Krona
  610.    ''' </summary>
  611.    SEK
  612.  
  613.    ''' <summary>
  614.    ''' Singapore Dollar
  615.    ''' </summary>
  616.    SGD
  617.  
  618.    ''' <summary>
  619.    ''' Saint Helena Pound
  620.    ''' </summary>
  621.    SHP
  622.  
  623.    ''' <summary>
  624.    ''' Sierra Leonean Leone
  625.    ''' </summary>
  626.    SLL
  627.  
  628.    ''' <summary>
  629.    ''' Somali Shilling
  630.    ''' </summary>
  631.    SOS
  632.  
  633.    ''' <summary>
  634.    ''' Surinamese Dollar
  635.    ''' </summary>
  636.    SRD
  637.  
  638.    ''' <summary>
  639.    ''' São Tomé and Príncipe Dobra
  640.    ''' </summary>
  641.    STD
  642.  
  643.    ''' <summary>
  644.    ''' Salvadoran Colón
  645.    ''' </summary>
  646.    SVC
  647.  
  648.    ''' <summary>
  649.    ''' Syrian Pound
  650.    ''' </summary>
  651.    SYP
  652.  
  653.    ''' <summary>
  654.    ''' Swazi Lilangeni
  655.    ''' </summary>
  656.    SZL
  657.  
  658.    ''' <summary>
  659.    ''' Thai Baht
  660.    ''' </summary>
  661.    THB
  662.  
  663.    ''' <summary>
  664.    ''' Tajikistani Somoni
  665.    ''' </summary>
  666.    TJS
  667.  
  668.    ''' <summary>
  669.    ''' Turkmenistani Manat
  670.    ''' </summary>
  671.    TMT
  672.  
  673.    ''' <summary>
  674.    ''' Tunisian Dinar
  675.    ''' </summary>
  676.    TND
  677.  
  678.    ''' <summary>
  679.    ''' Tongan Pa&#699;anga
  680.    ''' </summary>
  681.    TOP
  682.  
  683.    ''' <summary>
  684.    ''' Turkish Lira
  685.    ''' </summary>
  686.    [TRY]
  687.  
  688.    ''' <summary>
  689.    ''' Trinidad and Tobago Dollar
  690.    ''' </summary>
  691.    TTD
  692.  
  693.    ''' <summary>
  694.    ''' New Taiwan Dollar
  695.    ''' </summary>
  696.    TWD
  697.  
  698.    ''' <summary>
  699.    ''' Tanzanian Shilling
  700.    ''' </summary>
  701.    TZS
  702.  
  703.    ''' <summary>
  704.    ''' Ukrainian Hryvnia
  705.    ''' </summary>
  706.    UAH
  707.  
  708.    ''' <summary>
  709.    ''' Ugandan Shilling
  710.    ''' </summary>
  711.    UGX
  712.  
  713.    ''' <summary>
  714.    ''' US Dollar
  715.    ''' </summary>
  716.    USD
  717.  
  718.    ''' <summary>
  719.    ''' Uruguayan Peso
  720.    ''' </summary>
  721.    UYU
  722.  
  723.    ''' <summary>
  724.    ''' Uzbekistan Som
  725.    ''' </summary>
  726.    UZS
  727.  
  728.    ''' <summary>
  729.    ''' Venezuelan Bolívar Fuerte
  730.    ''' </summary>
  731.    VEF
  732.  
  733.    ''' <summary>
  734.    ''' Vietnamese Dong
  735.    ''' </summary>
  736.    VND
  737.  
  738.    ''' <summary>
  739.    ''' Vanuatu Vatu
  740.    ''' </summary>
  741.    VUV
  742.  
  743.    ''' <summary>
  744.    ''' Samoan Tala
  745.    ''' </summary>
  746.    WST
  747.  
  748.    ''' <summary>
  749.    ''' CFA Franc BEAC
  750.    ''' </summary>
  751.    XAF
  752.  
  753.    ''' <summary>
  754.    ''' Silver (troy ounce)
  755.    ''' </summary>
  756.    XAG
  757.  
  758.    ''' <summary>
  759.    ''' Gold (troy ounce)
  760.    ''' </summary>
  761.    XAU
  762.  
  763.    ''' <summary>
  764.    ''' East Caribbean Dollar
  765.    ''' </summary>
  766.    XCD
  767.  
  768.    ''' <summary>
  769.    ''' CFA Franc BCEAO
  770.    ''' </summary>
  771.    XOF
  772.  
  773.    ''' <summary>
  774.    ''' CFP Franc
  775.    ''' </summary>
  776.    XPF
  777.  
  778.    ''' <summary>
  779.    ''' Yemeni Rial
  780.    ''' </summary>
  781.    YER
  782.  
  783.    ''' <summary>
  784.    ''' South African Rand
  785.    ''' </summary>
  786.    ZAR
  787.  
  788.    ''' <summary>
  789.    ''' Zambian Kwacha
  790.    ''' </summary>
  791.    ZMW
  792.  
  793.    ''' <summary>
  794.    ''' Zimbabwean Dollar
  795.    ''' </summary>
  796.    ZWL
  797.  
  798. End Enum
  799.  

Y con eso, podemos hacer una función de uso genérico que tome como argumento un valor de la enumeración, usar la API y parsear el documento JSON devuelto para obtener el valor del Bitcoin:

Código
  1. Imports System.Globalization
  2. Imports System.IO
  3. Imports System.Net
  4. Imports System.Runtime.Serialization.Json
  5. Imports System.Text
  6. Imports System.Xml

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Gets the price of 1 Bitcoin in the specified currency.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. ''' <param name="currency">
  7. ''' The currency.
  8. ''' </param>
  9. ''' ----------------------------------------------------------------------------------------------------
  10. ''' <returns>
  11. ''' The resulting price.
  12. ''' </returns>
  13. ''' ----------------------------------------------------------------------------------------------------
  14. ''' <exception cref="HttpListenerException">
  15. ''' The returned Bitcoin rate info is empty due to an unknown error.
  16. ''' </exception>
  17. ''' ----------------------------------------------------------------------------------------------------
  18. <DebuggerStepThrough>
  19. Private Shared Function GetBitcoinPrice(ByVal currency As Currencies) As Decimal
  20.  
  21.    Dim uri As New Uri(String.Format("https://bitpay.com/api/rates/BTC/{0}", currency.ToString()))
  22.    Dim req As WebRequest = WebRequest.Create(uri)
  23.  
  24.    Using res As WebResponse = req.GetResponse(),
  25.          sr As New StreamReader(res.GetResponseStream()),
  26.          xmlReader As XmlDictionaryReader =
  27.              JsonReaderWriterFactory.CreateJsonReader(sr.BaseStream, Encoding.UTF8, New XmlDictionaryReaderQuotas, Nothing)
  28.  
  29.        Dim xml As XElement = XElement.Load(xmlReader)
  30.        If (xml.IsEmpty) Then
  31.            Dim errMsg As String = String.Format("The returned Bitcoin rate info is empty due to an unknown error. ""{0}""", uri.ToString())
  32.            Throw New HttpListenerException(HttpStatusCode.NotFound, errMsg)
  33.        End If
  34.  
  35.        Return Decimal.Parse(xml.<rate>.Value, NumberStyles.Currency, New NumberFormatInfo With {.CurrencyDecimalSeparator = "."})
  36.  
  37.    End Using
  38.  
  39. End Function

Modo de empleo:
Código
  1. Dim price As Decimal = GetBitcoinPrice(Currencies.USD)
  2. Console.WriteLine(price)

Saludos.


« Última modificación: 23 Diciembre 2017, 04:50 am por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.874



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #511 en: 23 Diciembre 2017, 04:28 am »

¿CÓMO OBTENER UNA REFERENCIA A TODOS LOS PROCESOS HIJO DE UN PROCESO?

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Gets the child processes of the source <see cref="Process"/>.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. ''' <param name="p">
  7. ''' The source <see cref="Process"/>.
  8. ''' </param>
  9. ''' ----------------------------------------------------------------------------------------------------
  10. ''' <returns>
  11. ''' A <see cref="IEnumerable(Of Process)"/> containing the child processes.
  12. ''' </returns>
  13. ''' ----------------------------------------------------------------------------------------------------
  14. <DebuggerStepThrough>
  15. Public Sahred Iterator Function GetChildProcesses(ByVal p As Process) As IEnumerable(Of Process)
  16.  
  17.    Dim scope As New ManagementScope("root\CIMV2")p.Id))
  18.    Dim options As New EnumerationOptions With {
  19.        .ReturnImmediately = True,
  20.        .Rewindable = False,
  21.        .DirectRead = True,
  22.        .EnumerateDeep = False
  23.    }
  24.  
  25.    Using mos As New ManagementObjectSearcher(scope, query, options),
  26.          moc As ManagementObjectCollection = mos.Get()
  27.  
  28.        For Each mo As ManagementObject In moc
  29.            Dim value As Object = mo.Properties("ProcessID").Value()
  30.            If (value IsNot Nothing) Then
  31.                Yield Process.GetProcessById(CInt(value))
  32.            End If
  33.        Next
  34.    End Using
  35.  
  36. End Function

Modo de empleo:
Código
  1. Dim mainProcess As Process = Process.GetProcessesByName("explorer").Single()
  2. Dim childProcesses As IEnumerable(Of Process) = GetChildProcesses(mainProcess)
  3.  
  4. For Each p As Process In childProcesses
  5.    Console.WriteLine(p.ProcessName)
  6. Next

Saludos.


« Última modificación: 23 Diciembre 2017, 08:15 am por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.874



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #512 en: 23 Diciembre 2017, 07:52 am »

CÓMO OBTENER EL PRECIO DEL BITCOIN DE UNA CANTIDAD DE CUALQUIER CRIPTOMONEDA EN LA MONEDA QUE QUIERAS

Con el fin de ahorrar la escritura de código, reutilizaremos la enumeración que ya publiqué en este otro post:


( deben copiar y pegar la enumeración "Currencies" junto al código que mostraré a continuación para que funcione. )

En esta ocasión, la API que utilizaremos será: https://coinmarketcap.com/api/, la cual soporta muchas criptomonedas, aunque no muchas divisas.

Primero definiremos una interfáz con nombre ICryptoCurrency, que nos servirá para representar criptomonedas (Bitcoin, Ethereum, Litecoin, etcétera) y sus funcionalidades.

Código
  1. Public Interface ICryptoCurrency
  2.  
  3.    ''' <summary>
  4.    ''' Gets the canonical name of this <see cref="ICryptoCurrency"/>.
  5.    ''' </summary>
  6.    ReadOnly Property Name As String
  7.  
  8.    ''' <summary>
  9.    ''' Gets the symbol of this <see cref="ICryptoCurrency"/>.
  10.    ''' </summary>
  11.    ReadOnly Property Symbol As String
  12.  
  13.    ''' <summary>
  14.    ''' Gets the price equivalency for 1 amount of this <see cref="ICryptoCurrency"/> converted to the specified currency.
  15.    ''' </summary>
  16.    Function GetPrice(ByVal currency As Currencies) As Double
  17.  
  18.    ''' <summary>
  19.    ''' Gets the price equivalency for the specified amount of this <see cref="ICryptoCurrency"/> converted to the specified currency.
  20.    ''' </summary>
  21.    Function GetPrice(ByVal amount As Double, ByVal currency As Currencies) As Double
  22.  
  23.    ''' <summary>
  24.    ''' Asunchronously gets the price equivalency for 1 amount of this <see cref="ICryptoCurrency"/> converted to the specified currency.
  25.    ''' </summary>
  26.    Function GetPriceAsync(ByVal currency As Currencies) As Task(Of Double)
  27.  
  28.    ''' <summary>
  29.    ''' Asynchronously gets the price equivalency for the specified amount of this <see cref="ICryptoCurrency"/> converted to the specified currency.
  30.    ''' </summary>
  31.    Function GetPriceAsync(ByVal amount As Double, ByVal currency As Currencies) As Task(Of Double)
  32.  
  33. End Interface

Seguidamente implementamos las criptomodas que queramos, en este caso el Bitcoin y Ethereum:

( para implementar más criptomonedas solo tienen que copiar y pegar la clase del Bitcoin o del Ethereum, modificar el nombre y el símbolo para la nueva criptomoneda, y lo demás dejarlo todo exactamente igual... )

Código
  1. ''' <summary>
  2. ''' Represents the Bitcoin (symbol: BTC) cryptocurrency.
  3. ''' </summary>
  4. Public Class Bitcoin : Implements ICryptoCurrency
  5.  
  6.    Public Sub New()
  7.    End Sub
  8.  
  9.    Public ReadOnly Property Name As String = "Bitcoin" Implements ICryptoCurrency.Name
  10.  
  11.    Public ReadOnly Property Symbol As String = "BTC" Implements ICryptoCurrency.Symbol
  12.  
  13.    ''' <summary>
  14.    ''' Gets the price for 1 Bitcoins converted to the specified currency.
  15.    ''' </summary>
  16.    Public Overridable Function GetPrice(ByVal currency As Currencies) As Double Implements ICryptoCurrency.GetPrice
  17.        Return CryptoCurrencyUtil.GetCryptoCurrencyPrice(Me, 1, currency)
  18.    End Function
  19.  
  20.    ''' <summary>
  21.    ''' Gets the price for the specified amount of Bitcoins converted to the specified currency.
  22.    ''' </summary>
  23.    Public Overridable Function GetPrice(ByVal amount As Double, ByVal currency As Currencies) As Double Implements ICryptoCurrency.GetPrice
  24.        Return CryptoCurrencyUtil.GetCryptoCurrencyPrice(Me, amount, currency)
  25.    End Function
  26.  
  27.    ''' <summary>
  28.    ''' Asynchronously gets the price for 1 Bitcoins converted to the specified currency.
  29.    ''' </summary>
  30.    Public Overridable Async Function GetPriceAsync(ByVal currency As Currencies) As Task(Of Double) Implements ICryptoCurrency.GetPriceAsync
  31.        Return Await CryptoCurrencyUtil.GetCryptoCurrencyPriceAsync(Me, 1, currency)
  32.    End Function
  33.  
  34.    ''' <summary>
  35.    ''' Asynchronously gets the price for the specified amount of Bitcoins converted to the specified currency.
  36.    ''' </summary>
  37.    Public Overridable Async Function GetPriceAsync(ByVal amount As Double, ByVal currency As Currencies) As Task(Of Double) Implements ICryptoCurrency.GetPriceAsync
  38.        Return Await CryptoCurrencyUtil.GetCryptoCurrencyPriceAsync(Me, amount, currency)
  39.    End Function
  40.  
  41. End Class

Código
  1. ''' <summary>
  2. ''' Represents the Ethereum (symbol: ETH) cryptocurrency.
  3. ''' </summary>
  4. Public Class Ethereum : Implements ICryptoCurrency
  5.  
  6.    Public Sub New()
  7.    End Sub
  8.  
  9.    Public ReadOnly Property Name As String = "Ethereum" Implements ICryptoCurrency.Name
  10.  
  11.    Public ReadOnly Property Symbol As String = "ETH" Implements ICryptoCurrency.Symbol
  12.  
  13.    ''' <summary>
  14.    ''' Gets the price for 1 Ethereums converted to the specified currency.
  15.    ''' </summary>
  16.    Public Overridable Function GetPrice(ByVal currency As Currencies) As Double Implements ICryptoCurrency.GetPrice
  17.        Return CryptoCurrencyUtil.GetCryptoCurrencyPrice(Me, 1, currency)
  18.    End Function
  19.  
  20.    ''' <summary>
  21.    ''' Gets the price for the specified amount of Ethereums converted to the specified currency.
  22.    ''' </summary>
  23.    Public Overridable Function GetPrice(ByVal amount As Double, ByVal currency As Currencies) As Double Implements ICryptoCurrency.GetPrice
  24.        Return CryptoCurrencyUtil.GetCryptoCurrencyPrice(Me, amount, currency)
  25.    End Function
  26.  
  27.    ''' <summary>
  28.    ''' Asynchronously gets the price for 1 Ethereums converted to the specified currency.
  29.    ''' </summary>
  30.    Public Overridable Async Function GetPriceAsync(ByVal currency As Currencies) As Task(Of Double) Implements ICryptoCurrency.GetPriceAsync
  31.        Return Await CryptoCurrencyUtil.GetCryptoCurrencyPriceAsync(Me, 1, currency)
  32.    End Function
  33.  
  34.    ''' <summary>
  35.    ''' Asynchronously gets the price for the specified amount of Ethereums converted to the specified currency.
  36.    ''' </summary>
  37.    Public Overridable Async Function GetPriceAsync(ByVal amount As Double, ByVal currency As Currencies) As Task(Of Double) Implements ICryptoCurrency.GetPriceAsync
  38.        Return Await CryptoCurrencyUtil.GetCryptoCurrencyPriceAsync(Me, amount, currency)
  39.    End Function
  40.  
  41. End Class

Por último, creamos una clase con nombre CryptoCurrencyUtil en la que declararemos las funciones GetCryptoCurrencyPrice y GetCryptoCurrencyPriceAsync:

Código
  1. Public NotInheritable Class CryptoCurrencyUtil
  2.  
  3.    Private Sub New()
  4.    End Sub
  5.  
  6.    ''' ----------------------------------------------------------------------------------------------------
  7.    ''' <summary>
  8.    ''' Gets the price of the specified cryptocurrency converted to the target currency.
  9.    ''' </summary>
  10.    ''' ----------------------------------------------------------------------------------------------------
  11.    ''' <param name="cryptoCurrency">
  12.    ''' The source <see cref="ICryptoCurrency"/>.
  13.    ''' </param>
  14.    '''
  15.    ''' <param name="amount">
  16.    ''' The amount value of the source cryptocurrency.
  17.    ''' </param>
  18.    '''
  19.    ''' <param name="currency">
  20.    ''' The target currency.
  21.    ''' </param>
  22.    ''' ----------------------------------------------------------------------------------------------------
  23.    ''' <returns>
  24.    ''' The resulting price.
  25.    ''' </returns>
  26.    ''' ----------------------------------------------------------------------------------------------------
  27.    ''' <exception cref="NotImplementedException">
  28.    ''' The specified currency is not supported by this API.
  29.    ''' </exception>
  30.    '''
  31.    ''' <exception cref="HttpListenerException">
  32.    ''' The requested cryptocurrency rate info is empty due to an unknown error.
  33.    ''' </exception>
  34.    '''
  35.    ''' <exception cref="FormatException">
  36.    ''' Element name '{0}' not found. Unknown error reason.
  37.    ''' </exception>
  38.    ''' ----------------------------------------------------------------------------------------------------
  39.    <DebuggerStepThrough>
  40.    Public Shared Function GetCryptoCurrencyPrice(ByVal cryptoCurrency As ICryptoCurrency, ByVal amount As Double, ByVal currency As Currencies) As Double
  41.  
  42.        Dim t As New Task(Of Double)(
  43.            Function() As Double
  44.                Return CryptoCurrencyUtil.GetCryptoCurrencyPriceAsync(cryptoCurrency, amount, currency).Result
  45.            End Function)
  46.  
  47.        t.Start()
  48.        t.Wait()
  49.  
  50.        Return t.Result
  51.  
  52.    End Function
  53.  
  54.    ''' ----------------------------------------------------------------------------------------------------
  55.    ''' <summary>
  56.    ''' Asynchronously gets the price of the specified cryptocurrency converted to the target currency.
  57.    ''' </summary>
  58.    ''' ----------------------------------------------------------------------------------------------------
  59.    ''' <param name="cryptoCurrency">
  60.    ''' The source <see cref="ICryptoCurrency"/>.
  61.    ''' </param>
  62.    '''
  63.    ''' <param name="amount">
  64.    ''' The amount value of the source cryptocurrency.
  65.    ''' </param>
  66.    '''
  67.    ''' <param name="currency">
  68.    ''' The target currency.
  69.    ''' </param>
  70.    ''' ----------------------------------------------------------------------------------------------------
  71.    ''' <returns>
  72.    ''' The resulting price.
  73.    ''' </returns>
  74.    ''' ----------------------------------------------------------------------------------------------------
  75.    ''' <exception cref="NotImplementedException">
  76.    ''' The specified currency is not supported by this API.
  77.    ''' </exception>
  78.    '''
  79.    ''' <exception cref="HttpListenerException">
  80.    ''' The requested cryptocurrency rate info is empty due to an unknown error.
  81.    ''' </exception>
  82.    '''
  83.    ''' <exception cref="FormatException">
  84.    ''' Element name '{0}' not found. Unknown error reason.
  85.    ''' </exception>
  86.    ''' ----------------------------------------------------------------------------------------------------
  87.    <DebuggerStepThrough>
  88.    Public Shared Async Function GetCryptoCurrencyPriceAsync(ByVal cryptoCurrency As ICryptoCurrency, ByVal amount As Double, ByVal currency As Currencies) As Task(Of Double)
  89.  
  90.        Dim validCurrencies As String() =
  91.        {
  92.            "AUD", "BRL", "CAD", "CHF", "CLP", "CNY", "CZK", "DKK",
  93.            "EUR", "GBP", "HKD", "HUF", "IDR", "ILS", "INR", "JPY",
  94.            "KRW", "MXN", "MYR", "NOK", "NZD", "PHP", "PKR", "PLN",
  95.            "RUB", "SEK", "SGD", "THB", "TRY", "TWD", "USD", "ZAR"
  96.        }
  97.  
  98.        If Not validCurrencies.Contains(currency.ToString().ToUpper()) Then
  99.            Throw New NotImplementedException("The specified currency is not supported by this API.",
  100.                                              New ArgumentException("", paramName:="currency"))
  101.        End If
  102.  
  103.        Dim uri As New Uri(String.Format("https://api.coinmarketcap.com/v1/ticker/{0}/?convert={1}",
  104.                                         cryptoCurrency.Name, currency.ToString()))
  105.  
  106.        Dim req As WebRequest = WebRequest.Create(uri)
  107.        Using res As WebResponse = Await req.GetResponseAsync(),
  108.                  SR As New StreamReader(res.GetResponseStream()),
  109.                  XmlReader As XmlDictionaryReader =
  110.                      JsonReaderWriterFactory.CreateJsonReader(SR.BaseStream, Encoding.UTF8, New XmlDictionaryReaderQuotas, Nothing)
  111.  
  112.            Dim xml As XElement = XElement.Load(XmlReader)
  113.            If (xml.IsEmpty) Then
  114.                Dim errMsg As String = String.Format("The requested cryptocurrency rate info is empty due to an unknown error. ""{0}""", uri.ToString())
  115.                Throw New HttpListenerException(HttpStatusCode.NotFound, errMsg)
  116.            End If
  117.  
  118.            Dim elementName As String = String.Format("price_{0}", currency.ToString().ToLower())
  119.            Dim element As XElement = xml.Element("item").Element(elementName)
  120.            If (element Is Nothing) Then
  121.                Throw New FormatException(String.Format("Element name '{0}' not found. Unknown error reason.", elementName))
  122.            End If
  123.  
  124.            Dim price As Double = Double.Parse(element.Value, NumberStyles.Currency, New NumberFormatInfo With {.CurrencyDecimalSeparator = "."})
  125.            Select Case amount
  126.                Case Is = 1
  127.                    Return price
  128.                Case Is < 1
  129.                    Return (price / (1 / amount))
  130.                Case Else ' > 1
  131.                    Return (price * amount)
  132.            End Select
  133.  
  134.        End Using
  135.  
  136.    End Function
  137.  
  138. End Class

LISTO.

Modo de empleo para obtener la equivalencia de 1 bitcoins a dólares:
Código
  1. Dim btc As New Bitcoin()
  2. Dim price As Double = btc.GetPrice(Currencies.USD)
  3. Debug.WriteLine(String.Format("{0:C}", price, CultureInfo.CurrentCulture))

O tambien:
Código
  1. Dim cryptoCurrency As ICryptoCurrency = New Bitcoin()
  2. Dim price As Double = CryptoCurrencyUtil.GetCryptoCurrencyPrice(cryptoCurrency, 1, Currencies.USD)
  3. Debug.WriteLine(String.Format("{0:C}", price, CultureInfo.CurrentCulture))

Modo de empleo para obtener la equivalencia de 5.86 ethereums a dólares:
Código
  1. Dim eth As New Ethereum()
  2. Dim price As Double = eth.GetPrice(5.86, Currencies.USD)
  3. Debug.WriteLine(String.Format("{0:C}", price, CultureInfo.CurrentCulture))

O tambien:
Código
  1. Dim cryptoCurrency As ICryptoCurrency = New Ethereum()
  2. Dim price As Double = CryptoCurrencyUtil.GetCryptoCurrencyPrice(cryptoCurrency, 5.86, Currencies.USD)
  3. Debug.WriteLine(String.Format("{0:C}", price, CultureInfo.CurrentCulture))




EDITO:
Se me olvidaba comentar... que por supuesto el nombre de la criptomoneda debe ser soportado por la API en cuestión... o mejor dicho el identificador, el campo "id" (no el campo "name"), así que quizás quieran adaptar las representaciones de criptomonedas para añadirle una propiedad con nombre "id" para ese propósito...

Aquí pueden ver todos los campos que devuelve el documento JSON:

Nótese que en el caso de Bitcoin y Ethereum el nombre es igual que el identificador para la API, por eso lo he simplificado y no he implimentado el campo "Id", pero no todos los nombres son iguales que los identificadores, véase un ejemplo:
...
id   "bitcoin-cash"
name   "Bitcoin Cash"
...

Saludos.
« Última modificación: 23 Diciembre 2017, 08:16 am por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.874



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #513 en: 5 Enero 2018, 09:22 am »

Como obtener el uso de porcentaje de CPU de un proceso

Código
  1.    ''' ----------------------------------------------------------------------------------------------------
  2.    ''' <summary>
  3.    ''' Gets the CPU percentage usage for the specified <see cref="Process"/>.
  4.    ''' </summary>
  5.    ''' ----------------------------------------------------------------------------------------------------
  6.    ''' <returns>
  7.    ''' The resulting CPU percentage usage for the specified <see cref="Process"/>.
  8.    ''' </returns>
  9.    ''' ----------------------------------------------------------------------------------------------------
  10.    <DebuggerStepThrough>
  11.    Public Shared Function GetProcessCPUPercentUsage(ByVal p As Process) As Double
  12.  
  13.        Using perf As New PerformanceCounter("Process", "% Processor Time", p.ProcessName, True)
  14.            perf.NextValue()
  15.            Thread.Sleep(TimeSpan.FromMilliseconds(250)) ' Recommended value: 1 second
  16.            Return (Math.Round(perf.NextValue() / Environment.ProcessorCount, 1))
  17.        End Using
  18.  
  19.    End Function
  20.  

primero hay que activar el uso de los contadores de rendimiento en el archivo de manifiesto de nuestra aplicación:
Código
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <configuration>
  3. ...
  4.  
  5.  <system.net>
  6.    <settings>
  7.      <performanceCounters enabled="true"/>
  8.    </settings>
  9.  </system.net>
  10.  
  11. ...
  12. </configuration>

Modo de empleo:
Código
  1. Do While True
  2.  
  3.    Using p As Process = Process.GetProcessesByName("NOMBRE DEL PROCESO").SingleOrDefault()
  4.        Dim str As String =
  5.            String.Format("Process Name: {0}; CPU Usage: {1}%",
  6.                          p.ProcessName, GetProcessCPUPercentUsage(p))
  7.  
  8.        Console.WriteLine(str)
  9.    End Using
  10.  
  11. Loop
« Última modificación: 5 Enero 2018, 09:25 am por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.874



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #514 en: 2 Febrero 2018, 10:51 am »

¿Cómo hacer WordWrapping a un String?.

Teniendo un string, y una longitud máxima en pixels, esta función/extensión de método nos servirá para hacerle wordwrap a dicho string, y así ajustar las palabrás al límite de longitud especificado.

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Wraps words of the source <see cref="String"/> to the
  4. ''' beginning of the next line when necessary to fit the specified pixel width.
  5. ''' </summary>
  6. ''' ----------------------------------------------------------------------------------------------------
  7. ''' <remarks>
  8. ''' Credits to @undejavue solution: <see href="https://stackoverflow.com/a/36803501/1248295"/>
  9. ''' </remarks>
  10. ''' ----------------------------------------------------------------------------------------------------
  11. ''' <param name="sender">
  12. ''' The source <see cref="String"/>.
  13. ''' </param>
  14. '''
  15. ''' <param name="maxWidth">
  16. ''' The maximum width, in pixels.
  17. ''' </param>
  18. '''
  19. ''' <param name="font">
  20. ''' The text font.
  21. ''' </param>
  22. ''' ----------------------------------------------------------------------------------------------------
  23. ''' <returns>
  24. ''' The resulting string.
  25. ''' </returns>
  26. ''' ----------------------------------------------------------------------------------------------------
  27. <DebuggerStepThrough>
  28. <Extension>
  29. <EditorBrowsable(EditorBrowsableState.Always)>
  30. Public Function WordWrap(ByVal sender As String, ByVal maxWidth As Integer, ByVal font As Font) As String
  31.  
  32.    Dim sourceLines() As String = sender.Split({" "c}, StringSplitOptions.None)
  33.    Dim wrappedString As New Global.System.Text.StringBuilder()
  34.    Dim actualLine As New Global.System.Text.StringBuilder()
  35.    Dim actualWidth As Double = 0
  36.  
  37.    For Each line As String In sourceLines
  38.        Dim lineWidth As Integer = TextRenderer.MeasureText(line & " ", font).Width
  39.        actualWidth += lineWidth
  40.  
  41.        If (actualWidth > maxWidth) Then
  42.            wrappedString.AppendLine(actualLine.ToString())
  43.            actualLine.Clear()
  44.            actualWidth = lineWidth
  45.        End If
  46.  
  47.        actualLine.Append(line & " ")
  48.    Next line
  49.  
  50.    If (actualLine.Length > 0) Then
  51.        wrappedString.AppendLine(actualLine.ToString())
  52.    End If
  53.  
  54.    Return wrappedString.ToString()
  55.  
  56. End Function

Ejemplo de uso:

Código
  1. Dim tb As New TextBox With {
  2.        .Multiline = True,
  3.        .ScrollBars = ScrollBars.Both,
  4.        .WordWrap = False,
  5.        .Size = New Drawing.Size(width:=250, height:=200)
  6.    }
  7.  
  8. Dim text As String = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
  9. Dim wordWrappedText As String = text.WordWrap(tb.Width, tb.Font)
  10.  
  11. Me.Controls.Add(tb)
  12. tb.Text = wordWrappedText
  13.  
  14. Console.WriteLine(wordWrappedText)


« Última modificación: 2 Febrero 2018, 10:55 am por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.874



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #515 en: 2 Febrero 2018, 11:02 am »

¿Cómo implementar funcionalidades de pausado y reanudado en un BackgroundWorker, y funcionalidades de iniciar y cancelar síncronas?.

Les presento el componente 'ElektroBackgroundWorker', es un BackgroundWorker extendido al que le añadí las funcionalidades ya mencionadas. Su modo de empleo es practicamente idéntico que un BackgroundWorker, tan solo mencionar que el equivalente al método 'BackgroundWorker.RunWorkerAsync()' es 'ElektroBackgroundWorker.RunAsync()'.

Código
  1. ' ***********************************************************************
  2. ' Author   : Elektro
  3. ' Modified : 02-February-2018
  4. ' ***********************************************************************
  5.  
  6. #Region " Option Statements "
  7.  
  8. Option Strict On
  9. Option Explicit On
  10. Option Infer Off
  11.  
  12. #End Region
  13.  
  14. #Region " Imports "
  15.  
  16. ' Imports ElektroKit.Core.Threading.Enums
  17.  
  18. Imports System.ComponentModel
  19. Imports System.Drawing
  20. Imports System.Threading
  21.  
  22. #End Region
  23.  
  24. #Region " ElektroBackgroundWorker "
  25.  
  26. ' Namespace Threading.Types
  27.  
  28.    ''' ----------------------------------------------------------------------------------------------------
  29.    ''' <summary>
  30.    ''' A extended <see cref="BackgroundWorker"/> component
  31.    ''' with synchronous (blocking) run/cancellation support,
  32.    ''' and asynchronous pause/resume features.
  33.    ''' </summary>
  34.    ''' ----------------------------------------------------------------------------------------------------
  35.    ''' <example> This is a code example.
  36.    ''' <code>
  37.    ''' Friend WithEvents Worker As ElektroBackgroundWorker
  38.    '''
  39.    ''' Private Sub Button_Run_Click() Handles Button_Run.Click
  40.    '''
  41.    '''     If (Me.Worker IsNot Nothing) Then
  42.    '''
  43.    '''         Select Case Me.Worker.State
  44.    '''             Case ElektroBackgroundWorkerState.Running, ElektroBackgroundWorkerState.Paused
  45.    '''                 Me.Worker.Cancel()
  46.    '''             Case Else
  47.    '''                 ' Do Nothing.
  48.    '''         End Select
  49.    '''
  50.    '''     End If
  51.    '''
  52.    '''     Me.Worker = New ElektroBackgroundWorker
  53.    '''     Me.Worker.RunAsync()
  54.    '''
  55.    ''' End Sub
  56.    '''
  57.    ''' Private Sub Button_Pause_Click() Handles Button_Pause.Click
  58.    '''     Me.Worker.RequestPause()
  59.    ''' End Sub
  60.    '''
  61.    ''' Private Sub Button_Resume_Click() Handles Button_Resume.Click
  62.    '''     Me.Worker.Resume()
  63.    ''' End Sub
  64.    '''
  65.    ''' Private Sub Button_Cancel_Click() Handles Button_Cancel.Click
  66.    '''     Me.Worker.Cancel()
  67.    ''' End Sub
  68.    '''
  69.    ''' ''' ----------------------------------------------------------------------------------------------------
  70.    ''' ''' &lt;summary&gt;
  71.    ''' ''' Handles the &lt;see cref="ElektroBackgroundWorker.DoWork"/&gt; event of the &lt;see cref="Worker"/&gt; instance.
  72.    ''' ''' &lt;/summary&gt;
  73.    ''' ''' ----------------------------------------------------------------------------------------------------
  74.    ''' ''' &lt;param name="sender"&gt;
  75.    ''' ''' The source of the event.
  76.    ''' ''' &lt;/param&gt;
  77.    ''' '''
  78.    ''' ''' &lt;param name="e"&gt;
  79.    ''' ''' The &lt;see cref="DoWorkEventArgs"/&gt; instance containing the event data.
  80.    ''' ''' &lt;/param&gt;
  81.    ''' ''' ----------------------------------------------------------------------------------------------------
  82.    ''' &lt;DebuggerStepperBoundary&gt;
  83.    ''' Private Sub Worker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) _
  84.    ''' Handles Worker.DoWork
  85.    '''
  86.    '''     Dim progress As Integer
  87.    '''
  88.    '''     Dim lock As Object = ""
  89.    '''     SyncLock lock
  90.    '''
  91.    '''         For i As Integer = 0 To 100
  92.    '''             If (Me.Worker.CancellationPending) Then ' Cancel the background operation.
  93.    '''                 e.Cancel = True
  94.    '''                 Exit For
  95.    '''
  96.    '''             Else
  97.    '''                 If (Me.Worker.PausePending) Then ' Pause the background operation.
  98.    '''                     Me.Worker.Pause() ' Blocking pause call.
  99.    '''                 End If
  100.    '''
  101.    '''                 Me.DoSomething()
  102.    '''
  103.    '''                 If Me.Worker.WorkerReportsProgress Then
  104.    '''                     progress = i
  105.    '''                     Me.Worker.ReportProgress(progress)
  106.    '''                 End If
  107.    '''
  108.    '''             End If
  109.    '''
  110.    '''         Next i
  111.    '''
  112.    '''     End SyncLock
  113.    '''
  114.    '''     If (Me.Worker.WorkerReportsProgress) AndAlso Not (Me.Worker.CancellationPending) AndAlso (progress &lt; 100) Then
  115.    '''         Me.Worker.ReportProgress(percentProgress:=100)
  116.    '''     End If
  117.    '''
  118.    ''' End Sub
  119.    '''
  120.    ''' ''' ----------------------------------------------------------------------------------------------------
  121.    ''' ''' &lt;summary&gt;
  122.    ''' ''' Handles the &lt;see cref="ElektroBackgroundWorker.ProgressChanged"/&gt; event of the &lt;see cref="Worker"/&gt; instance.
  123.    ''' ''' &lt;/summary&gt;
  124.    ''' ''' ----------------------------------------------------------------------------------------------------
  125.    ''' ''' &lt;param name="sender"&gt;
  126.    ''' ''' The source of the event.
  127.    ''' ''' &lt;/param&gt;
  128.    ''' '''
  129.    ''' ''' &lt;param name="e"&gt;
  130.    ''' ''' The &lt;see cref="ProgressChangedEventArgs"/&gt; instance containing the event data.
  131.    ''' ''' &lt;/param&gt;
  132.    ''' ''' ----------------------------------------------------------------------------------------------------
  133.    ''' &lt;DebuggerStepperBoundary&gt;
  134.    ''' Private Sub Worker_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) _
  135.    ''' Handles Worker.ProgressChanged
  136.    '''
  137.    '''     Console.WriteLine(String.Format("Background Work Progress: {00}%", e.ProgressPercentage))
  138.    '''
  139.    ''' End Sub
  140.    '''
  141.    ''' ''' ----------------------------------------------------------------------------------------------------
  142.    ''' ''' &lt;summary&gt;
  143.    ''' ''' Handles the &lt;see cref="ElektroBackgroundWorker.RunWorkerCompleted"/&gt; event of the &lt;see cref="Worker"/&gt; instance.
  144.    ''' ''' &lt;/summary&gt;
  145.    ''' ''' ----------------------------------------------------------------------------------------------------
  146.    ''' ''' &lt;param name="sender"&gt;
  147.    ''' ''' The source of the event.
  148.    ''' ''' &lt;/param&gt;
  149.    ''' '''
  150.    ''' ''' &lt;param name="e"&gt;
  151.    ''' ''' The &lt;see cref="RunWorkerCompletedEventArgs"/&gt; instance containing the event data.
  152.    ''' ''' &lt;/param&gt;
  153.    ''' ''' ----------------------------------------------------------------------------------------------------
  154.    ''' &lt;DebuggerStepperBoundary&gt;
  155.    ''' Private Sub Worker_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) _
  156.    ''' Handles Worker.RunWorkerCompleted
  157.    '''
  158.    '''     If (e.Cancelled) Then
  159.    '''         Debug.WriteLine("Background work cancelled.")
  160.    '''
  161.    '''     ElseIf (e.Error IsNot Nothing) Then
  162.    '''         Debug.WriteLine("Background work error.")
  163.    '''
  164.    '''     Else
  165.    '''         Debug.WriteLine("Background work done.")
  166.    '''
  167.    '''     End If
  168.    '''
  169.    '''     Console.WriteLine(String.Format("State: {0}", Me.Worker.State.ToString()))
  170.    '''
  171.    ''' End Sub
  172.    '''
  173.    ''' &lt;DebuggerStepperBoundary&gt;
  174.    ''' Private Sub DoSomething()
  175.    '''     Thread.Sleep(TimeSpan.FromSeconds(1))
  176.    ''' End Sub
  177.    ''' </code>
  178.    ''' </example>
  179.    ''' ----------------------------------------------------------------------------------------------------
  180.    ''' <seealso cref="BackgroundWorker" />
  181.    ''' ----------------------------------------------------------------------------------------------------
  182.    <DisplayName("ElektroBackgroundWorker")>
  183.    <Description("A extended BackgroundWorker component, with synchronous (blocking) run/cancellation support, and asynchronous pause/resume features.")>
  184.    <DesignTimeVisible(True)>
  185.    <DesignerCategory("Component")>
  186.    <ToolboxBitmap(GetType(Component), "Component.bmp")>
  187.    <ToolboxItemFilter("System.Windows.Forms", ToolboxItemFilterType.Require)>
  188.    <DefaultEvent("DoWork")>
  189.    Public Class ElektroBackgroundWorker : Inherits BackgroundWorker
  190.  
  191. #Region " Private Fields "
  192.  
  193.        ''' ----------------------------------------------------------------------------------------------------
  194.        ''' <summary>
  195.        ''' A <see cref="ManualResetEvent"/> that serves to handle synchronous operations (Run, Cancel, Pause, Resume).
  196.        ''' </summary>
  197.        ''' ----------------------------------------------------------------------------------------------------
  198.        Protected ReadOnly mreSync As ManualResetEvent
  199.  
  200.        ''' ----------------------------------------------------------------------------------------------------
  201.        ''' <summary>
  202.        ''' A <see cref="ManualResetEvent"/> that serves to handle asynchronous operations (RunAsync, CancelAsync, RequestPause).
  203.        ''' </summary>
  204.        ''' ----------------------------------------------------------------------------------------------------
  205.        Protected ReadOnly mreAsync As ManualResetEvent
  206.  
  207.        ''' ----------------------------------------------------------------------------------------------------
  208.        ''' <summary>
  209.        ''' Indicates whether the <see cref="BackGroundworker"/> has been initiated in synchronous mode.
  210.        ''' </summary>
  211.        ''' ----------------------------------------------------------------------------------------------------
  212.        Protected isRunSync As Boolean
  213.  
  214.        ''' ----------------------------------------------------------------------------------------------------
  215.        ''' <summary>
  216.        ''' Indicates whether a synchronous cancellation operation is requested.
  217.        ''' </summary>
  218.        ''' ----------------------------------------------------------------------------------------------------
  219.        Protected isCancelSyncRequested As Boolean
  220.  
  221.        ''' ----------------------------------------------------------------------------------------------------
  222.        ''' <summary>
  223.        ''' Indicates whether a (asynchronous) pause operation is requested.
  224.        ''' </summary>
  225.        ''' ----------------------------------------------------------------------------------------------------
  226.        Protected isPauseRequested As Boolean
  227.  
  228. #End Region
  229.  
  230. #Region " Properties "
  231.  
  232.        ''' ----------------------------------------------------------------------------------------------------
  233.        ''' <summary>
  234.        ''' Gets a value indicating whether the <see cref="ElektroBackgroundWorker"/> can report progress updates.
  235.        ''' </summary>
  236.        ''' ----------------------------------------------------------------------------------------------------
  237.        ''' <value>
  238.        ''' <see langword="True"/> if can report progress updates; otherwise, <see langword="False"/>.
  239.        ''' </value>
  240.        ''' ----------------------------------------------------------------------------------------------------
  241.        <Browsable(False)>
  242.        <EditorBrowsable(EditorBrowsableState.Always)>
  243.        <Description("A value indicating whether the ElektroBackgroundWorker can report progress updates.")>
  244.        Public Overloads ReadOnly Property WorkerReportsProgress As Boolean
  245.            Get
  246.                Return MyBase.WorkerReportsProgress
  247.            End Get
  248.        End Property
  249.  
  250.        ''' ----------------------------------------------------------------------------------------------------
  251.        ''' <summary>
  252.        ''' Gets a value indicating whether the <see cref="ElektroBackgroundWorker"/> supports asynchronous cancellation.
  253.        ''' </summary>
  254.        ''' ----------------------------------------------------------------------------------------------------
  255.        ''' <value>
  256.        ''' <see langword="True"/> if supports asynchronous cancellation; otherwise, <see langword="False"/>.
  257.        ''' </value>
  258.        ''' ----------------------------------------------------------------------------------------------------
  259.        <Browsable(False)>
  260.        <EditorBrowsable(EditorBrowsableState.Always)>
  261.        <Description("A value indicating whether the ElektroBackgroundWorker supports asynchronous cancellation.")>
  262.        Public Overloads ReadOnly Property WorkerSupportsCancellation As Boolean
  263.            Get
  264.                Return MyBase.WorkerSupportsCancellation
  265.            End Get
  266.        End Property
  267.  
  268.        ''' ----------------------------------------------------------------------------------------------------
  269.        ''' <summary>
  270.        ''' Gets the current state of a pending background operation.
  271.        ''' </summary>
  272.        ''' ----------------------------------------------------------------------------------------------------
  273.        ''' <value>
  274.        ''' The current state of a pending background operation.
  275.        ''' </value>
  276.        ''' ----------------------------------------------------------------------------------------------------
  277.        <Browsable(False)>
  278.        <EditorBrowsable(EditorBrowsableState.Always)>
  279.        <Description("The current state of a pending background operation.")>
  280.        Public ReadOnly Property State As ElektroBackgroundWorkerState
  281.            <DebuggerStepThrough>
  282.            Get
  283.                Return Me.stateB
  284.            End Get
  285.        End Property
  286.        ''' ----------------------------------------------------------------------------------------------------
  287.        ''' <summary>
  288.        ''' ( Backing Field )
  289.        ''' The current state of a pending background operation.
  290.        ''' </summary>
  291.        ''' ----------------------------------------------------------------------------------------------------
  292.        Private stateB As ElektroBackgroundWorkerState = ElektroBackgroundWorkerState.Stopped
  293.  
  294.        ''' ----------------------------------------------------------------------------------------------------
  295.        ''' <summary>
  296.        ''' Gets a value indicating whether the application has requested pause of a background operation.
  297.        ''' </summary>
  298.        ''' ----------------------------------------------------------------------------------------------------
  299.        ''' <value>
  300.        ''' <see langword="True"/> if the application has requested pause of a background operation;
  301.        ''' otherwise, false.
  302.        ''' </value>
  303.        ''' ----------------------------------------------------------------------------------------------------
  304.        <Browsable(False)>
  305.        <EditorBrowsable(EditorBrowsableState.Always)>
  306.        <Description("A value indicating whether the application has requested pause of a background operation.")>
  307.        Public ReadOnly Property PausePending As Boolean
  308.            Get
  309.                Return Me.isPauseRequested
  310.            End Get
  311.        End Property
  312.  
  313. #End Region
  314.  
  315. #Region " Constructors "
  316.  
  317.        ''' ----------------------------------------------------------------------------------------------------
  318.        ''' <summary>
  319.        ''' Initializes a new instance of the <see cref="ElektroBackgroundWorker"/> class.
  320.        ''' </summary>
  321.        ''' ----------------------------------------------------------------------------------------------------
  322.        <DebuggerNonUserCode>
  323.        Public Sub New()
  324.            Me.mreSync = New ManualResetEvent(initialState:=False)
  325.            Me.mreAsync = New ManualResetEvent(initialState:=True)
  326.        End Sub
  327.  
  328. #End Region
  329.  
  330. #Region " Public Methods "
  331.  
  332.        ''' ----------------------------------------------------------------------------------------------------
  333.        ''' <summary>
  334.        ''' Starts execution of a background operation.
  335.        ''' <para></para>
  336.        ''' It blocks the caller thread until the background work is done.
  337.        ''' </summary>
  338.        ''' ----------------------------------------------------------------------------------------------------
  339.        ''' <exception cref="InvalidOperationException">
  340.        ''' In order to run the BackgroundWorker, the background operation must be stopped or completed.
  341.        ''' </exception>
  342.        ''' ----------------------------------------------------------------------------------------------------
  343.        <DebuggerStepThrough>
  344.        Public Overridable Sub Run()
  345.  
  346.            If (Me Is Nothing) Then
  347.                Throw New ObjectDisposedException(objectName:="Me")
  348.  
  349.            Else
  350.                Select Case Me.stateB
  351.  
  352.                    Case ElektroBackgroundWorkerState.Stopped, ElektroBackgroundWorkerState.Completed
  353.                        Me.isRunSync = True
  354.                        MyBase.WorkerReportsProgress = False
  355.                        MyBase.WorkerSupportsCancellation = False
  356.                        MyBase.RunWorkerAsync()
  357.                        Me.stateB = ElektroBackgroundWorkerState.Running
  358.                        Me.mreSync.WaitOne()
  359.  
  360.                    Case Else
  361.                        Throw New InvalidOperationException("In order to run the BackgroundWorker, the background operation must be stopped or completed.")
  362.  
  363.                End Select
  364.  
  365.            End If
  366.  
  367.        End Sub
  368.  
  369.        ''' ----------------------------------------------------------------------------------------------------
  370.        ''' <summary>
  371.        ''' Asynchronously starts execution of a background operation.
  372.        ''' </summary>
  373.        ''' ----------------------------------------------------------------------------------------------------
  374.        ''' <exception cref="InvalidOperationException">
  375.        ''' In order to run the BackgroundWorker, the background operation must be stopped or completed.
  376.        ''' </exception>
  377.        ''' ----------------------------------------------------------------------------------------------------
  378.        <DebuggerStepThrough>
  379.        Public Overridable Sub RunAsync()
  380.  
  381.            If (Me Is Nothing) Then
  382.                Throw New ObjectDisposedException(objectName:="Me")
  383.  
  384.            Else
  385.                Select Case Me.stateB
  386.  
  387.                    Case ElektroBackgroundWorkerState.Stopped, ElektroBackgroundWorkerState.Completed
  388.                        MyBase.WorkerReportsProgress = True
  389.                        MyBase.WorkerSupportsCancellation = True
  390.                        MyBase.RunWorkerAsync()
  391.                        Me.stateB = ElektroBackgroundWorkerState.Running
  392.  
  393.                    Case Else
  394.                        Throw New InvalidOperationException("In order to run the BackgroundWorker, the background operation must be stopped or completed.")
  395.  
  396.                End Select
  397.  
  398.            End If
  399.  
  400.        End Sub
  401.  
  402.        ''' ----------------------------------------------------------------------------------------------------
  403.        ''' <summary>
  404.        ''' Pause a pending background operation.
  405.        ''' <para></para>
  406.        ''' It blocks the caller thread until the background work is resumed.
  407.        ''' To resume the background work, call the <see cref="ElektroBackgroundWorker.Resume"/> method.
  408.        ''' </summary>
  409.        ''' ----------------------------------------------------------------------------------------------------
  410.        ''' <exception cref="InvalidOperationException">
  411.        ''' In order to pause the BackgroundWorker, firstly a pause request should be made.
  412.        ''' </exception>
  413.        '''
  414.        ''' <exception cref="InvalidOperationException">
  415.        ''' In order to pause the BackgroundWorker, the background operation must be be running.
  416.        ''' </exception>
  417.        ''' ----------------------------------------------------------------------------------------------------
  418.        <DebuggerStepThrough>
  419.        Public Overridable Sub Pause()
  420.  
  421.            If (Me Is Nothing) Then
  422.                Throw New ObjectDisposedException(objectName:="Me")
  423.  
  424.            Else
  425.                Select Case Me.stateB
  426.  
  427.                    Case ElektroBackgroundWorkerState.Running
  428.                        If (Me.PausePending) Then
  429.                            Me.mreAsync.WaitOne(Timeout.Infinite)
  430.                        Else
  431.                            Throw New InvalidOperationException("In order to pause the BackgroundWorker, firstly a pause request should be made.")
  432.                        End If
  433.  
  434.                    Case Else
  435.                        Throw New InvalidOperationException("In order to pause the BackgroundWorker, the background operation must be running.")
  436.  
  437.                End Select
  438.  
  439.            End If
  440.  
  441.        End Sub
  442.  
  443.        ''' ----------------------------------------------------------------------------------------------------
  444.        ''' <summary>
  445.        ''' Asynchronously requests to pause a pending background operation.
  446.        ''' <para></para>
  447.        ''' To pause the background work after requesting a pause,
  448.        ''' call the <see cref="ElektroBackgroundWorker.Pause"/> method.
  449.        ''' </summary>
  450.        ''' ----------------------------------------------------------------------------------------------------
  451.        ''' <exception cref="InvalidOperationException">
  452.        ''' In order to request a pause of the BackgroundWorker, the background operation must be running.
  453.        ''' </exception>
  454.        ''' ----------------------------------------------------------------------------------------------------
  455.        <DebuggerStepThrough>
  456.        Public Overridable Sub RequestPause()
  457.  
  458.            If (Me Is Nothing) Then
  459.                Throw New ObjectDisposedException(objectName:="Me")
  460.  
  461.            Else
  462.                Select Case Me.stateB
  463.  
  464.                    Case ElektroBackgroundWorkerState.Running
  465.                        Me.isPauseRequested = True
  466.                        Me.stateB = ElektroBackgroundWorkerState.Paused
  467.                        Me.mreAsync.Reset()
  468.  
  469.                    Case Else
  470.                        Throw New InvalidOperationException("In order to request a pause of the BackgroundWorker, the background operation must be running..")
  471.  
  472.                End Select
  473.  
  474.            End If
  475.  
  476.        End Sub
  477.  
  478.        ''' ----------------------------------------------------------------------------------------------------
  479.        ''' <summary>
  480.        ''' Resume a pending paused background operation.
  481.        ''' </summary>
  482.        ''' ----------------------------------------------------------------------------------------------------
  483.        ''' <exception cref="InvalidOperationException">
  484.        ''' In order to resume the BackgroundWorker, the background operation must be paused.
  485.        ''' </exception>
  486.        ''' ----------------------------------------------------------------------------------------------------
  487.        <DebuggerStepThrough>
  488.        Public Overridable Sub [Resume]()
  489.  
  490.            If (Me Is Nothing) Then
  491.                Throw New ObjectDisposedException(objectName:="Me")
  492.  
  493.            Else
  494.                Select Case Me.stateB
  495.  
  496.                    Case ElektroBackgroundWorkerState.Paused
  497.                        Me.stateB = ElektroBackgroundWorkerState.Running
  498.                        Me.isPauseRequested = False
  499.                        Me.mreAsync.Set()
  500.  
  501.                    Case Else
  502.                        Throw New InvalidOperationException("In order to resume the BackgroundWorker, the background operation must be paused.")
  503.  
  504.                End Select
  505.  
  506.            End If
  507.  
  508.        End Sub
  509.  
  510.        ''' ----------------------------------------------------------------------------------------------------
  511.        ''' <summary>
  512.        ''' Requests cancellation of a pending background operation.
  513.        ''' <para></para>
  514.        ''' It blocks the caller thread until the remaining background work is canceled.
  515.        ''' </summary>
  516.        ''' ----------------------------------------------------------------------------------------------------
  517.        ''' <exception cref="InvalidOperationException">
  518.        ''' In order to cancel the BackgroundWorker, the background operation must be running or paused.
  519.        ''' </exception>
  520.        ''' ----------------------------------------------------------------------------------------------------
  521.        <DebuggerStepThrough>
  522.        Public Overridable Sub Cancel()
  523.  
  524.            Me.isCancelSyncRequested = True
  525.            Me.CancelAsync()
  526.            Me.mreSync.WaitOne()
  527.            Me.isCancelSyncRequested = False
  528.  
  529.        End Sub
  530.  
  531.        ''' ----------------------------------------------------------------------------------------------------
  532.        ''' <summary>
  533.        ''' Asynchronously requests cancellation of a pending background operation.
  534.        ''' </summary>
  535.        ''' ----------------------------------------------------------------------------------------------------
  536.        ''' <exception cref="InvalidOperationException">
  537.        ''' In order to cancel the BackgroundWorker, the background operation must be running or paused.
  538.        ''' </exception>
  539.        ''' ----------------------------------------------------------------------------------------------------
  540.        <DebuggerStepThrough>
  541.        Public Overridable Overloads Sub CancelAsync()
  542.  
  543.            If (Me Is Nothing) Then
  544.                Throw New ObjectDisposedException(objectName:="Me")
  545.  
  546.            Else
  547.                Select Case Me.stateB
  548.  
  549.                    Case ElektroBackgroundWorkerState.CancellationPending
  550.                        Exit Sub
  551.  
  552.                    Case ElektroBackgroundWorkerState.Running, ElektroBackgroundWorkerState.Paused
  553.                        Me.mreAsync.Set() ' Resume thread if it is paused.
  554.                        Me.stateB = ElektroBackgroundWorkerState.CancellationPending
  555.                        MyBase.CancelAsync() ' Cancel it.
  556.  
  557.                    Case Else
  558.                        Throw New InvalidOperationException("In order to cancel the BackgroundWorker, the background operation must be running or paused.")
  559.  
  560.                End Select
  561.  
  562.            End If
  563.  
  564.        End Sub
  565.  
  566. #End Region
  567.  
  568. #Region " Event Invocators "
  569.  
  570.        ''' ----------------------------------------------------------------------------------------------------
  571.        ''' <summary>
  572.        ''' Raises the <see cref="BackgroundWorker.DoWork"/> event.
  573.        ''' </summary>
  574.        ''' ----------------------------------------------------------------------------------------------------
  575.        ''' <param name="e">
  576.        ''' An <see cref="EventArgs"/> that contains the event data.
  577.        ''' </param>
  578.        ''' ----------------------------------------------------------------------------------------------------
  579.        Protected Overrides Sub OnDoWork(e As DoWorkEventArgs)
  580.            MyBase.OnDoWork(e)
  581.  
  582.            If (Me.isRunSync) OrElse (Me.isCancelSyncRequested) Then
  583.                Me.mreSync.Set()
  584.            End If
  585.        End Sub
  586.  
  587.        ''' ----------------------------------------------------------------------------------------------------
  588.        ''' <summary>
  589.        ''' Raises the <see cref="BackgroundWorker.ProgressChanged"/> event.
  590.        ''' </summary>
  591.        ''' ----------------------------------------------------------------------------------------------------
  592.        ''' <param name="e">
  593.        ''' An <see cref="ProgressChangedEventArgs"/> that contains the event data.
  594.        ''' </param>
  595.        ''' ----------------------------------------------------------------------------------------------------
  596.        Protected Overrides Sub OnProgressChanged(e As ProgressChangedEventArgs)
  597.            MyBase.OnProgressChanged(e)
  598.        End Sub
  599.  
  600.        ''' ----------------------------------------------------------------------------------------------------
  601.        ''' <summary>
  602.        ''' Raises the <see cref="BackgroundWorker.RunWorkerCompleted"/> event.
  603.        ''' </summary>
  604.        ''' ----------------------------------------------------------------------------------------------------
  605.        ''' <param name="e">
  606.        ''' An <see cref="RunWorkerCompletedEventArgs"/> that contains the event data.
  607.        ''' </param>
  608.        ''' ----------------------------------------------------------------------------------------------------
  609.        Protected Overrides Sub OnRunWorkerCompleted(e As RunWorkerCompletedEventArgs)
  610.            Me.stateB = ElektroBackgroundWorkerState.Completed
  611.            MyBase.OnRunWorkerCompleted(e)
  612.        End Sub
  613.  
  614. #End Region
  615.  
  616. #Region " Hidden Base Members "
  617.  
  618.        ''' ----------------------------------------------------------------------------------------------------
  619.        ''' <summary>
  620.        ''' Starts execution of a background operation.
  621.        ''' </summary>
  622.        ''' ----------------------------------------------------------------------------------------------------
  623.        <EditorBrowsable(EditorBrowsableState.Never)>
  624.        <DebuggerStepThrough>
  625.        Public Overridable Shadows Sub RunWorkerAsync()
  626.            MyBase.RunWorkerAsync()
  627.        End Sub
  628.  
  629. #End Region
  630.  
  631. #Region " IDisposable Implementation "
  632.  
  633.        ''' ----------------------------------------------------------------------------------------------------
  634.        ''' <summary>
  635.        ''' Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
  636.        ''' <para></para>
  637.        ''' Releases unmanaged and, optionally, managed resources.
  638.        ''' </summary>
  639.        ''' ----------------------------------------------------------------------------------------------------
  640.        ''' <param name="isDisposing">
  641.        ''' <see langword="True"/> to release both managed and unmanaged resources;
  642.        ''' <see langword="False"/> to release only unmanaged resources.
  643.        ''' </param>
  644.        ''' ----------------------------------------------------------------------------------------------------
  645.        <DebuggerStepThrough>
  646.        Protected Overrides Sub Dispose(isDisposing As Boolean)
  647.            MyBase.Dispose(isDisposing)
  648.  
  649.            If (isDisposing) Then
  650.                Me.mreSync.SafeWaitHandle.Close()
  651.                Me.mreSync.SafeWaitHandle.Dispose()
  652.                Me.mreSync.Close()
  653.                Me.mreSync.Dispose()
  654.  
  655.                Me.mreAsync.SafeWaitHandle.Close()
  656.                Me.mreAsync.SafeWaitHandle.Dispose()
  657.                Me.mreAsync.Close()
  658.                Me.mreAsync.Dispose()
  659.  
  660.                Me.isRunSync = False
  661.                Me.stateB = ElektroBackgroundWorkerState.Stopped
  662.            End If
  663.  
  664.        End Sub
  665.  
  666. #End Region
  667.  
  668.    End Class
  669.  
  670. ' End Namespace
  671.  
  672. #End Region
  673.  

+

Código
  1. ' ***********************************************************************
  2. ' Author   : Elektro
  3. ' Modified : 02-February-2018
  4. ' ***********************************************************************
  5.  
  6. #Region " Option Statements "
  7.  
  8. Option Strict On
  9. Option Explicit On
  10. Option Infer Off
  11.  
  12. #End Region
  13.  
  14. #Region " Imports "
  15.  
  16. ' Imports ElektroKit.Core.Threading.Types
  17.  
  18. #End Region
  19.  
  20. #Region " ElektroBackgroundWorker State "
  21.  
  22. ' Namespace Threading.Enums
  23.  
  24.    ''' ----------------------------------------------------------------------------------------------------
  25.    ''' <summary>
  26.    ''' Specifies the state of a <see cref="ElektroBackgroundWorker"/>.
  27.    ''' </summary>
  28.    ''' ----------------------------------------------------------------------------------------------------
  29.    Public Enum ElektroBackgroundWorkerState As Integer
  30.  
  31.        ''' <summary>
  32.        ''' The <see cref="ElektroBackgroundWorker"/> is stopped.
  33.        ''' </summary>
  34.        Stopped = 0
  35.  
  36.        ''' <summary>
  37.        ''' The <see cref="ElektroBackgroundWorker"/> is running.
  38.        ''' </summary>
  39.        Running = 1
  40.  
  41.        ''' <summary>
  42.        ''' The <see cref="ElektroBackgroundWorker"/> is paused.
  43.        ''' </summary>
  44.        Paused = 2
  45.  
  46.        ''' <summary>
  47.        ''' The <see cref="ElektroBackgroundWorker"/> is pending on a cancellation.
  48.        ''' </summary>
  49.        CancellationPending = 3
  50.  
  51.        ''' <summary>
  52.        ''' The <see cref="ElektroBackgroundWorker"/> is completed (stopped).
  53.        ''' </summary>
  54.        Completed = 4
  55.  
  56.    End Enum
  57.  
  58. ' End Namespace
  59.  
  60. #End Region
  61.  

Ejemplo de uso:

Código
  1. Friend WithEvents Worker As ElektroBackgroundWorker
  2.  
  3. Private Sub Button_Run_Click() Handles Button_Run.Click
  4.  
  5.    If (Me.Worker IsNot Nothing) Then
  6.  
  7.        Select Case Me.Worker.State
  8.            Case ElektroBackgroundWorkerState.Running, ElektroBackgroundWorkerState.Paused
  9.                Me.Worker.Cancel()
  10.            Case Else
  11.                ' Do Nothing.
  12.        End Select
  13.  
  14.    End If
  15.  
  16.    Me.Worker = New ElektroBackgroundWorker
  17.    Me.Worker.RunAsync()
  18.  
  19. End Sub
  20.  
  21. Private Sub Button_Pause_Click() Handles Button_Pause.Click
  22.    Me.Worker.RequestPause()
  23. End Sub
  24.  
  25. Private Sub Button_Resume_Click() Handles Button_Resume.Click
  26.    Me.Worker.Resume()
  27. End Sub
  28.  
  29. Private Sub Button_Cancel_Click() Handles Button_Cancel.Click
  30.    Me.Worker.Cancel()
  31. End Sub
  32.  
  33. ''' ----------------------------------------------------------------------------------------------------
  34. ''' <summary>
  35. ''' Handles the <see cref="ElektroBackgroundWorker.DoWork"/> event of the <see cref="Worker"/> instance.
  36. ''' </summary>
  37. ''' ----------------------------------------------------------------------------------------------------
  38. ''' <param name="sender">
  39. ''' The source of the event.
  40. ''' </param>
  41. '''
  42. ''' <param name="e">
  43. ''' The <see cref="DoWorkEventArgs"/> instance containing the event data.
  44. ''' </param>
  45. ''' ----------------------------------------------------------------------------------------------------
  46. <DebuggerStepperBoundary>
  47. Private Sub Worker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) _
  48. Handles Worker.DoWork
  49.  
  50.    Dim progress As Integer
  51.  
  52.    Dim lock As Object = ""
  53.    SyncLock lock
  54.  
  55.        For i As Integer = 0 To 100
  56.            If (Me.Worker.CancellationPending) Then ' Cancel the background operation.
  57.                e.Cancel = True
  58.                Exit For
  59.  
  60.            Else
  61.                If (Me.Worker.PausePending) Then ' Pause the background operation.
  62.                    Me.Worker.Pause() ' Blocking pause call.
  63.                End If
  64.  
  65.                Me.DoSomething()
  66.  
  67.                If Me.Worker.WorkerReportsProgress Then
  68.                    progress = i
  69.                    Me.Worker.ReportProgress(progress)
  70.                End If
  71.  
  72.            End If
  73.  
  74.        Next i
  75.  
  76.    End SyncLock
  77.  
  78.    If (Me.Worker.WorkerReportsProgress) AndAlso Not (Me.Worker.CancellationPending) AndAlso (progress < 100) Then
  79.        Me.Worker.ReportProgress(percentProgress:=100)
  80.    End If
  81.  
  82. End Sub
  83.  
  84. ''' ----------------------------------------------------------------------------------------------------
  85. ''' <summary>
  86. ''' Handles the <see cref="ElektroBackgroundWorker.ProgressChanged"/> event of the <see cref="Worker"/> instance.
  87. ''' </summary>
  88. ''' ----------------------------------------------------------------------------------------------------
  89. ''' <param name="sender">
  90. ''' The source of the event.
  91. ''' </param>
  92. '''
  93. ''' <param name="e">
  94. ''' The <see cref="ProgressChangedEventArgs"/> instance containing the event data.
  95. ''' </param>
  96. ''' ----------------------------------------------------------------------------------------------------
  97. <DebuggerStepperBoundary>
  98. Private Sub Worker_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) _
  99. Handles Worker.ProgressChanged
  100.  
  101.    Console.WriteLine(String.Format("Background Work Progress: {00}%", e.ProgressPercentage))
  102.  
  103. End Sub
  104.  
  105. ''' ----------------------------------------------------------------------------------------------------
  106. ''' <summary>
  107. ''' Handles the <see cref="ElektroBackgroundWorker.RunWorkerCompleted"/> event of the <see cref="Worker"/> instance.
  108. ''' </summary>
  109. ''' ----------------------------------------------------------------------------------------------------
  110. ''' <param name="sender">
  111. ''' The source of the event.
  112. ''' </param>
  113. '''
  114. ''' <param name="e">
  115. ''' The <see cref="RunWorkerCompletedEventArgs"/> instance containing the event data.
  116. ''' </param>
  117. ''' ----------------------------------------------------------------------------------------------------
  118. <DebuggerStepperBoundary>
  119. Private Sub Worker_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) _
  120. Handles Worker.RunWorkerCompleted
  121.  
  122.    If (e.Cancelled) Then
  123.        Debug.WriteLine("Background work cancelled.")
  124.  
  125.    ElseIf (e.Error IsNot Nothing) Then
  126.        Debug.WriteLine("Background work error.")
  127.  
  128.    Else
  129.        Debug.WriteLine("Background work done.")
  130.  
  131.    End If
  132.  
  133.    Console.WriteLine(String.Format("State: {0}", Me.Worker.State.ToString()))
  134.  
  135. End Sub
  136.  
  137. <DebuggerStepperBoundary>
  138. Private Sub DoSomething()
  139.    Thread.Sleep(TimeSpan.FromSeconds(1))
  140. End Sub
« Última modificación: 2 Febrero 2018, 11:09 am por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.874



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #516 en: 12 Febrero 2018, 03:32 am »

¿Cómo crear y administrar una cuenta de correo deshechable/temporal?.

El siguiente código que voy a mostrar sirve para crear una cuenta de correo temporal usando el servicio https://10minutemail.com/, leer e-mails entrantes, y responderlos.

Hasta donde han llegado mis análisis y experimentos todo parece indicar que funciona como es esperado. Si encuentran algún problema háganmelo saber para corregir el código.

LO BUENO:
  • Renovación automática del tiempo de vida de la dirección deshechable. Dicho de otro modo: la dirección de correo NO expira... hasta que se libere la instancia de clase.
  • Implementación thread-safe.
  • Implementación orientada a eventos.
  • Funcionalidad para obtener y leer los correos entrantes.
  • Funcionalidad para responder a correos entrantes usando la dirección de correo deshechable.
  • Simple, abstracto, es muy sencillo de usar.

LO MALO:
  • No añadí soporte para leer archivos adjuntos en los mails recibidos.
  • No añadí soporte para responder a un destinatario de un mail recibido.
  • 10minutemail.com es un servicio gratuito y por ende también limitado, solo permite crear alrededor de 3-5 direccioens e-mail por minuto y por IP.
    Sin embargo, probablemente esta limitación se podría bypassear usando proxies.



1.

Primero de todo he creado una interfaz con nombre IDisposableMail, la cual podremos rehutilizar en el futuro para representar cualquier otro servicio de correo temporal similar a https://10minutemail.com/. Evidentemente pueden extender la interfaz si lo desean.

Código
  1. #Region " Imports "
  2.  
  3. Imports System.Net.Mail
  4.  
  5. #End Region
  6.  
  7. #Region " IDisposableMail "
  8.  
  9. ''' ----------------------------------------------------------------------------------------------------
  10. ''' <summary>
  11. ''' Represents a disposable mail address.
  12. ''' </summary>
  13. ''' ----------------------------------------------------------------------------------------------------
  14. ''' <remarks>
  15. ''' Wikipedia article: <see href="https://en.wikipedia.org/wiki/Disposable_email_address"/>
  16. ''' </remarks>
  17. ''' ----------------------------------------------------------------------------------------------------
  18. Public Interface IDisposableMail
  19.  
  20. #Region " Events "
  21.  
  22.    ''' <summary>
  23.    ''' Occurs when a new inbox message arrived.
  24.    ''' </summary>
  25.    Event MailMessageArrived As EventHandler(Of MailMessageArrivedEventArgs)
  26.  
  27. #End Region
  28.  
  29. #Region " (Public) Methods "
  30.  
  31.    ''' <summary>
  32.    ''' Creates a new temporary mail address.
  33.    ''' </summary>
  34.    ''' <param name="updateInterval">
  35.    ''' The time interval to check for new incoming mail messages.
  36.    ''' </param>
  37.    Sub CreateNew(ByVal updateInterval As TimeSpan)
  38.  
  39.    ''' <summary>
  40.    ''' Renews the life-time for the current temporary mail address.
  41.    ''' </summary>
  42.    Sub Renew()
  43.  
  44. #End Region
  45.  
  46. #Region " (Private) Functions "
  47.  
  48.    ''' <summary>
  49.    ''' Gets the mail address.
  50.    ''' </summary>
  51.    ''' <returns>
  52.    ''' The mail address.
  53.    ''' </returns>
  54.    Function GetMailAddress() As MailAddress
  55.  
  56.    ''' <summary>
  57.    ''' Gets the inbox message count.
  58.    ''' </summary>
  59.    ''' <returns>
  60.    ''' The inbox message count.
  61.    ''' </returns>
  62.    Function GetMessageCount() As Integer
  63.  
  64.    ''' <summary>
  65.    ''' Gets the inbox messages.
  66.    ''' </summary>
  67.    ''' <returns>
  68.    ''' The inbox messages.
  69.    ''' </returns>
  70.    Function GetMessages() As IEnumerable(Of MailMessage)
  71.  
  72.    ''' <summary>
  73.    ''' Gets the time left to expire the current temporary mail address.
  74.    ''' </summary>
  75.    ''' <returns>
  76.    ''' The time left to expire the current temporary mail address.
  77.    ''' </returns>
  78.    Function GetExpirationTime() As TimeSpan
  79.  
  80. #End Region
  81.  
  82. End Interface
  83.  
  84. #End Region



2.

Para el evento IDisposableMail.MailMessageArrived creé la siguiente clase con nombre MailMessageArrivedEventArgs, la cual proveerá los datos del evento:

Código
  1. #Region " Imports "
  2.  
  3. Imports System.Net.Mail
  4. Imports System.Runtime.InteropServices
  5.  
  6. #End Region
  7.  
  8. #Region " MailMessageArrivedEventArgs "
  9.  
  10. ''' ----------------------------------------------------------------------------------------------------
  11. ''' <summary>
  12. ''' Represents the event data for the <see cref="IDisposableMail.MailMessageArrived"/> event.
  13. ''' </summary>
  14. ''' ----------------------------------------------------------------------------------------------------
  15. ''' <seealso cref="EventArgs" />
  16. ''' ----------------------------------------------------------------------------------------------------
  17. <ComVisible(True)>
  18. Public NotInheritable Class MailMessageArrivedEventArgs : Inherits EventArgs
  19.  
  20. #Region " Properties "
  21.  
  22.    ''' <summary>
  23.    ''' Gets the mail message.
  24.    ''' </summary>
  25.    ''' <value>
  26.    ''' The mail message.
  27.    ''' </value>
  28.    Public ReadOnly Property MailMessage As MailMessage
  29.  
  30. #End Region
  31.  
  32. #Region " Constructors "
  33.  
  34.    ''' <summary>
  35.    ''' Initializes a new instance of the <see cref="MailMessageArrivedEventArgs"/> class.
  36.    ''' </summary>
  37.    ''' <param name="msg">
  38.    ''' The mail message that arrived.
  39.    ''' </param>
  40.    Public Sub New(ByVal msg As MailMessage)
  41.        Me.MailMessage = msg
  42.    End Sub
  43.  
  44. #End Region
  45.  
  46. End Class
  47.  
  48. #End Region

3.

Seguidamente, extendí la clase WebClient para añadirle soporte para el uso de cookies, esto no es estrictamente necesario, la alternativa sería usar la clase HttpWeRequest y etc, pero de esta forma añadimos cierto nivel de abstracción adicional en la clase WebClient para poder utilizarla para este fin, y así podremos simplificar mucho el código necesario para escribir las solicitudes/requests al servicio de 10minutemail.com...

Código
  1. #Region " Imports "
  2.  
  3. Imports System.ComponentModel
  4. Imports System.Drawing
  5. Imports System.Net
  6. Imports System.Runtime.InteropServices
  7.  
  8. #End Region
  9.  
  10. #Region " ElektroWebClient "
  11.  
  12. ''' ----------------------------------------------------------------------------------------------------
  13. ''' <summary>
  14. ''' Represents a <see cref="WebClient"/> with support for cookies.
  15. ''' </summary>
  16. ''' ----------------------------------------------------------------------------------------------------
  17. ''' <remarks>
  18. ''' Original idea taken from: http://www.codingvision.net/tips-and-tricks/c-webclient-with-cookies
  19. ''' </remarks>
  20. ''' ----------------------------------------------------------------------------------------------------
  21. <DisplayName("ElektroWebClient")>
  22. <Description("A extended WebClient component, with support for cookies.")>
  23. <DesignTimeVisible(False)>
  24. <DesignerCategory("Component")>
  25. <ToolboxBitmap(GetType(Component), "Component.bmp")>
  26. <ToolboxItemFilter("System.Windows.Forms", ToolboxItemFilterType.Allow)>
  27. <ComVisible(True)>
  28. Public Class ElektroWebClient : Inherits WebClient
  29.  
  30. #Region " Properties "
  31.  
  32.    ''' <summary>
  33.    ''' Gets or sets a value indicating whether cookies are enabled.
  34.    ''' </summary>
  35.    ''' <value>
  36.    ''' <see langword="True"/> if cookies are enabled; otherwise, <see langword="False"/>.
  37.    ''' </value>
  38.    Public Property CookiesEnabled As Boolean
  39.  
  40.    ''' <summary>
  41.    ''' Gets the cookies.
  42.    ''' </summary>
  43.    ''' <value>
  44.    ''' The cookies.
  45.    ''' </value>
  46.    Public ReadOnly Property Cookies As CookieContainer
  47.        Get
  48.            Return Me.cookiesB
  49.        End Get
  50.    End Property
  51.    ''' <summary>
  52.    ''' (Backing field)
  53.    ''' <para></para>
  54.    ''' The cookies.
  55.    ''' </summary>
  56.    Private cookiesB As CookieContainer
  57.  
  58. #End Region
  59.  
  60. #Region " Constructors "
  61.  
  62.    ''' <summary>
  63.    ''' Initializes a new instance of the <see cref="ElektroWebClient"/> class.
  64.    ''' </summary>
  65.    Public Sub New()
  66.        MyBase.New()
  67.    End Sub
  68.  
  69. #End Region
  70.  
  71. #Region " Inherited Methods "
  72.  
  73.    ''' <summary>
  74.    ''' Returns a <see cref="WebRequest"/> object for the specified resource.
  75.    ''' </summary>
  76.    ''' <param name="address">
  77.    ''' A <see cref="Uri"/> that identifies the resource to request.
  78.    ''' </param>
  79.    ''' <returns>
  80.    ''' A new <see cref="WebRequest"/> object for the specified resource.
  81.    ''' </returns>
  82.    Protected Overrides Function GetWebRequest(ByVal address As Uri) As WebRequest
  83.        If Not (Me.CookiesEnabled) Then
  84.            Return MyBase.GetWebRequest(address)
  85.        End If
  86.  
  87.        Dim request As WebRequest = MyBase.GetWebRequest(address)
  88.        If (TypeOf request Is HttpWebRequest) Then
  89.            If (Me.cookiesB Is Nothing) Then
  90.                Me.cookiesB = New CookieContainer()
  91.            End If
  92.            DirectCast(request, HttpWebRequest).CookieContainer = Me.cookiesB
  93.        End If
  94.        Return request
  95.    End Function
  96.  
  97. #End Region
  98.  
  99. End Class
  100.  
  101. #End Region



4.

Esta es la última pieza de toda esta implementación, una clase con nombre TenMinuteMail que nos servirá para representar y administrar el correo deshechable...

Código
  1. #Region " Imports "
  2.  
  3. Imports System.Diagnostics.CodeAnalysis
  4. Imports System.Linq
  5. Imports System.Net
  6. Imports System.Net.Mail
  7. Imports System.Runtime.Serialization.Json
  8. Imports System.Text
  9. Imports System.Threading
  10. Imports System.Web
  11. Imports System.Xml
  12.  
  13. #End Region
  14.  
  15. #Region " TenMinuteMail "
  16.  
  17. ''' ----------------------------------------------------------------------------------------------------
  18. ''' <summary>
  19. ''' Creates and manages a temporary mail address using the https://10minutemail.com/ service.
  20. ''' <para></para>
  21. ''' Be aware the mail address will expire in approx. 10 minutes after calling the <see cref="TenMinuteMail.Dispose()"/> method.
  22. ''' </summary>
  23. ''' ----------------------------------------------------------------------------------------------------
  24. ''' <seealso cref="IDisposableMail"/>
  25. ''' <seealso cref="IDisposable"/>
  26. ''' ----------------------------------------------------------------------------------------------------
  27. Public Class TenMinuteMail : Implements IDisposableMail, IDisposable
  28.  
  29. #Region " Properties "
  30.  
  31.    ''' <summary>
  32.    ''' Gets the mail address.
  33.    ''' </summary>
  34.    ''' <value>
  35.    ''' The mail address.
  36.    ''' </value>
  37.    Public ReadOnly Property MailAddress As MailAddress
  38.        Get
  39.            Return Me.mailAddressB
  40.        End Get
  41.    End Property
  42.    ''' <summary>
  43.    ''' (Backing field) The current mail address.
  44.    ''' </summary>
  45.    Private mailAddressB As MailAddress
  46.  
  47.    ''' <summary>
  48.    ''' Gets the message count.
  49.    ''' </summary>
  50.    ''' <value>
  51.    ''' The message count.
  52.    ''' </value>
  53.    Public ReadOnly Property MessageCount As Integer
  54.        Get
  55.            Return Me.GetMessageCount()
  56.        End Get
  57.    End Property
  58.  
  59.    ''' <summary>
  60.    ''' Gets the inbox messages.
  61.    ''' </summary>
  62.    ''' <value>
  63.    ''' The inbox messages.
  64.    ''' </value>
  65.    Public Overridable ReadOnly Property Messages As IEnumerable(Of MailMessage)
  66.        Get
  67.            Return Me.GetMessages()
  68.        End Get
  69.    End Property
  70.  
  71.    ''' <summary>
  72.    ''' Gets the inbox message with the specified message id.
  73.    ''' </summary>
  74.    ''' <param name="id">
  75.    ''' The message id.
  76.    ''' </param>
  77.    ''' <value>
  78.    ''' The inbox message with the specified message id.
  79.    ''' </value>
  80.    Public Overridable ReadOnly Property Messages(ByVal id As String) As MailMessage
  81.        Get
  82.            Return Me.GetMessage(id)
  83.        End Get
  84.    End Property
  85.  
  86.    ''' <summary>
  87.    ''' Gets a value indicating whether the temporary mail service is blocked.
  88.    ''' <para></para>
  89.    ''' If <see langword="True"/>,
  90.    ''' this means you have requested too many temporary mail addresses from your IP address too quickly.
  91.    ''' <para></para>
  92.    ''' And you must wait some minutes to be able use 10minutemail.com service again.
  93.    ''' </summary>
  94.    ''' <value>
  95.    ''' If <see langword="True"/>,
  96.    ''' this means you have requested too many temporary mail addresses from your IP address too quickly.
  97.    ''' <para></para>
  98.    ''' And you must wait some minutes to be able use 10minutemail.com service again.; otherwise, <see langword="False"/>.
  99.    ''' </value>
  100.    Public ReadOnly Property IsBlocked As Boolean
  101.        Get
  102.            If Not (Me.isBlockedB) Then
  103.                Me.isBlockedB = Me.GetIsBlocked()
  104.            End If
  105.            Return isBlockedB
  106.        End Get
  107.    End Property
  108.    ''' <summary>
  109.    ''' ( Backing field)
  110.    ''' <para></para>
  111.    ''' Gets a value indicating whether the temporary mail service is blocked.
  112.    ''' <para></para>
  113.    ''' If <see langword="True"/>,
  114.    ''' this means you have requested too many temporary mail addresses from your IP address too quickly.
  115.    ''' <para></para>
  116.    ''' And you must wait some minutes to be able use 10minutemail.com service again.
  117.    ''' </summary>
  118.    Private isBlockedB As Boolean
  119.  
  120. #End Region
  121.  
  122. #Region " Fields "
  123.  
  124. #Region " Common "
  125.  
  126.    ''' <summary>
  127.    ''' The <see cref="ElektroWebClient"/> instance that manage cookies and requests to https://10minutemail.com/.
  128.    ''' </summary>
  129.    Protected Client As ElektroWebClient
  130.  
  131.    ''' <summary>
  132.    ''' A <see cref="Timer"/> instance that will renew the life-time of the temporary mail address,
  133.    ''' and check for new incoming mail messages.
  134.    ''' </summary>
  135.    Protected TimerUpdate As Timer
  136.  
  137.    ''' <summary>
  138.    ''' A counter to keep track of the current mail message count, and so detect new incoming mail messages.
  139.    ''' </summary>
  140.    Private messageCounter As Integer
  141.  
  142. #End Region
  143.  
  144. #Region " Uris "
  145.  
  146.    ''' <summary>
  147.    ''' The Uri that points to the main site.
  148.    ''' </summary>
  149.    Protected uriBase As Uri
  150.  
  151.    ''' <summary>
  152.    ''' The Uri that points to the address resource.
  153.    ''' </summary>
  154.    Protected uriAddress As Uri
  155.  
  156.    ''' <summary>
  157.    ''' The Uri that points to the blocked resource.
  158.    ''' </summary>
  159.    Protected uriBlocked As Uri
  160.  
  161.    ''' <summary>
  162.    ''' The Uri that points to the messagecount resource.
  163.    ''' </summary>
  164.    Protected uriMessageCount As Uri
  165.  
  166.    ''' <summary>
  167.    ''' The Uri that points to the messages resource.
  168.    ''' </summary>
  169.    Protected uriMessages As Uri
  170.  
  171.    ''' <summary>
  172.    ''' The Uri that points to the reply resource.
  173.    ''' </summary>
  174.    Protected uriReply As Uri
  175.  
  176.    ''' <summary>
  177.    ''' The Uri that points to the reset resource.
  178.    ''' </summary>
  179.    Protected uriReset As Uri
  180.  
  181.    ''' <summary>
  182.    ''' The Uri that points to the secondsleft resource.
  183.    ''' </summary>
  184.    Protected uriSecondsLeft As Uri
  185.  
  186. #End Region
  187.  
  188. #End Region
  189.  
  190. #Region " Events "
  191.  
  192.    ''' <summary>
  193.    ''' Occurs when a new inbox message arrived.
  194.    ''' </summary>
  195.    Public Event MailMessageArrived As EventHandler(Of MailMessageArrivedEventArgs) Implements IDisposableMail.MailMessageArrived
  196.  
  197. #End Region
  198.  
  199. #Region " Constructors "
  200.  
  201.    ''' <summary>
  202.    ''' Initializes a new instance of the <see cref="TenMinuteMail"/> class.
  203.    ''' </summary>
  204.    <DebuggerStepThrough>
  205.    Public Sub New()
  206.        Me.New(TimeSpan.FromSeconds(10))
  207.    End Sub
  208.  
  209.    ''' <summary>
  210.    ''' Initializes a new instance of the <see cref="TenMinuteMail"/> class.
  211.    ''' </summary>
  212.    ''' <param name="updateInterval">
  213.    ''' The time interval to check for new incoming messages.
  214.    ''' <para></para>
  215.    ''' Be aware that 10minutemail.com server's update interval are 10 seconds by default.
  216.    ''' </param>
  217.    ''' <exception cref="ArgumentException">
  218.    ''' Update interval must be in range between 10 to 60 seconds. - updateInterval
  219.    ''' </exception>
  220.    <SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification:="Don't panic")>
  221.    <DebuggerStepThrough>
  222.    Public Sub New(ByVal updateInterval As TimeSpan)
  223.        Me.uriBase = New Uri("https://10minutemail.com/")
  224.        Me.uriAddress = New Uri(Me.uriBase, "/10MinuteMail/resources/session/address")
  225.        Me.uriBlocked = New Uri(Me.uriBase, "/10MinuteMail/resources/session/blocked")
  226.        Me.uriMessageCount = New Uri(Me.uriBase, "/10MinuteMail/resources/messages/messageCount")
  227.        Me.uriMessages = New Uri(Me.uriBase, "/10MinuteMail/resources/messages")
  228.        Me.uriReply = New Uri(Me.uriBase, "/10MinuteMail/resources/messages/reply")
  229.        Me.uriReset = New Uri(Me.uriBase, "/10MinuteMail/resources/session/reset")
  230.        Me.uriSecondsLeft = New Uri(Me.uriBase, "/10MinuteMail/resources/session/secondsLeft")
  231.  
  232.        Me.CreateNew(updateInterval)
  233.    End Sub
  234.  
  235. #End Region
  236.  
  237. #Region " Public Methods "
  238.  
  239.    ''' <summary>
  240.    ''' Creates a new temporary mail address.
  241.    ''' </summary>
  242.    ''' <param name="updateInterval">
  243.    ''' The time interval to check for new incoming messages.
  244.    ''' <para></para>
  245.    ''' Be aware that 10minutemail.com server's update interval are 10 seconds by default.
  246.    ''' </param>
  247.    ''' <exception cref="ArgumentException">
  248.    ''' Update interval must be in range between 10 to 60 seconds. - updateInterval
  249.    ''' </exception>
  250.    <DebuggerStepThrough>
  251.    Public Overridable Sub CreateNew(ByVal updateInterval As TimeSpan) Implements IDisposableMail.CreateNew
  252.        Dim totalMilliseconds As Integer = Convert.ToInt32(updateInterval.TotalMilliseconds)
  253.  
  254.        Select Case totalMilliseconds
  255.            Case Is < 10000 ' 10 seconds.
  256.                Throw New ArgumentException("Update interval must be in range between 10 to 60 seconds.", "updateInterval")
  257.  
  258.            Case Is > 60000 ' 1 minute.
  259.                Throw New ArgumentException("Update interval must be in range between 10 to 60 seconds.", "updateInterval")
  260.  
  261.            Case Else
  262.                If (Me.TimerUpdate IsNot Nothing) Then
  263.                    Me.TimerUpdate.Change(Timeout.Infinite, Timeout.Infinite)
  264.                End If
  265.  
  266.                If (Me.Client IsNot Nothing) Then
  267.                    Me.Client.Dispose()
  268.                    Me.Client = Nothing
  269.                End If
  270.  
  271.                Me.isBlockedB = False
  272.                Me.mailAddressB = Nothing
  273.                Me.messageCounter = 0
  274.  
  275.                Me.Client = New ElektroWebClient() With {.CookiesEnabled = True, .Encoding = Encoding.UTF8}
  276.                Me.mailAddressB = Me.GetMailAddress()
  277.                Me.TimerUpdate = New Timer(AddressOf Me.UpdateTimer_CallBack, Me, totalMilliseconds, totalMilliseconds)
  278.  
  279.        End Select
  280.    End Sub
  281.  
  282.    ''' <summary>
  283.    ''' Replies to a <see cref="MailMessage"/> with the specified message id.
  284.    ''' </summary>
  285.    ''' <param name="msgId">
  286.    ''' The message id of the <see cref="MailMessage"/>.
  287.    ''' </param>
  288.    '''
  289.    ''' <param name="body">
  290.    ''' The body.
  291.    ''' </param>
  292.    Public Overridable Sub Reply(ByVal msgId As String, ByVal body As String)
  293.        Me.Reply(Me.Messages(msgId), body)
  294.    End Sub
  295.  
  296.    ''' <summary>
  297.    ''' Replies to the specified <see cref="MailMessage"/>.
  298.    ''' </summary>
  299.    ''' <param name="msg">
  300.    ''' The <see cref="MailMessage"/>.
  301.    ''' </param>
  302.    '''
  303.    ''' <param name="body">
  304.    ''' The body.
  305.    ''' </param>
  306.    Public Overridable Sub Reply(ByVal msg As MailMessage, ByVal body As String)
  307.  
  308.        Dim msgId As String = msg.Headers.Item("msgId")
  309.        Dim parameters As String = String.Format("messageId={0}&replyBody=""{1}""", msgId, HttpUtility.UrlEncode(body))
  310.  
  311.        Dim result As String
  312.        SyncLock (Me.Client)
  313.            Me.Client.Headers(HttpRequestHeader.ContentType) = "application/x-www-form-urlencoded"
  314.            result = Me.Client.UploadString(Me.uriReply, "POST", parameters)
  315.            Me.Client.Headers.Remove(HttpRequestHeader.ContentType)
  316.        End SyncLock
  317.  
  318.        ' ToDo: need to improve...
  319.        If Not String.IsNullOrEmpty(result) Then
  320.            ' ...
  321.        End If
  322.  
  323.    End Sub
  324.  
  325. #End Region
  326.  
  327. #Region " Private/Protected Methods "
  328.  
  329.    ''' <summary>
  330.    ''' Gets the mail address.
  331.    ''' </summary>
  332.    ''' <returns>
  333.    ''' The mail address.
  334.    ''' </returns>
  335.    ''' <exception cref="WebException">
  336.    ''' You have requested too many temporary mail addresses from your IP address too quickly.
  337.    ''' Please wait some minutes and try again.
  338.    ''' </exception>
  339.    <DebuggerStepThrough>
  340.    Protected Overridable Function GetMailAddress() As MailAddress Implements IDisposableMail.GetMailAddress
  341.        If (Me.IsBlocked) Then
  342.            Throw New WebException("You have requested too many temporary mail addresses from your IP address too quickly. Please wait some minutes and try again.")
  343.        End If
  344.  
  345.        If (Me.mailAddressB Is Nothing) Then
  346.            SyncLock (Me.Client)
  347.                Dim value As String = Me.Client.DownloadString(Me.uriAddress)
  348.                Me.mailAddressB = New MailAddress(value, "TenMinuteMail", Encoding.Default)
  349.            End SyncLock
  350.        End If
  351.  
  352.        Return Me.mailAddressB
  353.    End Function
  354.  
  355.    ''' <summary>
  356.    ''' Gets the inbox message count.
  357.    ''' </summary>
  358.    ''' <returns>
  359.    ''' The inbox message count.
  360.    ''' </returns>
  361.    ''' <exception cref="WebException">
  362.    ''' You have requested too many temporary mail addresses from your IP address too quickly.
  363.    ''' Please wait some minutes and try again.
  364.    ''' </exception>
  365.    <DebuggerStepThrough>
  366.    Protected Overridable Function GetMessageCount() As Integer Implements IDisposableMail.GetMessageCount
  367.        If (Me.IsBlocked) Then
  368.            Throw New WebException("You have requested too many temporary mail addresses from your IP address too quickly. Please wait some minutes and try again.")
  369.        End If
  370.  
  371.        SyncLock (Me.Client)
  372.            Dim value As String = Me.Client.DownloadString(Me.uriMessageCount)
  373.            Return Convert.ToInt32(value)
  374.        End SyncLock
  375.    End Function
  376.  
  377.    ''' <summary>
  378.    ''' Gets the inbox message with the specified message id.
  379.    ''' </summary>
  380.    ''' <param name="id">
  381.    ''' The message id.
  382.    ''' </param>
  383.    ''' <returns>
  384.    ''' The inbox message with the specified message id.
  385.    ''' </returns>
  386.    ''' <exception cref="WebException">
  387.    ''' You have requested too many temporary mail addresses from your IP address too quickly.
  388.    ''' Please wait some minutes and try again.
  389.    ''' </exception>
  390.    <DebuggerStepThrough>
  391.    Protected Overridable Function GetMessage(ByVal id As String) As MailMessage
  392.  
  393.        Return (From msg As MailMessage In Me.GetMessages()
  394.                Where msg.Headers("msgId").Equals(id, StringComparison.OrdinalIgnoreCase)
  395.               ).Single()
  396.  
  397.    End Function
  398.  
  399.    ''' <summary>
  400.    ''' Gets the inbox messages.
  401.    ''' </summary>
  402.    ''' <returns>
  403.    ''' The inbox messages.
  404.    ''' </returns>
  405.    ''' <exception cref="WebException">
  406.    ''' You have requested too many temporary mail addresses from your IP address too quickly.
  407.    ''' Please wait some minutes and try again.
  408.    ''' </exception>
  409.    <DebuggerStepThrough>
  410.    Protected Overridable Iterator Function GetMessages() As IEnumerable(Of MailMessage) Implements IDisposableMail.GetMessages
  411.        If (Me.IsBlocked) Then
  412.            Throw New WebException("You have requested too many temporary mail addresses from your IP address too quickly. Please wait some minutes and try again.")
  413.        End If
  414.  
  415.        If (Me.GetMessageCount = 0) Then
  416.            Exit Function
  417.        End If
  418.  
  419.        SyncLock (Me.Client)
  420.  
  421.            Dim src As Byte() = Me.Client.DownloadData(Me.uriMessages)
  422.            Using xmlReader As XmlDictionaryReader =
  423.              JsonReaderWriterFactory.CreateJsonReader(src, 0, src.Length, Encoding.UTF8, New XmlDictionaryReaderQuotas, Nothing)
  424.  
  425.                Dim xml As XElement = XElement.Load(xmlReader)
  426.                If (xml Is Nothing) Then
  427.                    Exit Function
  428.                End If
  429.  
  430.                For Each item As XElement In xml.Elements("item")
  431.  
  432.                    Dim recipientList As XElement = item.<recipientList>.Single()
  433.                    Dim primaryFromAddress As String = item.<primaryFromAddress>.Value
  434.                    Dim subject As String = item.<subject>.Value
  435.                    Dim body As String = item.<bodyText>.Value
  436.                    ' Get the message id. to identify and reply the message:
  437.                    Dim id As String = item.<id>.Value
  438.  
  439.                    ' ToDO: attachment support.
  440.                    ' Dim attachmentCount As Integer = Convert.ToInt32(item.<attachmentCount>.Value)
  441.                    ' Dim attachments As XElement = item.<attachments>.Single()
  442.                    ' ...
  443.                    ' MailMessage.Attachments.Add(New Attachment( ... , MediaTypeNames.Application.Octet))
  444.  
  445.                    Dim msg As New MailMessage()
  446.                    With msg
  447.                        .BodyEncoding = Encoding.UTF8
  448.                        ' .HeadersEncoding = Encoding.UTF8
  449.                        .SubjectEncoding = Encoding.UTF8
  450.  
  451.                        .Headers.Add("msgId", id) ' store the message id. in the headers.
  452.                        .From = New MailAddress(primaryFromAddress, "primaryFromAddress", Encoding.UTF8)
  453.                        .Subject = subject
  454.                        .IsBodyHtml = True
  455.                        .Body = body
  456.                    End With
  457.  
  458.                    For Each recipient As XElement In recipientList.Elements("item")
  459.                        msg.To.Add(New MailAddress(recipient.Value))
  460.                    Next recipient
  461.  
  462.                    Yield msg
  463.  
  464.                Next item
  465.  
  466.            End Using
  467.  
  468.        End SyncLock
  469.    End Function
  470.  
  471.    ''' <summary>
  472.    ''' Gets the time left to expire the current temporary mail address.
  473.    ''' </summary>
  474.    ''' <returns>
  475.    ''' The time left to expire the current temporary mail address.
  476.    ''' </returns>
  477.    <DebuggerStepThrough>
  478.    Protected Overridable Function GetExpirationTime() As TimeSpan Implements IDisposableMail.GetExpirationTime
  479.        Throw New NotImplementedException("The implementation is not necessary for 10minutemail.com service.")
  480.    End Function
  481.  
  482.    ''' <summary>
  483.    ''' Gets a value indicating whether the current temporary mail is blocked.
  484.    ''' <para></para>
  485.    ''' If <see langword="True"/>,
  486.    ''' this means you have requested too many temporary mail addresses from your IP address too quickly.
  487.    ''' <para></para>
  488.    ''' And you must wait some minutes to be able use 10minutemail.com service again.
  489.    ''' </summary>
  490.    ''' <returns>
  491.    ''' <para></para>
  492.    ''' If <see langword="True"/>,
  493.    ''' this means you have requested too many temporary mail addresses from your IP address too quickly.
  494.    ''' <para></para>
  495.    ''' And you must wait some minutes to be able use 10minutemail.com service again.
  496.    ''' </returns>
  497.    <DebuggerStepThrough>
  498.    Protected Overridable Function GetIsBlocked() As Boolean
  499.        SyncLock (Me.Client)
  500.            Dim value As String = Me.Client.DownloadString(Me.uriBlocked)
  501.            Return CBool(value)
  502.        End SyncLock
  503.    End Function
  504.  
  505.    ''' <summary>
  506.    ''' Renews the life-time for the current temporary mail address.
  507.    ''' </summary>
  508.    ''' <exception cref="WebException">
  509.    ''' You have requested too many temporary mail addresses from your IP address too quickly.
  510.    ''' Please wait some minutes and try again.
  511.    ''' </exception>
  512.    '''
  513.    ''' <exception cref="NotSupportedException">
  514.    ''' Unexpected response value: '{value}'
  515.    ''' </exception>
  516.    <DebuggerStepThrough>
  517.    Protected Overridable Sub Renew() Implements IDisposableMail.Renew
  518.        If (Me.IsBlocked) Then
  519.            Throw New WebException("You have requested too many temporary mail addresses from your IP address too quickly. Please wait some minutes and try again.")
  520.        End If
  521.  
  522.        SyncLock (Me.Client)
  523.            Dim value As String = Me.Client.DownloadString(Me.uriReset)
  524.            If Not (value.Equals("reset", StringComparison.OrdinalIgnoreCase)) Then
  525.                Throw New NotSupportedException(String.Format("Unexpected response value: '{0}'", value))
  526.            End If
  527.        End SyncLock
  528.    End Sub
  529.  
  530.    ''' <summary>
  531.    ''' Handles the calls from <see cref="TenMinuteMail.TimerUpdate"/>.
  532.    ''' </summary>
  533.    ''' <param name="state">
  534.    ''' An object containing application-specific information relevant to the
  535.    ''' method invoked by this delegate, or <see langword="Nothing"/>.
  536.    ''' </param>
  537.    Protected Overridable Sub UpdateTimer_CallBack(ByVal state As Object)
  538.  
  539.        If (Me.Client.IsBusy) Then
  540.            Exit Sub
  541.        End If
  542.  
  543.        SyncLock (Me.Client)
  544.            Me.Renew()
  545.  
  546.            Dim oldMsgCount As Integer = Me.messageCounter
  547.            Dim newMsgCount As Integer = Me.GetMessageCount()
  548.  
  549.            If (newMsgCount > oldMsgCount) Then
  550.                Me.messageCounter = newMsgCount
  551.                Dim messages As IEnumerable(Of MailMessage) = Me.GetMessages()
  552.  
  553.                For msgIndex As Integer = oldMsgCount To (newMsgCount - 1)
  554.                    Me.OnMailMessageArrived(New MailMessageArrivedEventArgs(messages(msgIndex)))
  555.                Next msgIndex
  556.            End If
  557.        End SyncLock
  558.  
  559.    End Sub
  560.  
  561. #End Region
  562.  
  563. #Region " Event Invocators "
  564.  
  565.    ''' <summary>
  566.    ''' Raises the <see cref="TenMinuteMail.MailMessageArrived"/> event.
  567.    ''' </summary>
  568.    ''' <param name="e">
  569.    ''' The <see cref="MailMessageArrivedEventArgs"/> instance containing the event data.
  570.    ''' </param>
  571.    Protected Overridable Sub OnMailMessageArrived(ByVal e As MailMessageArrivedEventArgs)
  572.  
  573.        If (Me.MailMessageArrivedEvent IsNot Nothing) Then
  574.            RaiseEvent MailMessageArrived(Me, e)
  575.        End If
  576.  
  577.    End Sub
  578.  
  579. #End Region
  580.  
  581. #Region " IDisposable Implementation "
  582.  
  583.    ''' <summary>
  584.    ''' Flag to detect redundant calls when disposing.
  585.    ''' </summary>
  586.    Protected isDisposed As Boolean
  587.  
  588.    ''' <summary>
  589.    ''' Releases all the resources used by this instance.
  590.    ''' </summary>
  591.    <DebuggerStepThrough>
  592.    Public Sub Dispose() Implements IDisposable.Dispose
  593.        Me.Dispose(isDisposing:=True)
  594.        GC.SuppressFinalize(obj:=Me)
  595.    End Sub
  596.  
  597.    ''' <summary>
  598.    ''' Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
  599.    ''' Releases unmanaged and, optionally, managed resources.
  600.    ''' </summary>
  601.    ''' <param name="isDisposing">
  602.    ''' <see langword="True"/>  to release both managed and unmanaged resources;
  603.    ''' <see langword="False"/> to release only unmanaged resources.
  604.    ''' </param>
  605.    Protected Overridable Sub Dispose(ByVal isDisposing As Boolean)
  606.        If Not (Me.isDisposed) AndAlso (isDisposing) Then
  607.            Me.MailMessageArrivedEvent = Nothing
  608.  
  609.            Me.TimerUpdate.Dispose()
  610.            Me.TimerUpdate = Nothing
  611.  
  612.            Me.Client.Dispose()
  613.            Me.Client = Nothing
  614.  
  615.            Me.mailAddressB = Nothing
  616.            Me.messageCounter = 0
  617.            Me.isBlockedB = False
  618.  
  619.            Me.uriAddress = Nothing
  620.            Me.uriBase = Nothing
  621.            Me.uriBlocked = Nothing
  622.            Me.uriMessageCount = Nothing
  623.            Me.uriMessages = Nothing
  624.            Me.uriReply = Nothing
  625.            Me.uriReset = Nothing
  626.            Me.uriSecondsLeft = Nothing
  627.        End If
  628.  
  629.        Me.isDisposed = True
  630.    End Sub
  631.  
  632. #End Region
  633.  
  634. End Class
  635.  
  636. #End Region



MODO DE EMPLEO

Un ejemplo simple para crear la dirección temporal y controlar la recepción de nuevos correos entrantes...

Código
  1. Imports System.Net.Mail
  2. Imports System.Text
  3.  
  4. Public NotInheritable Class Form1
  5.  
  6.    Private WithEvents TempMail As TenMinuteMail
  7.  
  8.    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  9.        Me.TempMail = New TenMinuteMail(TimeSpan.FromSeconds(10)) ' Set inbox notification interval to 10 sec.
  10.        Console.WriteLine(String.Format("Your 10MinuteMail Address: '{0}'", Me.TempMail.MailAddress.Address))
  11.    End Sub
  12.  
  13.    ''' ----------------------------------------------------------------------------------------------------
  14.    ''' <summary>
  15.    ''' Handles the <see cref="TenMinuteMail.MailMessageArrived"/> event of the <see cref="Form1.TempMail"/> object.
  16.    ''' </summary>
  17.    ''' ----------------------------------------------------------------------------------------------------
  18.    ''' <param name="sender">
  19.    ''' The source of the event.
  20.    ''' </param>
  21.    '''
  22.    ''' <param name="e">
  23.    ''' The <see cref="MailMessageArrivedEventArgs"/> instance containing the event data.
  24.    ''' </param>
  25.    ''' ----------------------------------------------------------------------------------------------------
  26.    Private Sub TempMail_MailMessageArrived(ByVal sender As Object, ByVal e As MailMessageArrivedEventArgs) _
  27.    Handles TempMail.MailMessageArrived
  28.  
  29.        Dim sb As New StringBuilder()
  30.        With sb
  31.            .AppendLine()
  32.            .AppendLine("NEW MAIL MESSAGE ARRIVED")
  33.            .AppendLine("************************")
  34.            .AppendLine()
  35.            .AppendLine(String.Format("From...: {0}", e.MailMessage.From.Address))
  36.            .AppendLine(String.Format("To.....: {0}", String.Join(";", (From msg As MailAddress In e.MailMessage.To))))
  37.            .AppendLine(String.Format("Subject: {0}", e.MailMessage.Subject))
  38.            .AppendLine(String.Format("Msg.Id.: {0}", e.MailMessage.Headers("msgId")))
  39.            .AppendLine()
  40.            .AppendLine("-------BODY START-------")
  41.            .AppendLine(e.MailMessage.Body)
  42.            .AppendLine("-------BODY END---------")
  43.        End With
  44.  
  45.        Console.WriteLine(sb.ToString())
  46.  
  47.    End Sub
  48.  
  49. End Class

En el ejemplo provisto, el formato a mostrar cuando se recibe un nuevo correo sería algo parecido a esto:

Código:
NEW MAIL MESSAGE ARRIVED
************************

From...: elektrostudios@elhacker.net
To.....: z421459@mvrht.net
Subject: Hello Sir.
Msg.Id.: 6443119781926234531

-------BODY START-------
Hello World!
<br />
<br />
-------BODY END---------

nota: el cuerpo del mensaje se devuelve en formato HTML.

EDITO:
Para responder a un e-mail simplemente deben usar el método TenMinuteMail.Reply pasándole como argumento la instancia del mensaje al que quieren responder, o en su defecto un identificador de mensaje, el cual lo puede encontrar almacenado en la cabecera de un mensaje: MailMessage.Headers("msgId")

Saludos!
« Última modificación: 12 Febrero 2018, 12:23 pm por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.874



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #517 en: 21 Febrero 2018, 12:48 pm »

Un simple snippet donde se hace uso de Reflection para obtener los estilos de control aplicados en un tipo de control específico.

Código
  1.    ''' ----------------------------------------------------------------------------------------------------
  2.    ''' <summary>
  3.    ''' Gets the value of the specified control style bit for the specified control.
  4.    ''' </summary>
  5.    ''' ----------------------------------------------------------------------------------------------------
  6.    ''' <param name="ctrl">
  7.    ''' The source <see cref="Control"/>.
  8.    ''' </param>
  9.    '''
  10.    ''' <param name="styles">
  11.    ''' The <see cref="ControlStyles"/> bit to return the value from.
  12.    ''' </param>
  13.    ''' ----------------------------------------------------------------------------------------------------
  14.    ''' <returns>
  15.    ''' <see langword="True"/> if the specified control style bit is set to <see langword="True"/>;
  16.    ''' otherwise, <see langword="False"/>.
  17.    ''' </returns>
  18.    ''' ----------------------------------------------------------------------------------------------------
  19.    Public Shared Function GetControlStyle(ByVal ctrl As Control, ByVal styles As ControlStyles) As Boolean
  20.  
  21.        Dim t As Type = ctrl.GetType()
  22.        Dim method As MethodInfo = t.GetMethod("GetStyle", BindingFlags.NonPublic Or BindingFlags.Instance)
  23.  
  24.        Return CBool(method.Invoke(ctrl, {styles}))
  25.  
  26.    End Function

Con esto podemos determinar, por ejemplo, si un control acepta transparencia:

Código
  1. dim value as boolean = GetControlStyle(Me.ListView1, ControlStyles.SupportsTransparentBackColor)



Otro snippet, para hacer lo opuesto, es decir, establecer el valor de un estilo de control:

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Sets a specified <see cref="ControlStyles"/> flag to
  4. ''' either <see langword="True"/> or <see langword="False"/> for the source control.
  5. ''' </summary>
  6. ''' ----------------------------------------------------------------------------------------------------
  7. ''' <param name="ctrl">
  8. ''' The source <see cref="Control"/>.
  9. ''' </param>
  10. '''
  11. ''' <param name="style">
  12. ''' The <see cref="ControlStyles"/> bit to set.
  13. ''' </param>
  14. '''
  15. ''' <param name="value">
  16. ''' <see langword="True"/> to apply the specified style to the control; otherwise, <see langword="False"/>.
  17. ''' </param>
  18. ''' ----------------------------------------------------------------------------------------------------
  19. <DebuggerStepThrough>
  20. Public Shared Sub SetControlStyle(ByVal ctrl As Control, ByVal style As ControlStyles, ByVal value As Boolean)
  21.  
  22.    Dim t As Type = ctrl.GetType()
  23.    Dim method As MethodInfo = t.GetMethod("SetStyle", BindingFlags.NonPublic Or BindingFlags.Instance)
  24.  
  25.    method.Invoke(ctrl, {style, value})
  26.  
  27. End Sub
« Última modificación: 21 Febrero 2018, 13:05 pm por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.874



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #518 en: 22 Febrero 2018, 19:31 pm »

Unas extensiones de método para obtener el ancho y alto del borde horizontal y vertical de un Form. Y también para obtener el tamaño de la barra de título (plus la opción de incluir el tamaño de los bordes de la ventana o no):

Código
  1. <HideModuleName>
  2. Public Module FormExtensions
  3.  
  4.    ''' ----------------------------------------------------------------------------------------------------
  5.    ''' <summary>
  6.    ''' Gets the size of the vertical border (the border of the left or right edge) of the source <see cref="Form"/>.
  7.    ''' </summary>
  8.    ''' ----------------------------------------------------------------------------------------------------
  9.    ''' <example> This is a code example.
  10.    ''' <code>
  11.    ''' Dim verticalBorderSize As Size = GetVerticalBorderSize(Me)
  12.    ''' Console.WriteLine(String.Format("Vertical Border Width  = {0}", verticalBorderSize.Width))
  13.    ''' Console.WriteLine(String.Format("Vertical Border Height = {0}", verticalBorderSize.Height))
  14.    ''' </code>
  15.    ''' </example>
  16.    ''' ----------------------------------------------------------------------------------------------------
  17.    ''' <param name="f">
  18.    ''' The source <see cref="Form"/>.
  19.    ''' </param>
  20.    ''' ----------------------------------------------------------------------------------------------------
  21.    ''' <returns>
  22.    ''' The size of the vertical border (the border of the left or right edge) of the source <see cref="Form"/>.
  23.    ''' </returns>
  24.    ''' ----------------------------------------------------------------------------------------------------
  25.    <Extension>
  26.    <EditorBrowsable(EditorBrowsableState.Always)>
  27.    <DebuggerStepThrough>
  28.    Public Function GetVerticalBorderSize(ByVal f As Form) As Size
  29.  
  30.        Select Case f.FormBorderStyle
  31.  
  32.            Case FormBorderStyle.None
  33.                Return Size.Empty
  34.  
  35.            Case FormBorderStyle.Fixed3D
  36.                Return New Size(SystemInformation.FixedFrameBorderSize.Width + SystemInformation.Border3DSize.Width,
  37.                                f.Height)
  38.  
  39.            Case FormBorderStyle.FixedDialog, FormBorderStyle.FixedSingle, FormBorderStyle.FixedToolWindow
  40.                Return New Size(SystemInformation.FixedFrameBorderSize.Width,
  41.                                f.Height)
  42.  
  43.            Case Else
  44.                Return New Size(SystemInformation.FrameBorderSize.Width,
  45.                                f.Height)
  46.  
  47.        End Select
  48.  
  49.    End Function
  50.  
  51.    ''' ----------------------------------------------------------------------------------------------------
  52.    ''' <summary>
  53.    ''' Gets the size of the horizontal border (the border of the top or bottom edge) of the source <see cref="Form"/>.
  54.    ''' </summary>
  55.    ''' ----------------------------------------------------------------------------------------------------
  56.    ''' <example> This is a code example.
  57.    ''' <code>
  58.    ''' Dim horizontalBorderSize As Size = GetHorizontalBorderSize(Me)
  59.    ''' Console.WriteLine(String.Format("Horizontal Border Width  = {0}", horizontalBorderSize.Width))
  60.    ''' Console.WriteLine(String.Format("Horizontal Border Height = {0}", horizontalBorderSize.Height))
  61.    ''' </code>
  62.    ''' </example>
  63.    ''' ----------------------------------------------------------------------------------------------------
  64.    ''' <param name="f">
  65.    ''' The source <see cref="Form"/>.
  66.    ''' </param>
  67.    ''' ----------------------------------------------------------------------------------------------------
  68.    ''' <returns>
  69.    ''' The size of the horizontal border (the border of the top or bottom edge) of the source <see cref="Form"/>.
  70.    ''' </returns>
  71.    ''' ----------------------------------------------------------------------------------------------------
  72.    <Extension>
  73.    <EditorBrowsable(EditorBrowsableState.Always)>
  74.    <DebuggerStepThrough>
  75.    Public Function GetHorizontalBorderSize(ByVal f As Form) As Size
  76.  
  77.        Select Case f.FormBorderStyle
  78.  
  79.            Case FormBorderStyle.None
  80.                Return Size.Empty
  81.  
  82.            Case FormBorderStyle.Fixed3D
  83.                Return New Size(f.Width,
  84.                                SystemInformation.FixedFrameBorderSize.Height + SystemInformation.Border3DSize.Height)
  85.  
  86.            Case FormBorderStyle.FixedDialog, FormBorderStyle.FixedSingle, FormBorderStyle.FixedToolWindow
  87.                Return New Size(f.Width,
  88.                                SystemInformation.FixedFrameBorderSize.Height)
  89.  
  90.            Case Else
  91.                Return New Size(f.Width,
  92.                                SystemInformation.FrameBorderSize.Height)
  93.  
  94.        End Select
  95.  
  96.    End Function
  97.  
  98.    ''' ----------------------------------------------------------------------------------------------------
  99.    ''' <summary>
  100.    ''' Gets the titlebar bounds of the source <see cref="Form"/>.
  101.    ''' </summary>
  102.    ''' ----------------------------------------------------------------------------------------------------
  103.    ''' <example> This is a code example.
  104.    ''' <code>
  105.    ''' Dim titleBarBoundsWithBorders As Rectangle = GetTitleBarBounds(Me, includeBorderSizes:=True)
  106.    ''' Console.WriteLine(String.Format("TitleBar Bounds (including borders) Width  = {0}", titleBarBoundsWithBorders.Width))
  107.    ''' Console.WriteLine(String.Format("TitleBar Bounds (including borders) Height = {0}", titleBarBoundsWithBorders.Height))
  108.    ''' Console.WriteLine(String.Format("TitleBar Bounds (including borders) Pos. X = {0}", titleBarBoundsWithBorders.X))
  109.    ''' Console.WriteLine(String.Format("TitleBar Bounds (including borders) Pos. Y = {0}", titleBarBoundsWithBorders.Y))
  110.    '''
  111.    ''' Dim titleBarBoundsWithoutBorders As Rectangle = GetTitleBarBounds(Me, includeBorderSizes:=False)
  112.    ''' Console.WriteLine(String.Format("TitleBar Bounds (not including borders) Width  = {0}", titleBarBoundsWithoutBorders.Width))
  113.    ''' Console.WriteLine(String.Format("TitleBar Bounds (not including borders) Height = {0}", titleBarBoundsWithoutBorders.Height))
  114.    ''' Console.WriteLine(String.Format("TitleBar Bounds (not including borders) Pos. X = {0}", titleBarBoundsWithoutBorders.X))
  115.    ''' Console.WriteLine(String.Format("TitleBar Bounds (not including borders) Pos. Y = {0}", titleBarBoundsWithoutBorders.Y))
  116.    ''' </code>
  117.    ''' </example>
  118.    ''' ----------------------------------------------------------------------------------------------------
  119.    ''' <param name="f">
  120.    ''' The source <see cref="Form"/>.
  121.    ''' </param>
  122.    '''
  123.    ''' <param name="includeBorderSizes">
  124.    ''' If <see langword="True"/>, the titlebar bounds will include the bounds of the top, left and right border edges.
  125.    ''' <para></para>
  126.    ''' If <see langword="False"/>, the titlebar bounds will NOT include the bounds of the top, left and right border edges.
  127.    ''' </param>
  128.    ''' ----------------------------------------------------------------------------------------------------
  129.    ''' <returns>
  130.    ''' The titlebar bounds (including the border sizes) of the source <see cref="Form"/>.
  131.    ''' </returns>
  132.    ''' ----------------------------------------------------------------------------------------------------
  133.    <Extension>
  134.    <EditorBrowsable(EditorBrowsableState.Always)>
  135.    <DebuggerStepThrough>
  136.    Public Function GetTitleBarBounds(ByVal f As Form, ByVal includeBorderSizes As Boolean) As Rectangle
  137.  
  138.        If (includeBorderSizes) Then
  139.            Select Case f.FormBorderStyle
  140.  
  141.                Case FormBorderStyle.None
  142.                    Return Rectangle.Empty
  143.  
  144.                Case FormBorderStyle.Fixed3D
  145.                    Return New Rectangle(New Point(0, 0),
  146.                                         New Size(f.Width, SystemInformation.CaptionHeight + SystemInformation.FixedFrameBorderSize.Height + SystemInformation.Border3DSize.Height))
  147.  
  148.                Case FormBorderStyle.FixedToolWindow
  149.                    Return New Rectangle(New Point(0, 0),
  150.                                         New Size(f.Width, SystemInformation.ToolWindowCaptionHeight + SystemInformation.FixedFrameBorderSize.Height))
  151.  
  152.                Case FormBorderStyle.SizableToolWindow
  153.                    Return New Rectangle(New Point(0, 0),
  154.                                         New Size(f.Width, SystemInformation.ToolWindowCaptionHeight + SystemInformation.FrameBorderSize.Height))
  155.  
  156.                Case FormBorderStyle.FixedDialog, FormBorderStyle.FixedSingle
  157.                    Return New Rectangle(New Point(0, 0),
  158.                                         New Size(f.Width, SystemInformation.CaptionHeight + SystemInformation.FixedFrameBorderSize.Height))
  159.  
  160.                Case Else
  161.                    Return New Rectangle(New Point(0, 0),
  162.                                         New Size(f.Width, SystemInformation.CaptionHeight + SystemInformation.FrameBorderSize.Height))
  163.  
  164.            End Select
  165.  
  166.        Else
  167.            Dim verticalBorderSize As Size = FormExtensions.GetVerticalBorderSize(f)
  168.            Dim horizontalBorderSize As Size = FormExtensions.GetHorizontalBorderSize(f)
  169.  
  170.            Select Case f.FormBorderStyle
  171.  
  172.                Case FormBorderStyle.None
  173.                    Return Rectangle.Empty
  174.  
  175.                Case FormBorderStyle.FixedToolWindow, FormBorderStyle.SizableToolWindow
  176.                    Return New Rectangle(New Point(verticalBorderSize.Width, horizontalBorderSize.Height),
  177.                                     New Size(f.ClientRectangle.Width, SystemInformation.ToolWindowCaptionHeight))
  178.  
  179.                Case Else
  180.                    Return New Rectangle(New Point(verticalBorderSize.Width, horizontalBorderSize.Height),
  181.                                     New Size(f.ClientRectangle.Width, SystemInformation.CaptionHeight))
  182.  
  183.            End Select
  184.  
  185.        End If
  186.  
  187.    End Function
  188.  
  189. End Module

Lo he probado con todos los tipos de estilos de form, y temas de terceros, parece funcionar correctamente en todos los casos, pero no descarto quizás haber cometido algún error en alguno de los cálculos de algún estilo de form, si encuentran algo me avisan.

Aquí les dejo un test de unidad que utilicé:

Código
  1. <TestMethod()>
  2. Public Sub TestNonClientAreaMeasures()
  3.  
  4.    Using f As New Form With {.Size = New Size(100, 100)}
  5.  
  6.        For Each style As FormBorderStyle In [Enum].GetValues(GetType(FormBorderStyle))
  7.  
  8.            Console.WriteLine(String.Format("Testing form border style: {0}", style.ToString()))
  9.            If (style = FormBorderStyle.None) Then
  10.                ' Zero border size and no title bar, so nothing to do here.
  11.                Continue For
  12.            End If
  13.  
  14.            f.FormBorderStyle = style
  15.            f.Show()
  16.  
  17.            Dim titlebarBounds As Rectangle = FormExtensions.GetTitleBarBounds(f, True) ' includes border bounds.
  18.            Dim titlebarBoundsWitoutBorders As Rectangle = FormExtensions.GetTitleBarBounds(f, False) ' not includes border bounds.
  19.  
  20.            Dim verticalBorderSize As Size = FormExtensions.GetVerticalBorderSize(f)
  21.            Dim horizontalBorderSize As Size = FormExtensions.GetHorizontalBorderSize(f)
  22.  
  23.            Dim formSize As Size = f.Bounds.Size ' includes non-client size.
  24.            Dim formClientSize As Size = f.ClientRectangle.Size ' client size only.
  25.            Dim formNonClientSize As New Size((formSize.Width - formClientSize.Width), ' non-client size only.
  26.                                          (formSize.Height - formClientSize.Height))
  27.  
  28.            Assert.AreEqual(formNonClientSize.Width, (verticalBorderSize.Width * 2),
  29.                        Environment.NewLine & Environment.NewLine &
  30.                        String.Format("Value of '{0} * 2' ({1}) and '{2}' ({3}) are not equal.",
  31.                                      "verticalBorderSize.Width", (verticalBorderSize.Width * 2),
  32.                                      "formNonClientSize.Width", formNonClientSize.Width))
  33.  
  34.            Assert.AreEqual(formClientSize.Width, titlebarBoundsWitoutBorders.Width,
  35.                        Environment.NewLine & Environment.NewLine &
  36.                        String.Format("Value of '{0}' ({1}) and '{2}' ({3}) are not equal.",
  37.                                      "titlebarBoundsWitoutBorders.Width", titlebarBoundsWitoutBorders.Width,
  38.                                      "formClientSize.Width", formClientSize.Width))
  39.  
  40.            Assert.AreEqual(formSize.Width, titlebarBounds.Width,
  41.                        Environment.NewLine & Environment.NewLine &
  42.                        String.Format("Value of '{0}' ({1}) and '{2}' ({3}) are not equal.",
  43.                                      "titlebarBounds.Width", titlebarBounds.Width,
  44.                                      "formSize.Width", formSize.Width))
  45.  
  46.            Assert.AreEqual(titlebarBounds.Height, (titlebarBoundsWitoutBorders.Height + horizontalBorderSize.Height),
  47.                        Environment.NewLine & Environment.NewLine &
  48.                        String.Format("Sum of '{0} + {1}' ({2}) and '{3}' ({4}) are not equal.",
  49.                                      "titlebarBoundsWitoutBorders.Height", "horizontalBorderSize.Height",
  50.                                      (titlebarBoundsWitoutBorders.Height + horizontalBorderSize.Height),
  51.                                      "titlebarBounds.Height", titlebarBounds.Height))
  52.  
  53.            Assert.AreEqual(formSize.Height, formClientSize.Height + titlebarBoundsWitoutBorders.Height + (horizontalBorderSize.Height * 2),
  54.                        Environment.NewLine & Environment.NewLine &
  55.                        String.Format("Sum of '{0} + {1} + ({2} * 2)' ({3}) and '{4}' ({5}) are not equal.",
  56.                                      "formClientSize.Height", "titlebarBoundsWitoutBorders.Height", "horizontalBorderSize.Height",
  57.                                      formClientSize.Height + titlebarBoundsWitoutBorders.Height + (horizontalBorderSize.Height * 2),
  58.                                      "formSize.Height", formSize.Height))
  59.  
  60.            Assert.AreEqual(formNonClientSize.Height, (titlebarBounds.Height + horizontalBorderSize.Height),
  61.                        Environment.NewLine & Environment.NewLine &
  62.                        String.Format("Sum of '{0} + {1}' ({2}) and '{3}' ({4}) are not equal.",
  63.                                      "titlebarBounds.Height", "horizontalBorderSize.Height",
  64.                                      (titlebarBounds.Height + horizontalBorderSize.Height),
  65.                                      "formNonClientSize.Height", formNonClientSize.Height))
  66.  
  67.            f.Hide()
  68.        Next style
  69.  
  70.    End Using
  71.  
  72. End Sub



Este método sirve para 'bloquear' la región visible de un Form, a los límites visibles de los controles hijos. El resultado es un Form con un fondo invisible y los controles visibles. Añadí una sobrecarga para poder especificar el tipo de control.

IMPORTANTE: este código utiliza las extensiones de método del módulo FormExtensions que compartí en este comentario más arriba... así que no se olviden de copiar ese código.

Código
  1.    ''' ----------------------------------------------------------------------------------------------------
  2.    ''' <summary>
  3.    ''' Locks the window region of the specified <see cref="Form"/> to the bounds of its child controls.
  4.    ''' </summary>
  5.    ''' ----------------------------------------------------------------------------------------------------
  6.    ''' <example> This is a code example.
  7.    ''' <code>
  8.    ''' LockFormRegionToControls(Me)
  9.    ''' </code>
  10.    ''' </example>
  11.    ''' ----------------------------------------------------------------------------------------------------
  12.    ''' <param name="f">
  13.    ''' The source <see cref="Form"/>.
  14.    ''' </param>
  15.    ''' ----------------------------------------------------------------------------------------------------
  16.    ''' <exception cref="NotImplementedException">
  17.    ''' </exception>
  18.    ''' ----------------------------------------------------------------------------------------------------
  19.    Public Shared Sub LockFormRegionToControls(ByVal f As Form)
  20.  
  21.        LockFormRegionToControls(Of Control)(f)
  22.  
  23.    End Sub
  24.  
  25.    ''' ----------------------------------------------------------------------------------------------------
  26.    ''' <summary>
  27.    ''' Locks the window region of the specified <see cref="Form"/> to the bounds of its child controls
  28.    ''' of the specified <see cref="Type"/>.
  29.    ''' </summary>
  30.    ''' ----------------------------------------------------------------------------------------------------
  31.    ''' <example> This is a code example.
  32.    ''' <code>
  33.    ''' LockFormRegionToControls(Of Button)(Me)
  34.    ''' </code>
  35.    ''' </example>
  36.    ''' ----------------------------------------------------------------------------------------------------
  37.    ''' <typeparam name="T">
  38.    ''' The <see cref="Type"/> of control.
  39.    ''' </typeparam>
  40.    '''
  41.    ''' <param name="f">
  42.    ''' The source <see cref="Form"/>.
  43.    ''' </param>
  44.    ''' ----------------------------------------------------------------------------------------------------
  45.    ''' <exception cref="NotImplementedException">
  46.    ''' </exception>
  47.    ''' ----------------------------------------------------------------------------------------------------
  48.    Public Shared Sub LockFormRegionToControls(Of T As Control)(ByVal f As Form)
  49.  
  50.        Select Case f.FormBorderStyle
  51.  
  52.            Case FormBorderStyle.FixedToolWindow, FormBorderStyle.SizableToolWindow
  53.                Throw New NotImplementedException()
  54.  
  55.            Case Else
  56.                Dim vBorderSize As Size = FormExtensions.GetVerticalBorderSize(f)
  57.                Dim tbBounds As Rectangle = FormExtensions.GetTitleBarBounds(f, includeBorderSizes:=True)
  58.  
  59.                Dim rects As IEnumerable(Of Rectangle) =
  60.                    (From ctrl As T In f.Controls.OfType(Of T)()
  61.                     Order By f.Controls.GetChildIndex(ctrl) Ascending
  62.                     Select ctrl.Bounds)
  63.  
  64.                Using rgn As New Region(New Rectangle(0, 0, f.Width, f.Height))
  65.                    rgn.MakeEmpty()
  66.  
  67.                    For Each rect As Rectangle In rects
  68.                        rgn.Union(rect)
  69.                    Next rect
  70.                    rgn.Translate(vBorderSize.Width, tbBounds.Height)
  71.  
  72.                    If (f.Region IsNot Nothing) Then
  73.                        f.Region.Dispose()
  74.                    End If
  75.                    f.Region = rgn
  76.                End Using
  77.  
  78.        End Select
  79.  
  80.    End Sub
« Última modificación: 22 Febrero 2018, 19:56 pm por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.874



Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #519 en: 25 Febrero 2018, 20:51 pm »

Un código simple y sencillo para obtener o establecer el modo de emulación de Internet Explorer en nuestra aplicación o para otra aplicación.

EDITO: código corregido, y refactorizado.

Código
  1.    ''' ----------------------------------------------------------------------------------------------------
  2.    ''' <summary>
  3.    ''' Specifies a Internet Explorer browser emulation mode.
  4.    ''' </summary>
  5.    ''' ----------------------------------------------------------------------------------------------------
  6.    ''' <remarks>
  7.    ''' <see href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)"/>
  8.    ''' </remarks>
  9.    ''' ----------------------------------------------------------------------------------------------------
  10.    Public Enum IEBrowserEmulationMode As Integer
  11.  
  12.        ''' <summary>
  13.        ''' Webpages containing standards-based !DOCTYPE directives are displayed in IE7 Standards mode.
  14.        ''' </summary>
  15.        IE7 = 7000
  16.  
  17.        ''' <summary>
  18.        ''' Webpages containing standards-based !DOCTYPE directives are displayed in IE8 mode.
  19.        ''' </summary>
  20.        IE8 = 8000
  21.  
  22.        ''' <summary>
  23.        ''' Webpages are displayed in IE8 Standards mode, regardless of the declared !DOCTYPE directive.
  24.        ''' <para></para>
  25.        ''' Failing to declare a !DOCTYPE directive causes the page to load in Quirks.
  26.        ''' </summary>
  27.        IE8Standards = 8888
  28.  
  29.        ''' <summary>
  30.        ''' Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode.
  31.        ''' </summary>
  32.        IE9 = 9000
  33.  
  34.        ''' <summary>
  35.        ''' Webpages are displayed in IE9 Standards mode, regardless of the declared !DOCTYPE directive.
  36.        ''' <para></para>
  37.        ''' Failing to declare a !DOCTYPE directive causes the page to load in Quirks.
  38.        ''' </summary>
  39.        IE9Standards = 9999
  40.  
  41.        ''' <summary>
  42.        ''' Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode.
  43.        ''' </summary>
  44.        IE10 = 10000
  45.  
  46.        ''' <summary>
  47.        ''' Webpages are displayed in IE10 Standards mode, regardless of the !DOCTYPE directive.
  48.        ''' </summary>
  49.        IE10Standards = 10001
  50.  
  51.        ''' <summary>
  52.        ''' Webpages containing standards-based !DOCTYPE directives are displayed in IE11 edge mode.
  53.        ''' </summary>
  54.        IE11 = 11000
  55.  
  56.        ''' <summary>
  57.        ''' Webpages are displayed in IE11 edge mode, regardless of the declared !DOCTYPE directive.
  58.        ''' <para></para>
  59.        ''' Failing to declare a !DOCTYPE directive causes the page to load in Quirks.
  60.        ''' </summary>
  61.        IE11Edge = 11001
  62.  
  63.    End Enum

+

Código
  1.    ''' ----------------------------------------------------------------------------------------------------
  2.    ''' <summary>
  3.    ''' Specifies a registry scope (a root key).
  4.    ''' </summary>
  5.    ''' ----------------------------------------------------------------------------------------------------
  6.    Public Enum RegistryScope As Integer
  7.  
  8.        ''' <summary>
  9.        ''' This refers to the HKEY_LOCAL_MACHINE (or HKLM) registry root key.
  10.        ''' <para></para>
  11.        ''' Configuration changes made on the subkeys of this root key will affect all users.
  12.        ''' </summary>
  13.        Machine = 0
  14.  
  15.        ''' <summary>
  16.        ''' This refers to the HKEY_CURRENT_USER (or HKCU) registry root key.
  17.        ''' <para></para>
  18.        ''' Configuration changes made on the subkeys of this root key will affect only the current user.
  19.        ''' </summary>
  20.        CurrentUser = 1
  21.  
  22.    End Enum

+

Código
  1.        ''' ----------------------------------------------------------------------------------------------------
  2.        ''' <summary>
  3.        ''' Gets or sets the Internet Explorer browser emulation mode for the current application.
  4.        ''' </summary>
  5.        ''' ----------------------------------------------------------------------------------------------------
  6.        ''' <seealso href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)"/>
  7.        ''' ----------------------------------------------------------------------------------------------------
  8.        ''' <example> This is a code example to get, set and verify the IE browser emulation mode for the current process.
  9.        ''' <code>
  10.        ''' Dim scope As RegistryScope = RegistryScope.CurrentUser
  11.        ''' Dim oldMode As IEBrowserEmulationMode
  12.        ''' Dim newMode As IEBrowserEmulationMode
  13.        '''
  14.        ''' oldMode = BrowserEmulationMode(scope)
  15.        ''' BrowserEmulationMode(scope) = IEBrowserEmulationMode.IE11Edge
  16.        ''' newMode = BrowserEmulationMode(scope)
  17.        '''
  18.        ''' Console.WriteLine(String.Format("Old Mode: {0} ({1})", oldMode, CStr(oldMode)))
  19.        ''' Console.WriteLine(String.Format("New Mode: {0} ({1})", newMode, CStr(newMode)))
  20.        '''
  21.        ''' Dim f As New Form() With {.Size = New Size(1280, 720)}
  22.        ''' Dim wb As New WebBrowser With {.Dock = DockStyle.Fill}
  23.        ''' f.Controls.Add(wb)
  24.        ''' f.Show()
  25.        ''' wb.Navigate("http://www.whatversion.net/browser/")
  26.        ''' </code>
  27.        ''' </example>
  28.        ''' ----------------------------------------------------------------------------------------------------
  29.        ''' <param name="scope">
  30.        ''' The registry scope.
  31.        ''' </param>
  32.        ''' ----------------------------------------------------------------------------------------------------
  33.        ''' <value>
  34.        ''' The Internet Explorer browser emulation mode.
  35.        ''' </value>
  36.        ''' ----------------------------------------------------------------------------------------------------
  37.        Public Shared Property BrowserEmulationMode(ByVal scope As RegistryScope) As IEBrowserEmulationMode
  38.            <DebuggerStepThrough>
  39.            Get
  40.                Return AppUtil.GetIEBrowserEmulationMode(Process.GetCurrentProcess().ProcessName, scope)
  41.            End Get
  42.            <DebuggerStepThrough>
  43.            Set(value As IEBrowserEmulationMode)
  44.                AppUtil.SetIEBrowserEmulationMode(Process.GetCurrentProcess().ProcessName, scope, value)
  45.            End Set
  46.        End Property
  47.  

+

Código
  1.        ''' ----------------------------------------------------------------------------------------------------
  2.        ''' <summary>
  3.        ''' Gets the Internet Explorer browser emulation mode for the specified process.
  4.        ''' </summary>
  5.        ''' ----------------------------------------------------------------------------------------------------
  6.        ''' <seealso href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)"/>
  7.        ''' ----------------------------------------------------------------------------------------------------
  8.        ''' <example> This is a code example.
  9.        ''' <code>
  10.        ''' Dim processName As String = Process.GetCurrentProcess().ProcessName
  11.        ''' Dim scope As RegistryScope = RegistryScope.CurrentUser
  12.        ''' Dim mode As IEBrowserEmulationMode = GetIEBrowserEmulationMode(processName, scope)
  13.        '''
  14.        ''' Console.WriteLine(String.Format("Mode: {0} ({1})", mode, CStr(mode)))
  15.        ''' </code>
  16.        ''' </example>
  17.        ''' ----------------------------------------------------------------------------------------------------
  18.        ''' <param name="processName">
  19.        ''' The process name (eg. 'cmd.exe').
  20.        ''' </param>
  21.        '''
  22.        ''' <param name="scope">
  23.        ''' The registry scope.
  24.        ''' </param>
  25.        ''' ----------------------------------------------------------------------------------------------------
  26.        ''' <returns>
  27.        ''' The resulting <see cref="IEBrowserEmulationMode"/>.
  28.        ''' </returns>
  29.        ''' ----------------------------------------------------------------------------------------------------
  30.        ''' <exception cref="NotSupportedException">
  31.        ''' </exception>
  32.        ''' ----------------------------------------------------------------------------------------------------
  33.        <DebuggerStepThrough>
  34.        Public Shared Function GetIEBrowserEmulationMode(ByVal processName As String, ByVal scope As RegistryScope) As IEBrowserEmulationMode
  35.  
  36.            processName = Path.GetFileNameWithoutExtension(processName)
  37.  
  38.            Using rootKey As RegistryKey = If(scope = RegistryScope.CurrentUser,
  39.                                              RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default),
  40.                                              RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default)),
  41.                  subKey As RegistryKey = rootKey.CreateSubKey("Software\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION",
  42.                                                               RegistryKeyPermissionCheck.ReadSubTree)
  43.  
  44.                Dim value As Integer =
  45.                    CInt(subKey.GetValue(String.Format("{0}.exe", processName), 0, RegistryValueOptions.None))
  46.  
  47.                ' If no browser emulation mode is retrieved from registry, then return default version for WebBrowser control.
  48.                If (value = 0) Then
  49.                    Return IEBrowserEmulationMode.IE7
  50.                End If
  51.  
  52.                If [Enum].IsDefined(GetType(IEBrowserEmulationMode), value) Then
  53.                    Return DirectCast(value, IEBrowserEmulationMode)
  54.  
  55.                Else
  56.                    Throw New NotSupportedException(String.Format("Unrecognized browser emulation version: {0}", value))
  57.  
  58.                End If
  59.  
  60.            End Using
  61.  
  62.        End Function
  63.  
  64.        ''' ----------------------------------------------------------------------------------------------------
  65.        ''' <summary>
  66.        ''' Gets the Internet Explorer browser emulation mode for the specified process.
  67.        ''' </summary>
  68.        ''' ----------------------------------------------------------------------------------------------------
  69.        ''' <seealso href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)"/>
  70.        ''' ----------------------------------------------------------------------------------------------------
  71.        ''' <example> This is a code example.
  72.        ''' <code>
  73.        ''' Dim p As Process = Process.GetCurrentProcess()
  74.        ''' Dim scope As RegistryScope = RegistryScope.CurrentUser
  75.        ''' Dim mode As IEBrowserEmulationMode = GetIEBrowserEmulationMode(p, scope)
  76.        '''
  77.        ''' Console.WriteLine(String.Format("Mode: {0} ({1})", mode, CStr(mode)))
  78.        ''' </code>
  79.        ''' </example>
  80.        ''' ----------------------------------------------------------------------------------------------------
  81.        ''' <param name="p">
  82.        ''' The process.
  83.        ''' </param>
  84.        '''
  85.        ''' <param name="scope">
  86.        ''' The registry scope.
  87.        ''' </param>
  88.        ''' ----------------------------------------------------------------------------------------------------
  89.        ''' <returns>
  90.        ''' The resulting <see cref="IEBrowserEmulationMode"/>.
  91.        ''' </returns>
  92.        ''' ----------------------------------------------------------------------------------------------------
  93.        ''' <exception cref="NotSupportedException">
  94.        ''' </exception>
  95.        ''' ----------------------------------------------------------------------------------------------------
  96.        <DebuggerStepThrough>
  97.        Public Shared Function GetIEBrowserEmulationMode(ByVal p As Process, ByVal scope As RegistryScope) As IEBrowserEmulationMode
  98.  
  99.            Return AppUtil.GetIEBrowserEmulationMode(p.ProcessName, scope)
  100.  
  101.        End Function
  102.  
  103.        ''' ----------------------------------------------------------------------------------------------------
  104.        ''' <summary>
  105.        ''' Sets the Internet Explorer browser emulation mode for the specified process.
  106.        ''' </summary>
  107.        ''' ----------------------------------------------------------------------------------------------------
  108.        ''' <seealso href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)"/>
  109.        ''' ----------------------------------------------------------------------------------------------------
  110.        ''' <example> This is a code example.
  111.        ''' <code>
  112.        ''' Dim processName As String = Process.GetCurrentProcess().ProcessName
  113.        ''' Dim scope As RegistryScope = RegistryScope.CurrentUser
  114.        ''' Dim oldMode As IEBrowserEmulationMode
  115.        ''' Dim newMode As IEBrowserEmulationMode
  116.        '''
  117.        ''' oldMode = GetIEBrowserEmulationMode(processName, scope)
  118.        ''' SetIEBrowserEmulationMode(processName, scope, IEBrowserEmulationMode.IE11Edge)
  119.        ''' newMode = GetIEBrowserEmulationMode(processName, scope)
  120.        '''
  121.        ''' Console.WriteLine(String.Format("Old Mode: {0} ({1})", oldMode, CStr(oldMode)))
  122.        ''' Console.WriteLine(String.Format("New Mode: {0} ({1})", newMode, CStr(newMode)))
  123.        '''
  124.        ''' Dim f As New Form() With {.Size = New Size(1280, 720)}
  125.        ''' Dim wb As New WebBrowser With {.Dock = DockStyle.Fill}
  126.        ''' f.Controls.Add(wb)
  127.        ''' f.Show()
  128.        ''' wb.Navigate("http://www.whatversion.net/browser/")
  129.        ''' </code>
  130.        ''' </example>
  131.        ''' ----------------------------------------------------------------------------------------------------
  132.        ''' <param name="processName">
  133.        ''' The process name (eg. 'cmd.exe').
  134.        ''' </param>
  135.        '''
  136.        ''' <param name="scope">
  137.        ''' The registry scope.
  138.        ''' </param>
  139.        '''
  140.        ''' <param name="mode">
  141.        ''' The Internet Explorer browser emulation mode to set.
  142.        ''' </param>
  143.        ''' ----------------------------------------------------------------------------------------------------
  144.        ''' <exception cref="NotSupportedException">
  145.        ''' </exception>
  146.        ''' ----------------------------------------------------------------------------------------------------
  147.        <DebuggerStepThrough>
  148.        Public Shared Sub SetIEBrowserEmulationMode(ByVal processName As String, ByVal scope As RegistryScope, ByVal mode As IEBrowserEmulationMode)
  149.  
  150.            processName = Path.GetFileNameWithoutExtension(processName)
  151.  
  152.            Dim currentIEBrowserEmulationMode As IEBrowserEmulationMode = GetIEBrowserEmulationMode(processName, scope)
  153.            If (currentIEBrowserEmulationMode = mode) Then
  154.                Exit Sub
  155.            End If
  156.  
  157.            Using rootKey As RegistryKey = If(scope = RegistryScope.CurrentUser,
  158.                                              RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default),
  159.                                              RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default)),
  160.                  regKey As RegistryKey = rootKey.CreateSubKey(
  161.                            "Software\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION",
  162.                            RegistryKeyPermissionCheck.ReadWriteSubTree)
  163.  
  164.                regKey.SetValue(String.Format("{0}.exe", processName),
  165.                                DirectCast(mode, Integer), RegistryValueKind.DWord)
  166.  
  167.            End Using
  168.  
  169.        End Sub
  170.  
  171.        ''' ----------------------------------------------------------------------------------------------------
  172.        ''' <summary>
  173.        ''' Sets the Internet Explorer browser emulation mode for the specified process.
  174.        ''' </summary>
  175.        ''' ----------------------------------------------------------------------------------------------------
  176.        ''' <seealso href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)"/>
  177.        ''' ----------------------------------------------------------------------------------------------------
  178.        ''' <example> This is a code example.
  179.        ''' <code>
  180.        ''' Dim processName As Process = Process.GetCurrentProcess()
  181.        ''' Dim scope As RegistryScope = RegistryScope.CurrentUser
  182.        ''' Dim oldMode As IEBrowserEmulationMode
  183.        ''' Dim newMode As IEBrowserEmulationMode
  184.        '''
  185.        ''' oldMode = GetIEBrowserEmulationMode(p, scope)
  186.        ''' SetIEBrowserEmulationMode(p, scope, IEBrowserEmulationMode.IE11Edge)
  187.        ''' newMode = GetIEBrowserEmulationMode(p, scope)
  188.        '''
  189.        ''' Console.WriteLine(String.Format("Old Mode: {0} ({1})", oldMode, CStr(oldMode)))
  190.        ''' Console.WriteLine(String.Format("New Mode: {0} ({1})", newMode, CStr(newMode)))
  191.        '''
  192.        ''' Dim f As New Form() With {.Size = New Size(1280, 720)}
  193.        ''' Dim wb As New WebBrowser With {.Dock = DockStyle.Fill}
  194.        ''' f.Controls.Add(wb)
  195.        ''' f.Show()
  196.        ''' wb.Navigate("http://www.whatversion.net/browser/")
  197.        ''' </code>
  198.        ''' </example>
  199.        ''' ----------------------------------------------------------------------------------------------------
  200.        ''' <param name="p">
  201.        ''' The process.
  202.        ''' </param>
  203.        '''
  204.        ''' <param name="scope">
  205.        ''' The registry scope.
  206.        ''' </param>
  207.        '''
  208.        ''' <param name="mode">
  209.        ''' The Internet Explorer browser emulation mode to set.
  210.        ''' </param>
  211.        ''' ----------------------------------------------------------------------------------------------------
  212.        ''' <exception cref="NotSupportedException">
  213.        ''' </exception>
  214.        ''' ----------------------------------------------------------------------------------------------------
  215.        <DebuggerStepThrough>
  216.        Public Shared Sub SetIEBrowserEmulationMode(ByVal p As Process, ByVal scope As RegistryScope, ByVal mode As IEBrowserEmulationMode)
  217.  
  218.            AppUtil.SetIEBrowserEmulationMode(p.ProcessName, scope, mode)
  219.  
  220.        End Sub
  221.  

Ejemplo de uso para obtener, establecer y verificar el modo de emulación del proceso actual:

Código
  1.    Dim scope As RegistryScope = RegistryScope.CurrentUser
  2.    Dim oldMode As IEBrowserEmulationMode
  3.    Dim newMode As IEBrowserEmulationMode
  4.  
  5.    oldMode = BrowserEmulationMode(scope)
  6.    BrowserEmulationMode(scope) = IEBrowserEmulationMode.IE11Edge
  7.    newMode = BrowserEmulationMode(scope)
  8.  
  9.    Console.WriteLine(String.Format("Old Mode: {0} ({1})", oldMode, CStr(oldMode)))
  10.    Console.WriteLine(String.Format("New Mode: {0} ({1})", newMode, CStr(newMode)))
  11.  
  12.    Dim f As New Form() With {.Size = New Size(1280, 720)}
  13.    Dim wb As New WebBrowser With {.Dock = DockStyle.Fill}
  14.    f.Controls.Add(wb)
  15.    f.Show()
  16.    wb.Navigate("http://www.whatversion.net/browser/")

Ejemplo de uso para obtener, establecer y verificar el modo de emulación de un proceso específico:

Código
  1.    Dim processName As String = Process.GetCurrentProcess().ProcessName
  2.    Dim scope As RegistryScope = RegistryScope.CurrentUser
  3.    Dim oldMode As IEBrowserEmulationMode
  4.    Dim newMode As IEBrowserEmulationMode
  5.  
  6.    oldMode = GetIEBrowserEmulationMode(processName, scope)
  7.    SetIEBrowserEmulationMode(processName, scope, IEBrowserEmulationMode.IE11Edge)
  8.    newMode = GetIEBrowserEmulationMode(processName, scope)
  9.  
  10.    Console.WriteLine(String.Format("Old Mode: {0} ({1})", oldMode, CStr(oldMode)))
  11.    Console.WriteLine(String.Format("New Mode: {0} ({1})", newMode, CStr(newMode)))
  12.  
  13.    Dim f As New Form() With {.Size = New Size(1280, 720)}
  14.    Dim wb As New WebBrowser With {.Dock = DockStyle.Fill}
  15.    f.Controls.Add(wb)
  16.    f.Show()
  17.    wb.Navigate("http://www.whatversion.net/browser/")

Saludos.
« Última modificación: 25 Febrero 2018, 23:36 pm por Eleкtro » En línea



Páginas: 1 ... 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 [52] 53 54 55 56 57 58 59 60 Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines