FreeBSD 8.1 Released today!
So I was browsing the FreeBSD Ftp yesterday and saw that FreeBSD 8.1-Release ISOs were available, and I almost jumped the gun and announced this yesterday.
So I was browsing the FreeBSD Ftp yesterday and saw that FreeBSD 8.1-Release ISOs were available, and I almost jumped the gun and announced this yesterday.
Yes, Duct Tape gets to add one more use to it already long bag of tricks.
Ok, this is seriously hilarious. Consumer Reports is very reputable. They don’t recommend the iPhone4 but recommend that if you have one, you fix it with Duct Tape.
Can there be anything funnier?
Question: How do you know all software programmers are crazy?
Answer: All their code has to be committed.
A Laffy Taffy style joke by Mark Minson
Hey all,
Here is a simple example of starting and stopping a service in C++. Just pass the service name as a parameter and the service will switch states. If stopped, it will start. If started, it will stop.
// StartStopService.cpp : Defines the entry point for the console application.
//
#include “stdafx.h”
#include
#include
int _tmain(int argc, _TCHAR* argv[])
{
SC_HANDLE serviceDbHandle = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
SC_HANDLE serviceHandle = OpenService(serviceDbHandle, argv[1], SC_MANAGER_ALL_ACCESS);
SERVICE_STATUS_PROCESS status;
DWORD bytesNeeded;
QueryServiceStatusEx(serviceHandle, SC_STATUS_PROCESS_INFO,(LPBYTE) &status,sizeof(SERVICE_STATUS_PROCESS), &bytesNeeded);
if (status.dwCurrentState == SERVICE_RUNNING)
{// Stop it
BOOL b = ControlService(serviceHandle, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS) &status);
if (b)
{
std::cout << "Service stopped." << std::endl;
}
else
{
std::cout << "Service failed to stop." << std::endl;
}
}
else
{// Start it
BOOL b = StartService(serviceHandle, NULL, NULL);
if (b)
{
std::cout << "Service started." << std::endl;
}
else
{
std::cout << "Service failed to start." << std::endl;
}
}
CloseServiceHandle(serviceHandle);
CloseServiceHandle(serviceDbHandle);
return 0;
}
[/sourcecode]
Hey all,
Here is a simple example of creating or deleting a windows share in C++.
// CreateShare.cpp : Defines the entry point for the console application.
//
#include “stdafx.h”
#include
#include
#include “lm.h”
int _tmain(int argc, _TCHAR* argv[])
{
// Create share
if (0 == _tcscmp(argv[1], _T(“create”)))
{
SHARE_INFO_2 si =
{
L”ShareName”,
STYPE_DISKTREE,
L”Any nice comment or remark”,
ACCESS_READ,
DWORD(-1),
0,
L”C:\\Users\\jbarneck\\Desktop\\Share”,
L””
};
DWORD parameterError = 0;
DWORD status = NetShareAdd(NULL, 2, (BYTE *) &si, ¶meterError);
if (status != ERROR_SUCCESS)
{
std::cout << "Error: " << status << std::endl;
if (status == ERROR_ACCESS_DENIED) // 5L in WinError.h
{
std::cout << "Access denied." << std::endl;
}
if (status == NERR_ServerNotStarted) // 2114 in LMErr.h
{
std::cout << "The Server service is stopped." << std::endl;
}
if (status == NERR_DuplicateShare) // 2118 in LMErr.h
{
std::cout << "The share already exists." << std::endl;
}
}
// End program
return 0;
}
// Delete share
if (0 == _tcscmp(argv[1], _T("delete")))
{
DWORD status = NetShareDel(NULL, L"ShareName", 0);
if (status != ERROR_SUCCESS)
{
std::cout << "Could not delete share: " << status << std::endl;
}
// End program
return 0;
}
}
[/sourcecode]
References:
NetShareAdd - http://msdn.microsoft.com/en-us/library/bb525384%28VS.85%29.aspx
NetShareDel - http://msdn.microsoft.com/en-us/library/bb525386%28v=VS.85%29.aspx
Ok, so I need to determine if a patch has been applied to an MSI. Lets start with Enumerating the installed products and enumerating all the patches applied for each installed product.
I guess the title should be “How to enumerate installed MSI products and their applied MSP patches.”
I have to do it in C++, which is a drag because it looked like three lines of code in C#, but hey, maybe it isn’t so hard with C++ using .NET as well.
I researched on MSDN, of course. It looks like I need to use this function: MsiGetPatchInfoEx. However, I need to know the MSI GUID in order to use that function, so I might as well learn to use the MsiEnumProducts, MsiGetProductInfo, MsiEnumPatches to match the Product to an MSI Guid and that to a patch.
Creating the Project
"$(WindowsSdkDir)Lib\msi.lib"
Learning the Code
So here is what the code I wrote in this little learning project will do:
vector
to store each MSIProduct
.MsiEnumProducts
function and for each installed MSI:MSIProductInfo
.MSIProduct
object using the information from MSIProductInfo
and add the MSIProduct
to the list or vector
.vector
to store each MSIPatch
.MSIPatchInfoEx
.MSIPatch
object using the information from MSIPatchInfoEx
and add the MSIPatch
to this list or vector
.Here is my code:
Run.cpp
This file does all the work and has the tmain function. It creates a list or vector
of MSIProduct
objects and then uses MsiEnumProducts and MsiGetProductInfo to create and add each MSIProduct
to the vector
. It also loops through each of the MSIProduct
‘s and find any installed patches. It adds each patch found to the MSIProduct
‘s _Patches
vector
.
// Run.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "windows.h" #include "Msi.h" #include "MSIProduct.h" // Includes MSIBase.h and MSIPatch.h as well #include <iostream> #include <vector> using namespace std; #define MYSIZE 512 int _tmain(int argc, _TCHAR* argv[]) { // Step 1. Create a list or vector to store each MSIProduct. vector<MSIProduct> *products = new vector<MSIProduct>(); // Step 2. Loop through each installed MSIs using the MsiEnumProducts // function and for each installed MSI: int i = 0; bool foundMoreApps = true; while (foundMoreApps) { DWORD size = MYSIZE; LPTSTR tmpGuid = new TCHAR[MYSIZE]; LPTSTR tmpName = new TCHAR[MYSIZE]; UINT ret1 = MsiEnumProducts(i, tmpGuid); if (ret1 > 0) { foundMoreApps = false; continue; } // Step 3. Get MSI information using MSIProductInfo. UINT ret2 = MsiGetProductInfo(tmpGuid, INSTALLPROPERTY_PRODUCTNAME, tmpName, &size); if (ret2 > 0) { // Todo: Handle failure } // Step 4. Create an MSIProduct object using the information from MSIProductInfo // and add the MSIProduct to the list or vector. products->push_back(MSIProduct()); products->at(i).SetName(tmpName); products->at(i).SetGuid(tmpGuid); // Step 5. Write to standard output the MSI count (as Id), the MSI name, and the MSI Guid. cout << endl; cout << "Id: " << i << endl; wcout << "Product: " << tmpName << endl; wcout << "Guid: " << tmpGuid << endl; cout << "Patches: "; // Step 6. Create a list or vector to store each MSIPatch. vector<MSIPatch> *patches = new vector<MSIPatch>(); products->at(i).SetPatches(patches); // Step 7. Check if any patches or MSPs are applied to the MSI and for each patch: int j = 0; bool foundMorePatches = true; while (foundMorePatches) { DWORD size = MYSIZE; LPTSTR tmpPatchGuid = new TCHAR[MYSIZE]; LPTSTR tmpPatchState = new TCHAR[MYSIZE]; LPTSTR tmpPatchTransforms = new TCHAR[MYSIZE]; UINT retPatch1 = MsiEnumPatches(tmpGuid, j, tmpPatchGuid, tmpPatchTransforms, &size); if (retPatch1 > 0) { cout << "(" << retPatch1 << ") :" << endl; foundMorePatches = false; continue; } // These values correspond to the constants the dwFilter parameter // of MsiEnumPatchesEx uses. // Step 8. Get MSP information using MSIPatchInfoEx. UINT retPatch2 = MsiGetPatchInfoEx(tmpPatchGuid, tmpGuid, NULL, MSIINSTALLCONTEXT_MACHINE, INSTALLPROPERTY_PATCHSTATE, tmpPatchState, &size); // Returns "1" if this patch is currently applied to the product. // Returns "2" if this patch is superseded by another patch. // Returns "4" if this patch is obsolete. if (retPatch2 > 0) { // Todo: Handle failure } // Step 9. Create an MSIPatch object using the information from MSIPatchInfoEx // and add the MSIPatch to this list or vector. patches->push_back(MSIPatch()); patches->at(j).SetPatchState(tmpPatchState); patches->at(j).SetGuid(tmpPatchGuid); patches->at(j).SetTransforms(tmpPatchTransforms); // Step 9. Write to standard output the MSP Guid. wcout << "\t" << "Patch Guid: " << tmpPatchGuid << endl; j++; } i++; } } [/sourcecode] I did create some simple supporting classes for this: <strong>MSIBase.h</strong> [sourcecode language="cpp"] #pragma once #include "windows.h" class MSIBase { public: // Constructor MSIBase(void); // Destructor virtual ~MSIBase(void); // Accessor functions LPTSTR GetName(); void SetName(LPTSTR inName); LPTSTR GetGuid(); void SetGuid(LPTSTR inGuid); protected: LPTSTR _Guid; LPTSTR _Name; };
MSIBase.cpp
#include "StdAfx.h" #include "MSIBase.h" MSIBase::MSIBase(void) { } MSIBase::~MSIBase(void) { } // Accessor functions LPTSTR MSIBase::GetName() { return _Name; } void MSIBase::SetName(LPTSTR inName) { _Name = inName; } LPTSTR MSIBase::GetGuid() { return _Guid; } void MSIBase::SetGuid(LPTSTR inGuid) { _Guid = inGuid; }
MSIProduct.h
#include "MSIBase.h" #include "MSIPatch.h" #include <vector> #pragma once class MSIProduct : public MSIBase { public: MSIProduct(void); ~MSIProduct(void); std::vector<MSIPatch> GetPatches(); void SetPatches(std::vector<MSIPatch> * inPatches); void AddPatch(MSIPatch inPatch); protected: std::vector<MSIPatch> * _Patches; };
MSIProduct.cpp
#include "StdAfx.h" #include "MSIProduct.h" MSIProduct::MSIProduct(void) { } MSIProduct::~MSIProduct(void) { delete _Patches; } std::vector<MSIPatch> MSIProduct::GetPatches() { return * _Patches; } void MSIProduct::SetPatches(std::vector<MSIPatch> * inPatches) { _Patches = inPatches; } void MSIProduct::AddPatch(MSIPatch inPatch) { _Patches->push_back(inPatch); }
MSIPatch.h
#pragma once #include "MSIBase.h" class MSIPatch : public MSIBase { public: MSIPatch(void); ~MSIPatch(void); LPTSTR GetTransforms(); void SetTransforms(LPTSTR inTransforms); int GetPatchState(); void SetPatchState(int inPatchState); void SetPatchState(LPTSTR inPatchState); protected: LPTSTR _Transforms; int _PatchState; };
MSIPatch.cpp
#include "StdAfx.h" #include "MSIPatch.h" MSIPatch::MSIPatch(void) { } MSIPatch::~MSIPatch(void) { } LPTSTR MSIPatch::GetTransforms() { return _Transforms; } void MSIPatch::SetTransforms(LPTSTR inTransforms) { _Transforms = inTransforms; } int MSIPatch::GetPatchState() { return _PatchState; } void MSIPatch::SetPatchState(int inPatchState) { _PatchState = inPatchState; } void MSIPatch::SetPatchState(LPTSTR inPatchState) { _PatchState = _wtoi(inPatchState); }
Sorry, I am not explaining in more detail, my time is limited.
Note: I found one problem where an application has a ™ in the name. (Skype™ 4.2) and the output doesn’t work well after that.
Copyright ® Rhyous.com – Linking to this article is allowed without permission and as many as ten lines of this article can be used along with this link. Any other use of this article is allowed only by permission of Rhyous.com.
Ok, so I have an existing C++ Visual Studio project (at my new position here as a Developer at LANDesk) and who knows who created it or when it was created. Anyway, I wanted to start a new project and use the same project type.
So how do I find out the project type.
In Visual Studio, I opened the ProjectName.vcproj file and found this information near the top:
<?xml version="1.0" encoding="Windows-1252"?> <VisualStudioProject ProjectType="Visual C++" Version="9.00" Name="MSICheckForPatch" ProjectGUID="{0793FB88-8BED-4297-8615-9408EA2FBE74}" Keyword="AtlProj" TargetFrameworkVersion="196613" > <Platforms> <Platform Name="Win32" /> </Platforms> ...
So I noticed the Keyword was AtlProj, so that clued me in.
Looks like it was as easy as opening a text file and looking.
If there is a better or easier way, please comment and let me know.
Ok, there are multiple options.
Here is the code, you choose the option you want.
It is best to use Option 1 or Option 2. Read this blog at MSDN for a better understanding:
Assembly.CodeBase vs. Assembly.Location
using System; namespace GetCurrentProcessName { class Program { static void Main(string[] args) { // It is best to use Option 1 or Option 2. Read this: // http://blogs.msdn.com/b/suzcook/archive/2003/06/26/assembly-codebase-vs-assembly-location.aspx // Option 1 - Using Location (Recommended) String fullExeNameAndPath = System.Reflection.Assembly.GetExecutingAssembly().Location; String ExeName = System.IO.Path.GetFileName(fullExeNameAndPath); // Option 2 - Using CodeBase instead of location String fullExeNameAndPathUrl = System.Reflection.Assembly.GetExecutingAssembly().CodeBase; String codeBase = System.IO.Path.GetFileName(fullExeNameAndPathUrl); // Option 3 - Usable but during debugging in Visual Studio it retuns ExeName.vhost.exe String fullVhostNameAndPath = Environment.GetCommandLineArgs()[0]; String vhostName = System.IO.Path.GetFileName(fullVhostNameAndPath); // Option 4 - Also usable but doesn't include the extension .exe and also returns ExeName.vhost // during debuggin in visual studio String prcessName = System.Diagnostics.Process.GetCurrentProcess().ProcessName; } } }
Copyright ® Rhyous.com – Linking to this page is allowed without permission and as many as ten lines of this page can be used along with this link. Any other use of this page is allowed only by permission of Rhyous.com.
Let say you want to have a TextBox in which you only want to allow integers (0-9) or maybe you only want to allow strings, A-Za-z.
Well, lets play around with this for a second and see what we can do.
To get started do this:
Ok, so you should now have the following function:
private void textBox1_KeyDown(object sender, KeyEventArgs e) { }
The key that was pressed is accessible from the KeyEventArgs variable, e. Specifically e.Key.
Key just happens to be an enum, which means they can basically be treated as integers.
The key press can be ignored by telling setting e.Handled=true. This way it is already marked as handled and will not be added to the TextBox.
Here is a simple function to allow only natural numbers or number keys 0-9 in a TextBox. Be aware that the keys may be different in other languages.
private void textBox1_KeyDown(object sender, KeyEventArgs e) { if (e.Key < Key.D0 || e.Key > Key.D9) { e.Handled = true; } }
Wow, that was pretty simple, right? WRONG! It is not that easy.
You realize that there are two sets of numbers on a keyboard right? You have numbers in row above your QWERTY keys and you likely have a Number pad on the right of your keyboard as well. That is not all either.
What else did we forget, you might ask? Well, of the seven requirements we need to handle, we only handled one. For an application to be considered release quality or enterprise ready or stable, all seven of these should be handled.
Here are the six requirements in clear statements.
Remembering lists like this is something that comes with experience. If you thought of these on your own, good work. If you didn’t think of them on your own, don’t worry, experience comes with time.
So lets enhance this to handle each of these.
private void textBox1_KeyDown(object sender, KeyEventArgs e) { e.Handled = !IsNumberKey(e.Key); } private bool IsNumberKey(Key inKey) { if (inKey < Key.D0 || inKey > Key.D9) { if (inKey < Key.NumPad0 || inKey > Key.NumPad9) { return false; } } return true; }
All right, we now have two of the six requirements down.
You can probably already guess how easy it will be to do something similar to handle these two keys.
protected void OnKeyDown(object sender, KeyEventArgs e) { e.Handled = !IsNumberKey(e.Key) && !IsActionKey(e.Key); } private bool IsNumberKey(Key inKey) { if (inKey < Key.D0 || inKey > Key.D9) { if (inKey < Key.NumPad0 || inKey > Key.NumPad9) { return false; } } return true; } private bool IsActionKey(Key inKey) { return inKey == Key.Delete || inKey == Key.Back || inKey == Key.Tab || inKey == Key.Return || Keyboard.Modifiers.HasFlag(ModifierKeys.Alt); }
Ok, now we have four of six requirements handled.
Yes, I can handle both at the same time with a new event TextChanged.
This is setup so that if someone pastes both letters and number, only the numbers are pasted: A1B2C3 becomes 123.
This event is not configured so we have to set it up.
You should now have this stub code for the event function.
private void textBox1_TextChanged(object sender, TextChangedEventArgs e) { }
Here is some easy code to make sure each character is actually a digit.
protected void OnTextChanged(object sender, TextChangedEventArgs e) { base.Text = LeaveOnlyNumbers(Text); } private string LeaveOnlyNumbers(String inString) { String tmp = inString; foreach (char c in inString.ToCharArray()) { if (!IsDigit(c)) { tmp = tmp.Replace(c.ToString(), ""); } } return tmp; } public bool IsDigit(char c) { return (c >= '0' && c <= '9'); }
Guess what else? This last function actual handles the first five requirements all by itself. But it is less efficient so we will leave the previous requirements as they are.
Ok, so some somehow your TextBox is passed inside code during runtime a string that contains more than just numbers. How are you going to handle it.
This is setup so that if someone pastes both letters and number, only the numbers are pasted: A1B2C3 becomes 123. Well, we need to run the same function as for Drag and Drop, so to not duplicate code, it is time to create a class or object.
Now we need to make our code reusable. Lets create a class called NumberTextBox and it can do everything automagically.
NumberTextBox
using System; using System.Windows.Controls; using System.Windows.Input; namespace System.Windows.Controls { public class DigitBox : TextBox { #region Constructors /// <summary> /// The default constructor /// </summary> public DigitBox() { TextChanged += new TextChangedEventHandler(OnTextChanged); KeyDown += new KeyEventHandler(OnKeyDown); } #endregion #region Properties new public String Text { get { return base.Text; } set { base.Text = LeaveOnlyNumbers(value); } } #endregion #region Functions private bool IsNumberKey(Key inKey) { if (inKey < Key.D0 || inKey > Key.D9) { if (inKey < Key.NumPad0 || inKey > Key.NumPad9) { return false; } } return true; } private bool IsActionKey(Key inKey) { return inKey == Key.Delete || inKey == Key.Back || inKey == Key.Tab || inKey == Key.Return || Keyboard.Modifiers.HasFlag(ModifierKeys.Alt); } private string LeaveOnlyNumbers(String inString) { String tmp = inString; foreach (char c in inString.ToCharArray()) { if (!IsDigit(c)) { tmp = tmp.Replace(c.ToString(), ""); } } return tmp; } public bool IsDigit(char c) { return (c >= '0' && c <= '9'); } #endregion #region Event Functions protected void OnKeyDown(object sender, KeyEventArgs e) { e.Handled = !IsNumberKey(e.Key) && !IsActionKey(e.Key); } protected void OnTextChanged(object sender, TextChangedEventArgs e) { base.Text = LeaveOnlyNumbers(Text); } #endregion } }
Now I can delete the events and functions from the Window1.xaml.cs file. I don’t have to add any code to the Window1.xaml.cs. Instead I need to reference my local namespace in the Window1.xaml and then change the TextBox to a local:NumberTextBox. Here is the XAML.
<Window x:Class="TextBoxIntsOnly.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:TextBoxIntsOnly" Title="Window1" Height="300" Width="300"> <Grid> <local:DigitBox Margin="87,27,71,0" VerticalAlignment="Top" x:Name="textBox1" /> <Label Height="28" HorizontalAlignment="Left" Margin="9,25,0,0" Name="label1" VerticalAlignment="Top" Width="72">Integers:</Label> <TextBox Height="23" Margin="87,56,71,0" Name="textBox2" VerticalAlignment="Top" /> <Label Height="28" HorizontalAlignment="Left" Margin="9,54,0,0" Name="label2" VerticalAlignment="Top" Width="72">Alphabet:</Label> </Grid> </Window>
And now all seven requirements are met.
Quote:
While the actual manuals and documentation you get with many open source applications and platforms can be underwhelming, the good news is that there are a lot of free, online books on open source topics available. We round these up on a regular basis here at OStatic, and in this post you’ll find seven online books that you can get comfortable with quickly. They introduce essential concepts for getting started with Linux, Firefox, Blender (3D graphics and animation), GIMP (graphics), the OpenOffice suite of productivity applications, and more.
EndQuote
The following are code snippets for common regular expressions in C#.
If you have a regular expression that you think is common or a correction/improvement to one of mine, please submit it.
The expression:
^[0-9]{1,3}\.){3}[0-9]{1,3}$
In CSharp code:
String theIpAddressPattern = @"^[0-9]{1,3}\.){3}[0-9]{1,3}$";
The expression:
^[\-\w]+\.)+[a-zA-Z]{2,4}$
In CSharp code:
String theDoainNamePattern = @"^[\-\w]+\.)+[a-zA-Z]{2,4}$";
The expression:
^[\w!#$%&'*+\-/=?\^_`{|}~]+(\.[\w!#$%&'*+\-/=?\^_`{|}~]+)*@((([\-\w]+\.)+[a-zA-Z]{2,4}$)|(([0-9]{1,3}\.){3}[0-9]{1,3}))
In CSharp code:
String theEmailPattern = @"^[\w!#$%&'*+\-/=?\^_`{|}~]+(\.[\w!#$%&'*+\-/=?\^_`{|}~]+)*" + "@" + @"((([\-\w]+\.)+[a-zA-Z]{2,4})|(([0-9]{1,3}\.){3}[0-9]{1,3}))$";
a
The expression:
((^http(s)*://(([\-\w]+\.)+[a-zA-Z]{2,4}.*)))$|(^ftp://([\w](:[\w]))*(([\-\w]+\.)+[a-zA-Z]{2,4}[/\w]*))$
In CSharp code:
String theURLPattern = @"((^http(s)*://(([\-\w]+\.)+[a-zA-Z]{2,4}.*)))$" + @"|(^ftp://([\w](:[\w]))*(([\-\w]+\.)+[a-zA-Z]{2,4}[/\w]*))$";
Of course C# supports regular expressions. I happen to have learned regular expressions in my dealings with FreeBSD, shell scripting, php, and other open source work. So naturally I would want to add this as a skill as I develop in C#.
This is a method in code or script to describe the format or pattern of a string. For example, look at an email address:
someuser@somedomain.tld
It is important to understand that we are not trying to compare the email string against another string, we are trying to compare the string against a pattern.
To verify the email was in the correct format using String functions, it would take dozens of different functions running one after another. However, with a regular expression, a proper email address can be verified in one single function.
So instead regular expression is a language, almost like a scripting language in itself, for defining character patterns.
Most characters represent themselves. However, some characters don’t represent themselves without escaping them with a backslash because they represent something else. Here is a table of those characters.
Expression | Meaning |
---|---|
* | Any number of the previous character or character group. |
+ | One of more of the previous character or character group. |
^ | Beginning of line or string. |
$ | End of line or string. |
? | Pretty much any single character. |
. | Pretty much any character, zero characters, one character, or any number of characters |
[ … ] | This forms a character class expression |
( … ) | This forms a group of items |
You should look up more regular expression rules. I don’t explain them all here. This is just to give you an idea.
Here is a quick example of a regular expression that matches String=String. At first you might think this is easy and you can use this expression:
.*=.*
While that might work, it is very open. And it allows for zero characters before and after the equals, which should not be allowed.
This next pattern is at least correct but still very open.
.+=.+
What if the first value is limited to only alphanumeric characters?
[a-zA-z0-9]=.+
What if the second value has to be a valid windows file path or URL? And we will make sure we cover start to finish as well.
^[0-9a-zA-Z]+=[^<>|?*\”]+$
See how the more restrictions you put in place, the more complex the expression gets?
The pattern of an email is as follows: (Reference: wikipedia)
See updates here: C# – Email Regular Expression
So a simple patterns of an email address should be something like these:
This are all quick an easy examples and will not work in every instance but are usually accurate enough for casual programs.
But a comprehensive example is much more complex.
^[\w!#$%&'*+\-/=?\^_`{|}~]+(\.[\w!#$%&'*+\-/=?\^_`{|}~]+)*@((([\-\w]+\.)+[a-zA-Z]{2,4})|(([0-9]{1,3}\.){3}[0-9]{1,3}))$
^(([^<>()[\]\\.,;:\s@\""]+(\.[^<>()[\]\\.,;:\s@\""]+)*)|(\"".+\""))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$
So let me explain the first one that I wrote as it passes my unit tests below:
The start | |
[\w!#$%&’*+\-/=?\^_`{|}~]+ | At least one valid local-part character not including a period. |
(\.[\w!#$%&’*+\-/=?\^_`{|}~]+)* | Any number (including zero) of a group that starts with a single period and has at least one valid local-part character after the period. |
@ | The @ character |
( | Start group 1 |
( | Start group 2 |
([\-\w]+\.)+ | At least one group of at least one valid word character or hyphen followed by a period |
[\w]{2,4} | Any two to four valid top level domain characters. |
) | End group 2 |
| | an OR statement |
( | Start group 3 |
([0-9]{1,3}\.){3}[0-9]{1,3} | A regular expression for an IP Address. |
) | End group 3 |
) | End group 1 |
Here is code for both examples. My email regular expression is enabled and the one I found on line is commented out. To see how they work differently, just comment out mine, and uncomment the one I found online.
using System; using System.Collections.Generic; using System.Text.RegularExpressions; namespace RegularExpressionsTest { class Program { static void Main(string[] args) { // Example 1 - Parameter=value // Match any character before and after the = // String thePattern = @"^.+=.+$"; // Match only Upper and Lowercase letters and numbers before // the = as a parameter name and after the equal match the // any character that is allowed in a file's full path // // ^[0-9a-zA-Z]+ This is any number characters upper or lower // case or 0 thru 9 at the string's beginning. // // = Matches the = character exactly // // [^<>|?*\"]+$ This is any character except < > | ? * " // as they are not valid in a file path or URL String theNameEqualsValue = @"abcd=http://"; String theParameterEqualsValuePattern = "^[0-9a-zA-Z]+=[^<>|?*\"]+$"; bool isParameterEqualsValueMatch = Regex.IsMatch(theNameEqualsValue, theParameterEqualsValuePattern); Log(isParameterEqualsValueMatch); // Example 2 - Email address formats String theEmailPattern = @"^[\w!#$%&'*+\-/=?\^_`{|}~]+(\.[\w!#$%&'*+\-/=?\^_`{|}~]+)*" + "@" + @"((([\-\w]+\.)+[a-zA-Z]{2,4})|(([0-9]{1,3}\.){3}[0-9]{1,3}))$"; // The string pattern from here doesn't not work in all instances. // http://www.cambiaresearch.com/c4/bf974b23-484b-41c3-b331-0bd8121d5177/Parsing-Email-Addresses-with-Regular-Expressions.aspx //String theEmailPattern = @"^(([^<>()[\]\\.,;:\s@\""]+(\.[^<>()[\]\\.,;:\s@\""]+)*)|(\"".+\""))" // + "@" // + @"((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])" // + "|" // + @"(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$"; Console.WriteLine("Bad emails"); foreach (String email in GetBadEmails()) { Log(Regex.IsMatch(email, theEmailPattern)); } Console.WriteLine("Good emails"); foreach (String email in GetGoodEmails()) { Log(Regex.IsMatch(email, theEmailPattern)); } } private static void Log(bool inValue) { if (inValue) { Console.WriteLine("It matches the pattern"); } else { Console.WriteLine("It doesn't match the pattern"); } } private static List GetBadEmails() { List emails = new List(); emails.Add("joe"); // should fail emails.Add("joe@home"); // should fail emails.Add("a@b.c"); // should fail because .c is only one character but must be 2-4 characters emails.Add("joe-bob[at]home.com"); // should fail because [at] is not valid emails.Add("joe@his.home.place"); // should fail because place is 5 characters but must be 2-4 characters emails.Add("joe.@bob.com"); // should fail because there is a dot at the end of the local-part emails.Add(".joe@bob.com"); // should fail because there is a dot at the beginning of the local-part emails.Add("john..doe@bob.com"); // should fail because there are two dots in the local-part emails.Add("john.doe@bob..com"); // should fail because there are two dots in the domain emails.Add("joe<>bob@bob.come"); // should fail because <> are not valid emails.Add("joe@his.home.com."); // should fail because it can't end with a period emails.Add("a@10.1.100.1a"); // Should fail because of the extra character return emails; } private static List GetGoodEmails() { List emails = new List(); emails.Add("joe@home.org"); emails.Add("joe@joebob.name"); emails.Add("joe&bob@bob.com"); emails.Add("~joe@bob.com"); emails.Add("joe$@bob.com"); emails.Add("joe+bob@bob.com"); emails.Add("o'reilly@there.com"); emails.Add("joe@home.com"); emails.Add("joe.bob@home.com"); emails.Add("joe@his.home.com"); emails.Add("a@abc.org"); emails.Add("a@192.168.0.1"); emails.Add("a@10.1.100.1"); return emails; } } }
Hey all,
You have a TextBox
and you want to detect when someone presses “Enter” and do something different than if they type text.
This one is simple, but you need to be careful when closing a window in multiple places.
The Event you want to use is KeyDown
.
Imagine you have a TextBox
called TextBoxCompanyName
where you are asking the company name. It is common to enter the name and press Enter and have “Enter” act just like the OK button.
You already have an OK button and it is setup to close the window or do other stuff first.
private void ButtonOK_Click(object sender, RoutedEventArgs e) { // May do other stuff. this.Close(); } private void TextBoxCompanyName_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Enter) { ButtonOK_Click(this, new RoutedEventArgs()); } }
Notice I don’t just call this.Close()
again in the new TextBoxCompanyName_KeyDown
event; but instead I call the ButtonOK_Click
function to simulate the OK button being clicked. This way:
You now know how to do something different when you press “Enter”. I hope that was easy for you.
Copyright ® Rhyous.com – Linking to this page is allowed without permission and as many as ten lines of this page can be used along with this link. Any other use of this page is allowed only by permission of Rhyous.com.
I wrote a regex for email that is gets the best results of any I have found online. Along with getting better results, it is shorter too.
Download the C# project with unit tests here: EmailRegEx on GitHub
The pattern of an email is described as follows:
So a simple patterns of an email address should be something like these:
These are all quick an easy examples and will not work in every instance but are usually accurate enough for casual programs.
But a comprehensive example is much more complex.
^[\w!#$%&'*+\-/=?\^_`{|}~]+(\.[\w!#$%&'*+\-/=?\^_`{|}~]+)*@((([\-\w]+\.)+[a-zA-Z]{2,4})|(([0-9]{1,3}\.){3}[0-9]{1,3}))\z
^(([^<>()[\]\\.,;:\s@\""]+(\.[^<>()[\]\\.,;:\s@\""]+)*)|(\"".+\""))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$
So let me explain the first one that I wrote as it passes my unit tests below:
The start | |
[\w!#$%&’*+\-/=?\^_`{|}~]+ | At least one valid local-part character not including a period. |
(\.[\w!#$%&’*+\-/=?\^_`{|}~]+)* | Any number (including zero) of a group that starts with a single period and has at least one valid local-part character after the period. |
@ | The @ character |
( | Start group 1 |
( | Start group 2 |
([\-\w]+\.)+ | At least one group of at least one valid word character or hyphen followed by a period. The attached project has a more complex hostname regex option too. |
[\w]{2,4} | Any two to four valid top level domain characters. |
) | End group 2 |
| | an OR statement |
( | Start group 3 |
([0-9]{1,3}\.){3}[0-9]{1,3} | A regular expression for an IP Address. The attached project has a more complex IP regex example too. |
) | End group 3 |
) | End group 1 |
\z | No end of line: \r or \n. |
Here is code for both examples. My email regular expression is enabled and the one I found on line is commented out. To see how they work differently, just comment out mine, and uncomment the one I found online.
using System; using System.Collections.Generic; using System.Text.RegularExpressions; namespace RegularExpressionsTest { class Program { static void Main(string[] args) { String theEmailPattern = @"^[\w!#$%&'*+\-/=?\^_`{|}~]+(\.[\w!#$%&'*+\-/=?\^_`{|}~]+)*" + "@" + @"((([\-\w]+\.)+[a-zA-Z]{2,4})|(([0-9]{1,3}\.){3}[0-9]{1,3}))\z"; // The string pattern from here doesn't not work in all instances. // http://www.cambiaresearch.com/c4/bf974b23-484b-41c3-b331-0bd8121d5177/Parsing-Email-Addresses-with-Regular-Expressions.aspx //String theEmailPattern = @"^(([^<>()[\]\\.,;:\s@\""]+(\.[^<>()[\]\\.,;:\s@\""]+)*)|(\"".+\""))" // + "@" // + @"((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])" // + "|" // + @"(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$"; Console.WriteLine("Bad emails"); foreach (String email in GetBadEmails()) { Log(Regex.IsMatch(email, theEmailPattern)); } Console.WriteLine("Good emails"); foreach (String email in GetGoodEmails()) { Log(Regex.IsMatch(email, theEmailPattern)); } } private static void Log(bool inValue) { if (inValue) { Console.WriteLine("It matches the pattern"); } else { Console.WriteLine("It doesn't match the pattern"); } } private static List<String> GetBadEmails() { List<String> emails = new List<String>(); emails.Add("joe"); // should fail emails.Add("joe@home"); // should fail emails.Add("a@b.c"); // should fail because .c is only one character but must be 2-4 characters emails.Add("joe-bob[at]home.com"); // should fail because [at] is not valid emails.Add("joe@his.home.place"); // should fail because place is 5 characters but must be 2-4 characters emails.Add("joe.@bob.com"); // should fail because there is a dot at the end of the local-part emails.Add(".joe@bob.com"); // should fail because there is a dot at the beginning of the local-part emails.Add("john..doe@bob.com"); // should fail because there are two dots in the local-part emails.Add("john.doe@bob..com"); // should fail because there are two dots in the domain emails.Add("joe<>bob@bob.com"); // should fail because <> are not valid emails.Add("joe@his.home.com."); // should fail because it can't end with a period emails.Add("john.doe@bob-.com"); // should fail because there is a dash at the start of a domain part emails.Add("john.doe@-bob.com"); // should fail because there is a dash at the end of a domain part emails.Add("a@10.1.100.1a"); // Should fail because of the extra character emails.Add("joe<>bob@bob.com\n"); // should fail because it end with \n emails.Add("joe<>bob@bob.com\r"); // should fail because it ends with \r return emails; } private static List<String> GetGoodEmails() { List<String> emails = new List<String>(); emails.Add("joe@home.org"); emails.Add("joe@joebob.name"); emails.Add("joe&bob@bob.com"); emails.Add("~joe@bob.com"); emails.Add("joe$@bob.com"); emails.Add("joe+bob@bob.com"); emails.Add("o'reilly@there.com"); emails.Add("joe@home.com"); emails.Add("joe.bob@home.com"); emails.Add("joe@his.home.com"); emails.Add("a@abc.org"); emails.Add("a@abc-xyz.org"); emails.Add("a@192.168.0.1"); emails.Add("a@10.1.100.1"); return emails; } } }
Well, now you have the best C# Email Regular Expression out there.
Update: My attached project has an even better and more accurate one now too.
(Reference: wikipedia)
Ok, so I already can upload a file to an FTP server: How to upload a file to an FTP server using C#?
However, now I need to create a directory first.
It follows some basic steps:
See the steps inside the source as comments:
using System; using System.IO; using System.Net; namespace CreateDirectoryOnFtpServer { class Program { static void Main(string[] args) { CreateDirectoryOnFTP("ftp://ftp.server.tld", /*user*/"User1", /*pw*/"Passwd!", "NewDirectory"); } static void CreateDirectoryOnFTP(String inFTPServerAndPath, String inUsername, String inPassword, String inNewDirectory) { // Step 1 - Open a request using the full URI, ftp://ftp.server.tld/path/file.ext FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(inFTPServerAndPath + "/" + inNewDirectory); // Step 2 - Configure the connection request request.Credentials = new NetworkCredential(inUsername, inPassword); request.UsePassive = true; request.UseBinary = true; request.KeepAlive = false; request.Method = WebRequestMethods.Ftp.MakeDirectory; // Step 3 - Call GetResponse() method to actually attempt to create the directory FtpWebResponse makeDirectoryResponse = (FtpWebResponse)request.GetResponse(); } } }
All right, now you have created a directory on the FTP server.
Copyright ® Rhyous.com – Linking to this page is allowed without permission and as many as ten lines of this page can be used along with this link. Any other use of this page is allowed only by permission of Rhyous.com.