December 13, 2008 by mikemccabe
Microsoft Visual Studio structures work as ‘Solutions’, each of which can contain multiple ‘Projects’. I create each project in it’s own sub-directory. This leads to a problem…
I wanted to add a project to my solution that used some C# files from another project in the same solution. I tried the straightforward way, choosing ‘Add files…’ on the target project and navigating to the files in the source project. This created a new copy of the file in the target directory – not what I wanted. If I later made changes to the file in one project, I’d have to manually go and make the changes to the same file in the other project, or allow them to diverge. A maintenance headache.
So I did a hack:
- Add the files from the source project to the target project as above
- Save the target project
- Open the target project file (e.g. ‘.csproj’) in a text editor
- Find the file refererences – something like
<Compile Include="FileFromSourceProject.cs" />
- Change to
<Compile Include="..\SourceProject\FileFromSourceProject.cs" />
- Save the project in the text editor
- Delete the unneeded new file copies in the target project directory
- Reopen the target project in Visual Studio. (This happened automatically.)
OK! Now the files show up in the Solution Explorer with a little ‘reference’ icon.
Anyone know how to do this without hacking?
Anyway, this works. Just one file in the file system, logically shared by two projects.
To make this useful in practice, I started using conditional compilation symbols (in project properties -> build) and #if … #endif sections in my code. It’s clumsy and C-ish, but it got the job done.
One more note here: The file will use the compilation symbols from whatever project you open it from – so if you’ve disabled some code for one project, it won’t show up in intellisense, etc. This sometimes means you’ll want to close the file and re-open it by clicking on the right icon or reference in the Solution Explorer to get the right symbols.
It’s simple, but enough of a hack that I had to think a bit to remember how to do it the second time. Maybe this post will help.
Tags: project, references, Solution Explorer, Visual Studio
Posted in Uncategorized | 1 Comment »
July 19, 2008 by mikemccabe
This one took me weeks. My laptop runs a dual boot mac/windows system, which is nifty and all… but managing partitions, and especially fixing partition problems, brings in a world where every step can require an hour with dd to fix. But anyway.
Making a long story short… I mistakenly booted up my laptop with an eSATA drive attached that contained an old exact mirror of my Windows install. Something seemed wrong about the files on the desktop, so I shut down and rebooted without the drive… to discover that the Windows boot now hung at the blue ‘Welcome to Windows XP’ screen. (The MacOS boot was fine.)
During a rescue install, I noticed that Windows now seemed to think that the MacOS partition was the C drive, and the Windows partition was the D drive.
I eventually fixed this by adapting instructions from http://winhlp.com/node/66 to modify the registry on the Windows partition. I booted into Puppy Linux to access the windows files, then copied the registry ‘hive’ to another windows machine to edit it. I tried deleting the entries for \DosDevices\C: and \DosDevices\D: as suggested, but what finally worked was to *swap* the values associated with these entries.
The first thing I did on seeing the problem was to use Puppy Linux and dd to make an image of the problem partition. So I was able to backtrack from the various failed rescue installs I tried, by restoring the image, but each step took hours.
Tags: boot hang, dd, mirror, partition, puppy linux, registry, windows xp
Posted in Uncategorized | Leave a Comment »
January 25, 2008 by mikemccabe
My first C# generic function.
In computer terms, to clamp a value is to make sure that it lies between some maximum and minimum values. If it’s greater than the max value, then it’s replaced by the max, etc. I first learned it in the context of computer graphics, for colors – it’s used for instance to make sure that your raytraced pixel isn’t ‘blacker than black’. So:
public static T Clamp<T>(T Value, T Max, T Min)
where T : System.IComparable<T> {
if (Value.CompareTo(Max) > 0)
return Max;
if (Value.CompareTo(Min) < 0)
return Min;
return Value;
}
(Comments about multiple return values will be forwarded to the circular file.)
Tags: c#, clamp, generic, System.IComparable
Posted in Uncategorized | Leave a Comment »
August 7, 2007 by mikemccabe
The many varieties of spam protection mean that it’s hard to send e-mail from the command-line these days.
I thought I’d see if I couldn’t do it with wget and my squirrelmail webmail account. After much trial and error, here’s what I came up with:
wget --save-cookies cookies.txt --keep-session-cookies --post-data 'login_username=username&secretkey=password' http://webmail.server.com/src/redirect.php
wget --load-cookies cookies.txt --post-data 'body=body here&send_to=recipient%40wherever.com&subject=subject here&send=1' http://webmail.server.com/src/compose.php
Looks like options are:
- send_to
- send_to_cc
- send_to_bcc
- body
- subject
and maybe?:
Posted in Uncategorized | 1 Comment »
April 14, 2007 by mikemccabe
This one took me a while.
I have a .Net 2.0 C# application (in Visual Studio 5.0) with an embedded WebBrowser object. The application automatically loads web pages (for timing tests) – potentially thousands of them over the course of days. As it turns out, this exposes a bad memory leak – every web page the browser visits grows the process by a megabyte or more. I’m pretty sure it’s not my app – I created a bare wrapper around a WebBrowser object, and saw the same behavior. Ditto AxWebBrowser.
OK – how to move it out of process? Visual Basic and WScript types have been doing this for aeons (with CreateObject(“InternetExplorer.Application”)), but it wasn’t obvious how to do it in an early-bound way without InvokeMember calls. I’m sure it’s old lore. But for some reason, it took me a lot of searching! Maybe I can save someone the pain.
Here’s what I found: (adapted from http://www.novicksoftware.com/TipsAndTricks/tip-csharp-open-ie-browser.htm )
You might need to add SHDocVw.dll as a reference to your project. Project->Add Reference->Browse to C:\WINDOWS\system32.
using SHDocVw;
public InternetExplorer GetIE() {
Type oType = Type.GetTypeFromProgID("InternetExplorer.Application");
InternetExplorer result = null;
if (oType != null) {
result = Activator.CreateInstance(oType) as SHDocVw.InternetExplorer;
}
return result;
}
Pretty simple. (Error checking is left as an exercise for the reader
)
The resulting InternetExplorer object is fully typed, joyful and IntelliSense-happy. And it runs in an external process, so calling MyIEObj.Quit() frees the system memory. Leak fixed. Now it’s in an external window, but that’s fine by me. (The ‘InternetExplorer’ type differs from the ‘WebBrowser’ type in that it has some extra application-oriented methods, such as Quit().)
Posted in Uncategorized | 2 Comments »
March 17, 2007 by mikemccabe
I’ve been developing a GUI application in C#, in MS Visual Studio 2005. Mostly a pleasant experience. However…
I recently added a vanilla C++ dll to my C# application, so I could call a few of it’s functions via p/invoke. All was good until I tried to deploy the application to another machine, whereupon I got the usual polite crash notification as soon as I called anything in the application that tried to p/invoke the new dll:
Venturi Wireless Timer has encountered a problem and needs to close. We are sorry for the inconvenience.
On debugging I learned the following: (after installing the .net platform SDK on the remote machine… at 300MB, I’m looking for alternatives!)
An unhandled exception of type ‘System.DllNotFoundException’ occurred in MyCSharpGUI.exe
Additional information: Unable to load DLL ‘mynewdll.dll’: This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem. (Exception from HRESULT: 0×800736B1)
mynewdll.dll was in the application directory, where it should be. Copy to system32… no luck. Rename? The next time I start the application, there’s a quick progress bar, and a fresh copy reappears. So the application install knows about the dll… but is there some kind of manifest voodoo?
The solution: In the installer project for the application, within Visual Studio, go to Properties, click Prerequisites, and check ‘Visual C++ Runtime Libraries (x86)’. Makes sense. A clearer error message might have helped…
Now (unlike other prerequisites) the installer installs the C++ runtime libraries every time, without detecting if they’ve already been installed. Not perfect, but it’s progress!
Posted in Uncategorized | 1 Comment »
March 10, 2007 by mikemccabe
My test blog. When I find a solution to a software problem, I’ll post it here. And maybe other stuff.
Posted in Uncategorized | 1 Comment »