Friday, November 2, 2007
Opening up Scheduled Tasks for remote servers from the command line
Imagine you have Scheduled Tasks on many servers. While it is easy enough to open a Window in Windows Explorer and type something like
file:////myserver/Scheduled
to open the Scheduled Tasks window for a specified server, this does not work if you type this into the command prompt or in a batch file.
What I found is that you can open a shortcut from the command line though. So, open the Scheduled Tasks as described above, and then drag the icon in the left part of the address bar to your desktop (or other directory). This will create a shortcut. You can then type this into a command line or batch file and the Scheduled Tasks Window will open for the specified server.
This is not a huge time saver, but it is convenient to have a list of icons to click instead of trying to remember all the servers, type them in, etc. If you have lots of servers that need to be updated it can be very slow waiting for the Scheduled Tasks windows to appear. I recommend putting them in a batch file with the name of the shortcut (you will need to enclose in double quotes if the name has spaces in it) on each line.
Here is an example of a batch file that opens 3 servers one after another.
"Scheduled Tasks on server1.lnk"
"Scheduled Tasks on server2.lnk"
"Scheduled Tasks on server3.lnk"
Now when you need to update the scheduled tasks all you do is run this batch file, take a few minute break, come back and you will have all your Scheduled Tasks windows open and ready for editing. This beats doing it one at a time if you ask me. :)
TIP: You really only need to create one shortcut. Then make a copy of it, and open it in notepad. It is fairly cryptic looking. Just look for the server name and change it to the server you want it to point to. Save the text file. That is it. No you have a shortcut that works, and you didn't have to wait to connect to Scheduled Tasks to create it.
Thursday, October 25, 2007
Getting to the result that was returned when selecting in an ObjectDataSource
ASP.NET 2.0 has some really nice drag and drop features. Let's pretend you have a GridView and and ObjectDataSource that you have configured on the page. No you want to do something interesting with the results that the ObjectDataSource returns before it is passed on to the GridView. This could be any number of things. For example, maybe timezone conversion, rounding, etc.
The ObjectDataSource provides a Selected event that you can hook into. Here is an example that
protected
void BLL_Selected(object sender, ObjectDataSourceStatusEventArgs e) { DataTable dt = e.ReturnValue as DataTable; // do interesting stuff here... }Select distinct rows from a DataTable
It is probably best to describe a scenario to understand what I am trying to describe. Let's assume you have a DataTable called myDataTable that has three columns (Col1, Col2, Col3). You want to get a distinct list based on Col1 and Col2. In SQL you could do something like: Select distinct Col1, Col2 from MyTable; Believe it or not, we can do the same thing with the in memory table known as a DataTable in .Net. // populate the DataTable DataTable myDataTable = DAL.doSomeQuery();
bool distinct = true;
DataTable distinctRows = myDataTable.DefaultView.ToTable(distinct, new string[] { "Col1", "Col2" }); That is it, but it is only available in .Net 2.0.
Tuesday, October 23, 2007
ASP.NET and EventLog: Event ID issues when writing to Event Log
If you get the following message (except your application name):
The description for Event ID ( 234 ) in Source ( dotNET Sample App ) cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer. You may be able to use the /AUXSOURCE= flag to retrieve this description; see Help and Support for details. The following information is part of the event: Sample Event.
The best part of this is that the existing logs no longer have this message either once you follow the steps below.
What it is trying to tell you is that when it tries to look up Event ID 234 in the Source Called dotNET Sample App, it can't figure out what 234 is supposed to represent because it can't find the dll that maps the event ids to localized messages. What it wants is an entry in the Registry that points to the dll.
For example, if you are writing to the Application event log and using the source called dotNET Sample App, the key needs to be at:
HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application\dotNET Sample App\EventMessageFile.
The value needs to point to a .dll file that has been compiled specially for this purpose using.
It appears that if this key does not exist, you can add the above key (Expandable String Value), and point the value to (slightly different path if v1.x):
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\EventLogMessages.dll
If you want user friendly messages in the event log instead of number for the event id, you will need to do the following.
If the key is not already there, you can add a new Expandable String Value with the name Event MessageFile and the value of the path (including the .dll) to the dll.
The following url is a good start: http://msdn2.microsoft.com/en-us/library/system.diagnostics.eventinstance.aspx
Here is how to use Message Compiler (to create the event id dll): http://msdn2.microsoft.com/en-us/library/aa385638.aspx
If you want to fix this the quick way and have a generic dll get used automatically then just do the following. This step may or may not be necessary if you are running a Windows application, but is necessary if you want an ASP.NET application to log events.
1. Launch RegEdit
2. Navigate to Delete the key at HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application\dotNET Sample App
3. From the Edit menu select Permissions.
4. Add the ASPNET user (or whatever user your application is running under or impersonating if using ASP.NET) and give it Read and Write permission. Verify that the Application and Security Keys now have these permissions also.
NOTE: Under IIS 6.0 the user isn't ASPNET, it is Network Service
Tip: If you need help debugging permission, you can always add Everyone with Full Control and reduce permissions until you figure out what permissions you really need. Be sure to not leave it this way though. It is a small security hole.
NOTE: You are probably not writing to System, but if you have code like the following in your application, the SourceExists() method will throw an exception. To avoid this, you need to grant permissions to it also (at least until the CreateEventSource()) method successfully creates the key. After that, you should not get the error when SourceExists() is called. There are other solutions as well. For example, you can always create a standalone Windows application with the same name as your web application and have it run the CreateEventSource() method. This will get you past the SourceExists() call, and this will create the source. You will still need to adjust permissions for your application to log properly though. You can also create an event log installer. I have never done this, and sounds like a complicated solution to me. Permissions is much simpler and falls under the general configuration knowledge that can be used for any web application.
if (!EventLog.SourceExists(sourceName))
{
EventLog.CreateEventSource(sourceName, "Application");
}
5. Now run your application, and make sure the CreateEventSource() is called. This should create the key:
HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application\dotNET Sample App
NOTE: You may need to run your application twice as it takes a short time for the new Event Source to be synchronized with other parts of Windows.
6. Verify that the EventMessageFile key was created properly.
NOTE: If you specify the category id in your code, you will also need to do something similar. I have not tested the solution, but I expect if you create custom message then you will have a file that you can't point to in the registry in much the same way. I know the key for the categories does not automatically get created, but using mc.exe as you would have done for event ids (if you needed custom messages) should work. I welcome feedback on this. I recommend setting the category id to 0 in your code if you don't want to deal with this issue.
Another Symptom of this is that MS LogParser will generate errors like the following
Task aborted.Too many parse errors - abortingParse errors:Unable to map Event Message from Event Source "dotNET Sample App"Unable to map Event Message from Event Source "dotNET Sample App"
when a query like
LogParser.exe "select distinct message from application where message like '%display messages from a remote computer%'" -msgErrorMode:ERROR -e 10
is executed to find all the troubled errors in the first place.
To fix this, make sure registry key and path to dll exists for source as described above.
Literally you can copy and paste from one SQL Server to another
Let's say you want to copy data from one server to another. Assume you have a table called MyTable on ServerA and the exact same table on ServerB.
Basically all you have to do is simply copy and paste the rows from one screen to another. Here are the details.
Here are step by step instructions:
1. Open MS SQL Server Management Studio
2. Browse to your favorite table using the Object Explorer.
3. Right click on the table and select "Open Table"
4. Shift or control click the rows you want to copy.
5. Type control-C.
Repeat steps 1 - 4 on the other server that has this same table (no data though).
UPDATE: Be sure to select the last row that has all nulls, otherwise the paste may not work as expected.
Lastly, type Control-V to paste the data.
This tip does not work in Enterprise Manager that comes with SQL Server 2000 (at least that I know of).
Easy way to restart your ASP.NET web site
If you don't want to use IIS to recycle your application pool, or don't have access to it or iisreset command then there is an quick and easy way to force your ASP.NET web site to recycle. This includes the application variables that you may have defined and use in your application.
Simply edit your web.config. Any change should work. That is it.
NOTE: I have tried changing other source code such as .cs files and it doesn't seem to trigger a restart of the application. I imagine it would have to be a real code change that causes the compiled dll to be regenerated, not just adding a space at the end of a line or something simple like I tried.
Wednesday, October 10, 2007
Image alignment in HTML / CSS
Let's assume you have a line that starts with an image with text to the right of it. By default the image and text are vertically aligned to the bottom of the image and the baseline (bottom except for letters like g, j, y, etc) of the text. To make the image be centered on the line of text you do the following.
<
img border="0" src="myImage.gif" style="vertical-align:middle"/>my text that is to the right of the image.
Subscribe to:
Posts (Atom)