|
Hi,
I'm developing an Explorer bar using VS.NET 2003 (C#) on Windows XP. For
some time, I've noticed that I don't have filenames and line numbers
appearing in my exceptions' stack traces. On the other hand, debugging with
breakpoints, etc. seems to work fine in VS.NET 2003. I can't understand why
this isn't working -- and I think it used to work, perhaps under VS.NET
2002, but maybe not. The information doesn't appear in exceptions when
running under VS.NET or when not.
I am running my Explorer bar (which is a class library, not an application)
on the same machine (and user account) which built the library. The PDB
file is accessible to me, and its location does match the location in the
assembly. I am making Debug builds, and I do have "Generate debugging
information" enabled. As far as I can tell, the PDB and DLL files are
equally fresh and the same version?
Any tips? Is this a known bug? It's driving me batty trying to locate an
exception in code blocks without any help from line numbers.
Thanks!
Arun
|
|
|
|
|
When you debug your shell extension, are you debugging a new instance of the shell (explorer.exe)? If the release assembly was registered and the shell invoked it it will continue to use it until the reference count is zero. The only way to do this is kill your shell or be sure to start a new shell when debugging. So long as you're on the same machine, the PE/COFF header (not the assembly) will point to the path of the PDB for debug builds). Since you're sure that it's pointing to the right place, I figured the release version might be registered and running currently.
Otherwise, I can't think of any reason besides your debugging environment being hosed. If you're still getting runtime exceptions (which shouldn't happen in production code, of coruse) that prompt to start a debugger, I doubt this is the case.
If none of the above are the case, when debugging your app, look at the Output window. Do you see where it loads your assembly? Does it say "Symbols loaded" or something similar, or that they can't be found?
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thanks for responding. I do see "Symbols loaded" for my assembly when debugging my assembly, but even still, the line numbers don't appear in the exception's StackTrace.
I'm pretty sure that I'm using the Debug build, as I make a point of not popping up exception-laden message boxes in the release builds.
I even tried rebooting my computer yesterday after building and installing a new Debug release of my browser bar.... just in case.
I started a new solution for a Windows application and was able to get line numbers in the stack trace, so at least I know that the problem is limited to my solution.
|
|
|
|
|
If you took many of the defaults when installing VS.NET (or have installed the Platform SDK), you should have a utility called dumpbin.exe. If you do, type dumpbin.exe /pdbpath <dll path> and see where it thinks the PDB file is located. If it uses a relative path (and I think the PATH directories can contain it, too...don't remember off the top of my head), try moving the PDB file into the same path as the executable (or try another PATH directory). Also make sure that your assembly is registered using regasm.exe /codebase (registering this from the project options uses this switch too).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Okay, there's the ticket!
dumpbin.exe was telling me that the PDB path was relative (.\). So I copied my PDB file into the GAC, right next to my DLL, and it worked. I didn't really expect that to work, but I guess the GAC is more lenient than it seems.
What does the /codebase switch get me? I'm starting to question my current practices, even though they've been working.
I install my assembly like so:
<br />
gacutil /nologo /if VisIT.dll<br />
regasm VisIT.dll<br />
According to C# in a Nutshell, I shouldn't use /codebase if the assembly is in the GAC or if I plan to add it to the GAC. I wonder if I need it in the GAC. I thought I did -- or that it seemed like a good idea -- since this is for a shell extension.
Thanks,
Arun
|
|
|
|
|
The /codebase switch tells regasm.exe to register the full path to the assembly in the registry. Since your assembly is in the GAC, you really don't need this (and I would recommend against it).
IMO, you should refrain from testing assemblies in the GAC. Until you get your explorer bar working, just select the option in your project settings to register it (again, this uses the /codebase switch or at least duplicates the behavior) and test against that until you're ready to deploy it with an installation or something. Sure gets rid of problems like this and keeps your GAC clean, especially if you're using automatic versioning (using the asterisk in the AssemblyVersionAttribute ), which I've learned causes more problems than not (especially large solutions where you update and redirect assembly bindings regularily).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Okay, I'll try to avoid the GAC for now, even though it's been okay for me for the past year. For a short while, I was trying out automatic versioning, but then I turned it off because my installer used a hardcoded assembly version number, and I never got around to finding a dynamic workaround.
Thanks for your helpful persistence.
|
|
|
|
|
If you're using the Windows Installer project in VS.NET, add the output of your project to the installer and it is updated whenever you recompile your C# project (it becomes a dependency of the installer project).
I'm not saying the GAC doesn't work, I'm just saying that it can lead to problems until you're done testing. You've already had one. If you use automatic versioning you'll have lots of assemblies (differing only by version) in your GAC. It doesn't hurt anything, but it sure clutters up the GAC. It's just a recommendation that's not uncommon when debugging applications, especially in larger teams.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I have a WinForm application which appears fine on my computer and several others, but I have found one computer on which some of the controls appears "cut-off".
I have all the controls on the application anchored so that when i view the application on my computer, it looks fine no matter how I resize it. It seems as though on this one other computer that the form is not following the anchoring I had set up. The strange part is, that this only happens on one tab of the application. (There are several other pages in the TabControl set up in the same manner which display fine on all computers). Also, when this "problem computer" is used to view the application via RAdmin on another computer, it appears as it is supposed to.
Any ideas on what could be going on here???
|
|
|
|
|
~michL~ wrote:
Any ideas on what could be going on here???
Screen resolution.
Since .NET uses pixels and pixels display differently on different resolutions, the layout of the form can't truly be garaunteed. This is why some languages like VB6 (and below) use twips, points, and other logical units. The anchoring won't matter in this case because the initial positions and sizes of the controls are correct in relation to pixels. It's pretty hard to explain.
I've actually never seen that big of a problem before. What resolution are you using? What resolution is the other machine using?
If necessary, you can always P/Invoke the GetDeviceCaps native function (for which the SystemInformationClass does, but doesn't support everything) and get the number of pixels per whatever logical unit you like. The reason it works when you use RDP (termainal services) is because you can specify a resolution in which to work when you connect. The graphics card on the target machine should support your target resolution, so you might want to try using that resolution locally on that machine.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Unfortunately, all resolutions on that particular computer display incorrectly so it could not be fixed that easily...meanwhile, on other computers all resolutions do display correctly. I had been using 1280x1024, while the other computer had a res of 1024x768, but like I said, even when changing the resolution of the other computer to 1280x1024, the problem was not fixed.
And since the resolution doesn't solve the problem, it seems that GetDeviceCaps would not solve it either.
|
|
|
|
|
There's more to calculating pixels per logical unit. What is the dpi of the monitor? Is the right driver configured for the display adapter and the monitor itself? These all have a major impact on how things are displayed on your monitor. There's plenty of information about this in the Platform SDK.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I have a Windows form in which I have 5 Button controls, named B1, B2,
B3 .... B5. I want to programatically iterate through these controls,
where I have to work on their properties. Initially all Buttons need
to be invisible. But then iteratively, I want them to be visible. A long handed version is as follows:
while (dr.Read()) {
B1.Visible=true;
B2.Visible=true;
B3.Visible=true;
B4.Visible=true;
B5.Visible=true;
}
I want the following:
while (dr.Read()) {
int i=1;
Bi.Visible=true; //this is just my intent, not an actual statement
i=i+1;
}
where dr is a SqlDataReader. I want i to iterate from 1 through 5, and
then all Buttons are visible. I tried concatenating string to form B1,
B2 etc. programatically, but that does not work.
Help appreciated.
|
|
|
|
|
There are many ways you can do this, such as keeping an array or collection of specific controls you're interested in, or checking the type of the Control in the Controls property of the container Control (like a Form , UserControl , Panel , etc.) like so:
foreach (Control c in Controls)
{
if (c is Button)
{
Button b = (Button)c;
b.Visible = true;
}
} If you only want specific names, make sure the Name property of the Button is assigned and compare that with "B1" through "B5" to make sure it's a Button you want to control.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Heath and Collin, thanks for the reply.
One of the issue is that I am trying to generate a switchboard menu. I have a total of 15 buttons. As users click on the items in the switchboard, the number of buttons dynamically grow or shrink depending on the sub-items under the item being clicked. So, I do not have a static number of buttons that I need to work with.
For example the main menu may look like this:
* Main
* InventoryControl
* ProductionControl
* Exit
This will be represented by 4 buttons (where * represents a button) with corresponding text.
If a user clicks InventoryControl, this window form will be repainted with a different menu, which may have 10 items. So, then I have to make those 10 buttons visible.
Thanks for the help
|
|
|
|
|
Two ways:
1) You could add all the buttons to a collection then iterate over the collection.
2) Alternatively, if these are the only buttons on your form then you could just iterate over the existing Controls collection. (You will notice in the "Windows Form Designer generated code" section there is a section that has lots of this.Controls.Add(...);
Example using existing controls collection on the form:
Button btn;
foreach(Control ctrl in this.Controls)
{
btn = ctrl as Button;
if(btn == null)
continue;
btn.Visible=true;
}
--Colin Mackay--
EuroCPian Spring 2004 Get Together[^]
"You can have everything in life you want if you will just help enough other people get what they want." --Zig Ziglar
|
|
|
|
|
I am trying to update a table from a datatable. The datatable is populated first from a text file and then I would like to get that data into a database datatable. However the code below does not work, part of it is I do not know how to associate the connection string to the data adapter. Also, is there anything else I need to do? Do I need to have separate Update, Insert, and Delete commands or is it possible to just call the Update command?
ConnectToDb connection = new ConnectToDb().conn; //this returns a SqlConnection
SqlDataAdapter da = new SqlDataAdapter();
da.Update(ds.Tables["TradeOrderFillsPre"]);
|
|
|
|
|
Reading the table into a DataTable and adding that to a DataSet is what I would recommend, but iterating over the list of values in the text file and using a simple SqlCommand with SqlParameter s (so you declare the command one and parameterize it to simply change the values and call ExecuteNonQuery ) would also be easy and more efficient.
If you want to use the SqlDataAdapter , you must at least have the SelectCommand assigned to with a SqlCommand for your SELECT statement. In order to insert, update, or delete rows, however, you must have the InsertCommand , UpdateCommand , and DeleteCommand assigned on the SqlDataAdapter . You can use the SqlCommandBuilder with the SelectCommand if the command is simple enough (i.e., JOINs and other advanced statements are not supported). Also, the SelectCommand must be parameterized (see the SqlCommand.Parameters property).
See the SqlDataAdapter class documentation in the .NET Framework SDK (installed by default with VS.NET, and available online from http://msdn.microsoft.com/netframework[^]) for more information and an example of how to use some of these classes.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I have a list view with 3 subitems. I am handling the mouse down event and I would like to find out which subitem was clicked. I can find no easy way to get the subitem rectangle.
How do I do this?
Gary Kirkham
A working Program is one that has only unobserved bugs
I thought I wanted a career, turns out I just wanted paychecks
|
|
|
|
|
One way is to use ListView.GetItemAt to get the ListViewItem that was clicked, then enumerate the ListView.Columns collection and compare the x-coordinate with the incremental ColumnHeader.Width property (i.e., incrementally add the width of the ColumnHeader s as you enumerate and see if the x-coordinate falls within the start and end x-coordinates of the column.
Another way is to override WndProc in a derivative class, define the NMITEMACTIVATE structure, and use the iItem and iSubItem members of the struct. For more information, see the Platform SDK for the LVN_CLICK notification message and the NMITEMACTIVATE structure (includes the NMHDR structure, which you can simply merge the members of into the NMITEMACTIVATE struct if you don't plan on using the NMHDR struct elsewhere).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thanks for the reply.
Heath Stewart wrote:
compare the x-coordinate with the incremental ColumnHeader.Width property (i.e., incrementally add the width of the ColumnHeaders as you enumerate and see if the x-coordinate falls within the start and end x-coordinates of the column.
I thought of that, but it just seemed so kludgey
Gary Kirkham
A working Program is one that has only unobserved bugs
I thought I wanted a career, turns out I just wanted paychecks
|
|
|
|
|
Yeah, but it's certainly a heck of a lot easier than the second way (which encapsulates notification messages and structures for the List-View common control like most of the controls in the .NET Framework base class library do)!
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I ran into some serious bugs in the adobe reader 6.0 activex control. (pdf.ocx has problems when trying to load .xfdf file) I've been at Adobes forums and posted about this topic. People say that the control has zero support. What is a good pdf viewer control that has support for .xfdf ?
(auto merge with linked pdf and no need to save the result. Just needs to have basic viewing features and has to be able to print)
|
|
|
|
|
I have a C# com object that I'm creating which I'm testing in a VB environment. This COM object is also calling other COM objects which were written in VB.
I have a VB COM object with a method who's signature looks like this:
Public Function MyFunction(varNames() As String) As String()
I'm trying to send in a string array when calling this guy in my C# code like this:
string[] sNames = { "ProjectName" };
COMInt.ComClass oCDS = new COMInt.ComClass();<br />
<br />
sValues = oCDS.MyFunction(ref sNames);
I get type mismatch on the "ref sNames". This is just one of many combinations I've tried, but have not quite figured out the correct type match.
Here is the error I receive in VS.Net:
D:\CSS\Dev\ProjName\ProjClass.cs(255): The best overloaded method match for 'COMInt.ComClass.MyFunction(ref System.Array)' has some invalid arguments
Can anybody help me out and explain this?
P.S. Sorry for all the "MyFunction" and "ProjClass", etc.... but this is at work and I could get in trouble just for posting the names of things (they are VERY picky).
There are only 10 types of people in this world....those that understand binary, and those that do not.
|
|
|
|
|
Check the signature of MyFunction . If it doesn't have a ref or out keyword before the param, don't use either ref or out to call the method. String s in .NET (as well as most other classes) are already reference Types, so you rarely need to use ref or out (sometimes it's necessary, like for pointers to pointers, but it's typically only necessary for value types).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|