If you receive this message while trying to delete a windows service - check if the Services.msc application is open.
You will need to restart in order to delete the service, but you will know to first close the Services.msc application the next time PRIOR uninstalling the service (using installutil /u service_exe_name).
Hope this helps someone outthere...
Edit : I found another scenario when this can happen and it seems to be more .NET specific and common to software developers - if your service creates some worker threads, Windows will attempt to kill the main thread, the main thread will attempt to kill the main thread but the worker threads if not marked as BackgroundThreads via the IsBackgroundThread property will remain. The GC will wait for them to reach a safe point so they can be terminated and the service will most probably be only marked for deletion, requiring you to restart windows.
Please note - if you are using the ThreadPool class you will probably not hit this problem as the ThreadPool internal threads are automatically marked as background threads.
Edit 2: Another case when you will receive The specified service has been marked for deletion error message is when you try to uninstall service which wasn't stopped first or it was marked as unstopable.
This is done if you have this.CanStop = false in your service code.
Windows knows this service shouldn't be stopped and it will only mark it for deletion but will not delete it right away.
Be careful with CanStop property.
All the stuff that bothers software developer in his everyday tasks.
Showing posts with label Windows Forms. Show all posts
Showing posts with label Windows Forms. Show all posts
Dec 3, 2009
May 19, 2009
5 minutes C# - get windows special folders path
Just a two lines of code in order to retrieve the path to a special folder of your choice (My Documents, ApplicationData etc):
string strAppData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
DirectoryInfo diMyDocuments = new DirectoryInfo(strAppData);
Here is the Environment.SpecialFolder Enum:
Environment.SpecialFolder.ApplicationData - the data which some applications store about the current user (mostly used for personalized settings), this is for roaming users.
Environment.SpecialFolder.CommonApplicationData - Application data which is common for all users.
Environment.SpecialFolder.CommonProgramFiles - "The directory for components that are shared across applications"
Environment.SpecialFolder.Cookies - The folder where the user cookies are stored.
Environment.SpecialFolder.Desktop - The logical desktop.
Environment.SpecialFolder.DesktopDirectory - this is the directory which is used to store file objects on the desktop.
Environment.SpecialFolder.Favorites - Current user favorite items.
Environment.SpecialFolder.History - Current user Internet History.
Environment.SpecialFolder.InternetCache - Internet cached files.
Environment.SpecialFolder.LocalApplicationData - As the first one but for non-roaming users.
Environment.SpecialFolder.MyComputer - I'll let you figure this out ...
Environment.SpecialFolder.MyDocuments - I'll let you figure this out too ...
Environment.SpecialFolder.MyMusic - ... and this one ...
Environment.SpecialFolder.MyPictures - ... and this one ...
Environment.SpecialFolder.Personal - this one is more important, this directory is used as a repository for documents...
Environment.SpecialFolder.ProgramFiles - this one is clear, I believe
Environment.SpecialFolder.Programs - Contains user program groups.
Environment.SpecialFolder.Recent - Users most recently used documetns.
Environment.SpecialFolder.SendTo - This directory is used for the Send To > item in the context menu. By adding folders here, they will appear in the Send To -> item when you click on a file or folder.
Environment.SpecialFolder.StartMenu - Contains the Start Menu items.
Environment.SpecialFolder.Startup - The Startup group (Start Menu -> All Programs -> Startup).
Environment.SpecialFolder.System - The system directory (%Windir%\System32)
Environment.SpecialFolder.Templates - Document templates repository.
Hope I helped a bit.
Have a great coding.
string strAppData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
DirectoryInfo diMyDocuments = new DirectoryInfo(strAppData);
Here is the Environment.SpecialFolder Enum:
Environment.SpecialFolder.ApplicationData - the data which some applications store about the current user (mostly used for personalized settings), this is for roaming users.
Environment.SpecialFolder.CommonApplicationData - Application data which is common for all users.
Environment.SpecialFolder.CommonProgramFiles - "The directory for components that are shared across applications"
Environment.SpecialFolder.Cookies - The folder where the user cookies are stored.
Environment.SpecialFolder.Desktop - The logical desktop.
Environment.SpecialFolder.DesktopDirectory - this is the directory which is used to store file objects on the desktop.
Environment.SpecialFolder.Favorites - Current user favorite items.
Environment.SpecialFolder.History - Current user Internet History.
Environment.SpecialFolder.InternetCache - Internet cached files.
Environment.SpecialFolder.LocalApplicationData - As the first one but for non-roaming users.
Environment.SpecialFolder.MyComputer - I'll let you figure this out ...
Environment.SpecialFolder.MyDocuments - I'll let you figure this out too ...
Environment.SpecialFolder.MyMusic - ... and this one ...
Environment.SpecialFolder.MyPictures - ... and this one ...
Environment.SpecialFolder.Personal - this one is more important, this directory is used as a repository for documents...
Environment.SpecialFolder.ProgramFiles - this one is clear, I believe
Environment.SpecialFolder.Programs - Contains user program groups.
Environment.SpecialFolder.Recent - Users most recently used documetns.
Environment.SpecialFolder.SendTo - This directory is used for the Send To > item in the context menu. By adding folders here, they will appear in the Send To -> item when you click on a file or folder.
Environment.SpecialFolder.StartMenu - Contains the Start Menu items.
Environment.SpecialFolder.Startup - The Startup group (Start Menu -> All Programs -> Startup).
Environment.SpecialFolder.System - The system directory (%Windir%\System32)
Environment.SpecialFolder.Templates - Document templates repository.
Hope I helped a bit.
Have a great coding.
Етикети:
.NET C# technologies,
C#,
Windows Forms
Dec 1, 2008
Microsoft Office Word automation in C# - How to add table to the document?
The following C# code will create a new document, add a table to it and ask the user to save it. Document will look like this:

The following code will add a table in word and then ask the user to provide a filename to save the document:
Microsoft.Office.Interop.Word.Application app = new Microsoft.Office.Interop.Word.ApplicationClass();
app.Visible = false;
object start = 0;
object end = 0;
object oNull = System.Reflection.Missing.Value;
Document doc = new DocumentClass();
doc = app.Documents.Add(ref oNull, ref oNull, ref oNull, ref oNull);
Table tbl = doc.Tables.Add(doc.Range(ref start, ref end), 10, 2, ref oNull, ref oNull);
Random rnd = new Random();
for (int i = 0; i < 10; i++)
{
tbl.Rows[i + 1].Cells[1].Range.Text = "Run# :" + ((int)i + 1).ToString();
tbl.Rows[i + 1].Cells[2].Range.Text = "Value :" + rnd.Next(0, 2000).ToString();
}
object oFalse = false;
app.Visible = true;
try
{
doc.Save();
}
catch (Exception ex)
{
if (ex.Message.ToLower().IndexOf("command failed") == -1)
{
throw ex;
}
}
app.Quit(ref oFalse, ref oFalse, ref oFalse);
What we done is to create a new document, a new table, and fill the table with random values.
Seems very easy but not quite sure how well document :).
The following code will add a table in word and then ask the user to provide a filename to save the document:
Microsoft.Office.Interop.Word.Application app = new Microsoft.Office.Interop.Word.ApplicationClass();
app.Visible = false;
object start = 0;
object end = 0;
object oNull = System.Reflection.Missing.Value;
Document doc = new DocumentClass();
doc = app.Documents.Add(ref oNull, ref oNull, ref oNull, ref oNull);
Table tbl = doc.Tables.Add(doc.Range(ref start, ref end), 10, 2, ref oNull, ref oNull);
Random rnd = new Random();
for (int i = 0; i < 10; i++)
{
tbl.Rows[i + 1].Cells[1].Range.Text = "Run# :" + ((int)i + 1).ToString();
tbl.Rows[i + 1].Cells[2].Range.Text = "Value :" + rnd.Next(0, 2000).ToString();
}
object oFalse = false;
app.Visible = true;
try
{
doc.Save();
}
catch (Exception ex)
{
if (ex.Message.ToLower().IndexOf("command failed") == -1)
{
throw ex;
}
}
app.Quit(ref oFalse, ref oFalse, ref oFalse);
What we done is to create a new document, a new table, and fill the table with random values.
Seems very easy but not quite sure how well document :).
Етикети:
C#,
Software Development,
Windows Forms
Jul 10, 2008
C# Microsoft Excel Automation - very simple Microsoft Excel AddIn to get Amazon deals
in xmlNodeItems)
{
i++;
if (i > 10) break;
// Get title, link and description, the
// description will be later used to retrieve image url.
string strTitle = xmlNodeItem.SelectSingleNode("title").InnerText;
string strLink = xmlNodeItem.SelectSingleNode("link").InnerText;
string strDescription = xmlNodeItem.SelectSingleNode("description").InnerText;
// Get the cell in which we will write the title of the product.
Excel.Range rngTitle = ((Excel.Worksheet)Application.ActiveSheet).get_Range("A" + i.ToString(), "A" + i.ToString());
// Some variables for the picture creation:
float picLeft = 50;
float picTop = float.Parse(rngTitle.Top.ToString()) + 5f;
float picWidth = 50;
float picHeight = 50;
string strImageFile = GetImageUrl(strDescription);
// Make fonts bold and write the text in the first cell ("A").
rngTitle.Font.Bold = true;
rngTitle.Value2 = strTitle;
// Add the picture
Excel.Shape pic = ((Excel.Worksheet)Application.ActiveSheet).Shapes.AddPicture(strImageFile, Microsoft.Office.Core.MsoTriState.msoCTrue, Microsoft.Office.Core.MsoTriState.msoCTrue, picLeft, picTop, picWidth, picHeight);
// Make the title centered both horizontally and vertically.
rngTitle.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
rngTitle.VerticalAlignment = Excel.XlVAlign.xlVAlignCenter;
// Make the picture move if neighbour cell is resized.
pic.Placement = Microsoft.Office.Interop.Excel.XlPlacement.xlMove;
}
Note : I removed the VSTO generated code region so I don't waste space. You shouldn't do this ;).
In other words if you copy the code you will need to paste it below the VSTO generated code region.
I also used a subroutine to extract the image url from the description, it is very simple, greedy regular expression:
private string GetImageUrl(string strDescription)
{
Match mImage = Regex.Match(strDescription, "src=\".+?\"");
return mImage.Value.Replace("src=", "").Replace("\"", "");
}
Things to do:
1. First of all there is no good way to resize a cell in Excel. Your user will be presented very ugly screen. Here is how it actually looks if you don't resize the cells:

Very ugly huh?
2. The other think that bothers me is that Amazon lists about 100 products in their deals feed. So it is a bit slowly to get all the images (they are downloaded on the fly).
I will be very happy to discuss this problem with any of you.
Cheers ;).
{
i++;
if (i > 10) break;
// Get title, link and description, the
// description will be later used to retrieve image url.
string strTitle = xmlNodeItem.SelectSingleNode("title").InnerText;
string strLink = xmlNodeItem.SelectSingleNode("link").InnerText;
string strDescription = xmlNodeItem.SelectSingleNode("description").InnerText;
// Get the cell in which we will write the title of the product.
Excel.Range rngTitle = ((Excel.Worksheet)Application.ActiveSheet).get_Range("A" + i.ToString(), "A" + i.ToString());
// Some variables for the picture creation:
float picLeft = 50;
float picTop = float.Parse(rngTitle.Top.ToString()) + 5f;
float picWidth = 50;
float picHeight = 50;
string strImageFile = GetImageUrl(strDescription);
// Make fonts bold and write the text in the first cell ("A").
rngTitle.Font.Bold = true;
rngTitle.Value2 = strTitle;
// Add the picture
Excel.Shape pic = ((Excel.Worksheet)Application.ActiveSheet).Shapes.AddPicture(strImageFile, Microsoft.Office.Core.MsoTriState.msoCTrue, Microsoft.Office.Core.MsoTriState.msoCTrue, picLeft, picTop, picWidth, picHeight);
// Make the title centered both horizontally and vertically.
rngTitle.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
rngTitle.VerticalAlignment = Excel.XlVAlign.xlVAlignCenter;
// Make the picture move if neighbour cell is resized.
pic.Placement = Microsoft.Office.Interop.Excel.XlPlacement.xlMove;
}
Note : I removed the VSTO generated code region so I don't waste space. You shouldn't do this ;).
In other words if you copy the code you will need to paste it below the VSTO generated code region.
I also used a subroutine to extract the image url from the description, it is very simple, greedy regular expression:
private string GetImageUrl(string strDescription)
{
Match mImage = Regex.Match(strDescription, "src=\".+?\"");
return mImage.Value.Replace("src=", "").Replace("\"", "");
}
Things to do:
1. First of all there is no good way to resize a cell in Excel. Your user will be presented very ugly screen. Here is how it actually looks if you don't resize the cells:
Very ugly huh?
2. The other think that bothers me is that Amazon lists about 100 products in their deals feed. So it is a bit slowly to get all the images (they are downloaded on the fly).
I will be very happy to discuss this problem with any of you.
Cheers ;).
Mar 19, 2008
Very simple tool to watch ending Sedo Auctions
| Few months ago I was interested in the domain trading business. It was interesting to me as it generated 14.2 million dollars back in 2006. It is based on speculla I think. Something like FOREX but not quite. I registered two domains and placed them on Sedo Auctions. I was also interested on how other domains are going so I decided to write a small tool. It will stay in your tray and will show you the auctions which are about to end the next 24 hours. The following information is gathered about each auction: - Domain for sale - Price - Currency - Time left before the auction is closed - Google PR for each domain The program is available for download from Chameleon Bulgaria I decided to put a banner on this program so my domains |
Here is a direct link to the program page on Chameleon Bulgaria may be found
here
Mar 16, 2008
5 minutes C# to dispose your NotifyIcon object
| If you have this problem - try calling .Dispose() method for your NotifyIcon explicitly in the FormClosing event: private void Form1_FormClosing(object sender, FormClosingEventArgs e) { notifyIcon1.Dispose(); } Note : this trick may not work if the Application was terminated abnormally. I will investigate that issue when I have some free time and report back what is the best approach on this. |
Етикети:
.NET,
.NET C# technologies,
C#,
Windows Forms
Feb 4, 2008
5 minutes C# code to load CSV file into a DataSet
| Step 1 : add button for browsing files, a textbox to hold the file name and paste the followin code in the browse button click handler (this code will basically popup a OpenFileDialog, set up to only open files with .csv extension): |
OpenFileDialog ofd = new OpenFileDialog ();
ofd.Filter = "CSV Files|*.csv" ;
if (ofd.ShowDialog() == DialogResult .OK)
{
this .textBox2.Text = ofd.FileName;
GetData();
}
Then we need to get the file from the textbox2 and load it into data set:
private void GetData()
{
FileInfo fi = new FileInfo (textBox2.Text);
OleDbConnection con = new OleDbConnection ( @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fi.Directory.FullName + ";Extended Properties='text;HDR=Yes;FMT=Delimited'" );
con.Open();
DataSet dsThings = new DataSet ();
OleDbCommand cmd = new OleDbCommand ( "SELECT * FROM " + fi.Name, con);
OleDbDataAdapter adapt = new OleDbDataAdapter (cmd);
adapt.Fill(dsThings);
this .dataGridView1.DataSource = dsThings.Tables[0];
}
As you can see we use OleDB provider to load the CSV file into the dataset.
Етикети:
.NET,
.NET C# technologies,
C#,
Windows Forms
Jan 28, 2008
Job Done!
| I think I made it finally. The osCommerce 2 vShop import was made this afternoon. Just waiting QA test now. |
Етикети:
.NET,
.NET C# technologies,
C#,
Data Mining,
Services,
Software,
Software Development,
Windows Forms
Jan 22, 2008
.NET C# to parse MySQL queries? Impossible? Pavel can make it ;) (with some ifs and buts offcourse ;)
| The most interesting task in my career came the end of the last week. As a Vizibility employee I was asked if I can port osCommerce live site to out vShop solution (http://www.vizibility.co.uk/tmenu/vshop.asp) The interesting thing is that I had no access to osCommerce nor did I ever worked with it. What's even more chalenging - osCommerce database was given to me as SQL queries, something like : drop table if exists table ; create table table ( -- Some things here ... ); insert into table ( As a normal software developer so there were 3 big chalanges: 1. How to parse this SQL thing (it is MySQL) ? 2. How to figure out |
3. How to port all those things as a script so it can be applied to our live servers by the support team?
It's really chalanging don't you think? First I thought it will be a good step to install fresh copy of osCommerce, import the products and try to port them as CSV or something. But then I understood it will take too much time, so I decided to parse the SQL queries on my own and store them in a predefined objects like tables, rows and so on and so on. Then I could easilly transfer them as a text files in the format we needed.
And I almost made it - the parsing methods are done (I was able to parse this thing in a day but some bugs still appear).
Seems the more I work on our shopping solution the more easier I can understand other's shopping solutions.
Great task in a great company!
Етикети:
.NET,
.NET C# technologies,
C#,
Data Mining,
Services,
Software,
Software Development,
Windows Forms
Jan 21, 2008
5 minutes C# code to open Web.Config from Windows Forms application.
| In my previous post about IIS, Virtual Directories and Directory Services you saw how can you obtain the sites per IIS instance as well sa all the root virtual directories. Now it is time to show you how can you obtain the Web.Config file for a root directory. At first glance I thought it will be easy, I thought I will simply need declare the following: using System.Web.Configuration; And / or : using System.Configuration; Well it's not quite this way. In order to load web.config file from a windows forms application you need to have some kind of context to be used or, in other words, file mapping. The following method takes two parameters : path to the root directory and DirectoryEntry, representing the root directory |
And here is the method:
List < string []> GetWebConfigAppSettings( string Path, DirectoryEntry entry)
{
List < string []> items = new List < string []>();
if (entry.Properties[ "Path" ].Value != null )
{
FileInfo fiWebConfig = new FileInfo (entry.Properties[ "Path" ].Value + @"\web.config" );
if (fiWebConfig.Exists)
{
WebConfigurationFileMap fm = new WebConfigurationFileMap ();
System.Collections. Hashtable props = new System.Collections. Hashtable ();
foreach (System.DirectoryServices. PropertyValueCollection property in entry.Properties)
{
string propertyName = property.PropertyName;
props.Add(propertyName, property.Value);
}
VirtualDirectoryMapping mapping = new VirtualDirectoryMapping (fiWebConfig.Directory.FullName, true );
fm.VirtualDirectories.Add(entry.Properties[ "AppRoot" ].Value.ToString(), mapping);
System.Configuration. Configuration cfg = System.Web.Configuration. WebConfigurationManager .OpenMappedWebConfiguration(fm, entry.Properties[ "AppRoot" ].Value.ToString());
foreach ( KeyValueConfigurationElement elmt in cfg.AppSettings.Settings)
{
items.Add( new string [] { elmt.Key, elmt.Value });
}
}
}
return items;
}
The method above will return a List
As you can see the magic begins in :
> System.Configuration. Configuration cfg = System.Web.Configuration. WebConfigurationManager .OpenMappedWebConfiguration(fm, entry.Properties[ "AppRoot" ].Value.ToString());
method. You simply need to make some preparations befor ask it to open the web.config.
Note : this code again is written in few minutes and does not pretend to be optimized, you can again use it at your own will.
Етикети:
.NET,
.NET C# technologies,
C#,
IIS,
Services,
Software Development,
Windows Forms
Jan 13, 2008
Another 5 minutes with C# to post to Google Blogs (Blogger.com) using Google Blogs SDK (2)
Jan 10, 2008
5 minutes with C# - Get your blog in TreeView Control
Етикети:
.NET,
.NET C# technologies,
C#,
Development,
Google Blogs API,
Third Party,
Windows Forms
Another 5 minutes with C# to post to Google Blogs (Blogger.com) using Google Blogs SDK
| // Create service to be used for queries Service service = new Service ( "blogger" , "blogger-sample" ); AtomEntry createdEntry = new AtomEntry (); // Create credentials you should add your blog username // and password here service.Credentials = new GDataCredentials ( "your_username" , "your_password" ); // As I only have one blog to speed up - I am taking it, // You can extend here in order to allow the user to // select from mutliple |
Uri firstBlogUri = GetFirstBlogUri(service);
// If we have the Uri - it's time to actually post.
if (firstBlogUri != null )
{
// Create FeedQuery and assign Uri.
FeedQuery query = new FeedQuery ();
query.Uri = firstBlogUri;
// Create Atom Feed from that query.
AtomFeed feed = service.Query(query);
// Create atom entry for the new post
AtomEntry newPost = new AtomEntry ();
// Fill in the post information
// You need to have a control named richTextBox2 which will
// contain the post body and a textBox1 control which will
// contain the post title.
newPost.Title.Text = this .textBox1.Text;
newPost.Content = new AtomContent ();
newPost.Content.Content = richTextBox2.Text;
newPost.Content.Type = "html" ;
newPost.Authors.Add( new AtomPerson ());
newPost.Authors[0].Name = "Pavel Donchev" ;
// Try to publish and report success / fail:
try
{
createdEntry = service.Insert(query.Uri, newPost);
}
catch ( Exception ex)
{
MessageBox .Show(ex.Message);
}
if (createdEntry != null )
{
MessageBox .Show(newPost.Title.Text + " posted successfully!" );
}
}
There is also a helper function to retrieve the blog Uri:
Uri GetFirstBlogUri( Service service)
{
FeedQuery query = new FeedQuery ();
// Retrieving a list of blogs
query.Uri = new Uri ( "http://www.blogger.com/feeds/default/blogs" );
AtomFeed feed = null ;
feed = service.Query(query);
AtomEntry entry = feed.Entries[0];
for ( int i = 0; i < entry.Links.Count; i++)
{
if (entry.Links[i].Rel.Equals( "http://schemas.google.com/g/2005#post" ))
{
return new Uri (entry.Links[i].HRef.ToString());
}
}
return null ;
}
Jan 8, 2008
5 minutes C# code to help you blog source ...
| As I was unabled to find a reliable editor to convert my code samples to html, I decided to write one. You need two richTextBox components, named richTextBox1 and richTextBox2 and a Button, named button1. Here is the code you need to put into the button1 click event handler: private void button1_Click(object sender, EventArgs e) { string oldColor = "-"; string newColor = string.Empty; StringBuilder strHtml = new StringBuilder(); for (int i = 0; i < this.richTextBox1.Text.Length; i++) { richTextBox1.Select(i, 1); |
if ((newColor != oldColor) && (newColor != string.Empty))
{
if (!oldColor.Equals("-"))
{
strHtml.Append("");
}
strHtml.Append(" + newColor + ";\">");
oldColor = newColor;
}
strHtml.Append(richTextBox1.SelectedText.Replace("<", "<").Replace(">", ">"));
Application.DoEvents();
}
strHtml.Append("");
StringBuilder sbNew = new StringBuilder();
sbNew.Append(strHtml.ToString().Replace(" ", " "));
richTextBox2.AppendText(sbNew.ToString());
}
PLEASE NOTE: this code was written in 5 or 10 minutes, it doesn't pretend to be either clean or readable, it simply works. If you want - you can take it, optimize it, use it or whatever, just have in mind it wasn't written carefully ;).
Етикети:
.NET,
.NET C# technologies,
C#,
Google Blogs API,
Windows Forms
Subscribe to:
Posts (Atom)