Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
raminasi
Jan 25, 2005

a last drink with no ice
I have a GUI application (written in C#) that remembers its previous settings each time it's run, and there's been a request for functionality to export and import collections of user settings. This seems like something that might already exist in .NET, since the settings are already serialized in an xml file in %appdata%, but I haven't been able to find anything. Is there a solution to this or will I have to roll my own? (This is using .NET 2.0)

Adbot
ADBOT LOVES YOU

raminasi
Jan 25, 2005

a last drink with no ice
I'm working on a WinForms application where the status of many controls depends on values of other controls (check this box to enable this text field, this button is disabled until you type a filename in, et cetera), but it seems overly tedious to hook up event handlers for each thing that could change. I feel like I should be able to register some handler for "anything inside me changed" for the whole form (or any container, really) that would go through and set all the enabled/disabled/whatever in one go.

Am I thinking about this the right way? I'm still fairly new to GUI programming in general. If so, is there any way to do what I'm thinking? I haven't been able to find anything.

(This is .NET 2.0, in C#.)

raminasi
Jan 25, 2005

a last drink with no ice

uXs posted:

You can create one event handler and hook it up to everything. Maybe you'll need seperate ones for each type of control, but that's about it. Plus you can create one function that sets everything and just call that from the few event handlers you have.

Thanks, I knew there was something fundamental that I just wasn't getting.

raminasi
Jan 25, 2005

a last drink with no ice
That's awesome, and solves my "how the hell do I elegantly save settings" problem, too.

raminasi
Jan 25, 2005

a last drink with no ice
I have had a lot of success simply limiting my google searches to microsoft's domains. There's a lot of documentation, but it's pretty good (in my experience).

raminasi
Jan 25, 2005

a last drink with no ice

tinselt0wn posted:

What are people's thoughts on F#? Does it have potential to be taken seriously, or will it be a gimmick that never catches on? I've been dicking around with functional programming, and I'm wondering if I should stick with something tried and true, or start learning f#

I don't know enough real computer science to be able to evaluate languages.

From less language-theoretic point of view, I've been picking up F# for a new project, and I really like it. I feel like my proportion of :doh: bugs has decreased by an order of magnitude (compared to C# and C++, which are the only other languages I've done real work in), and I'm still relatively unfamiliar with the language.

Keep in mind that F# derives significantly from ML, so in a sense, it's pretty "tried and true" out of the box.

(The development tools seem still feel a little immature, but hey)

raminasi
Jan 25, 2005

a last drink with no ice
I am tearing my hair out here.

I want to automate Excel 2010 via COM. I have it installed on my system. I also have Excel 2003 installed on my system. When I try to use the Excel interop assembly version 14.0, Excel 2003 launches. I gather that this is due to some "feature" that makes targeting multiple versions of Office easier, but I just want to loving run 2010. No matter how I reference the version 14.0 assemblies, or which settings I twiddle, the wrong version of Excel runs. I've tried manually editing config files in the bowels of my GAC. I repair-installed the Office development tools for VS2010 and it didn't fix it. I even uninstalled the loving 2003 PIAs and Excel 2003 still launches.

On a whim I cracked open Process Monitor and watched devenv.exe launch Excel 2003, and Excel 2003 proceed to read information out of the Excel 2010 executable, just to mock me.

The only thing I've been able to find is that I might need to disable the publisher policy on something, but I can't figure out where to put the magic XML attribute into the application config file to do this. (I don't even really know what that means or why it might be useful!) It might not even work - it seems like the problem that everyone else has is the opposite of mine (where a newer version of Office hijacks the interop assemblies, not an older version).

I'm almost to the point of just uninstalling Excel 2003, but I don't have the install media for that with me so I won't be able to reinstall it, and I'm not even confident that it will fix anything (I worry that I'll just start getting COM exceptions because it can't find the files it wants).

I'm sorry if I'm not being very coherent with this, it's five thirty in the morning and I'm spent over three hours trying to figure this out. Does anyone have any ideas?

e: ok I fumbled around some more and now I'm getting a build error:
code:
"Cannot find wrapper assembly for type library "VBIDE"
I don't know what this means!

edit again: ok I got it to work somehow, I uninstalled and then reinstalled the Office 2010 dev tools for VS 2010, and then opened Excel 2010 manually which caused it to reinstall something for itself, and then re-added the assembly references to the project and got some weird build warning that I ignored, and then waved my magic wand and sacrificed a goat, and it seems to be working

raminasi fucked around with this message at 14:03 on Jun 15, 2010

raminasi
Jan 25, 2005

a last drink with no ice
I am working in VS2005 with a solution with two projects: an unmanaged console app, and a winforms frontend written in C#. The console app is a .exe that the frontend launches with Process.Start(). Is there a relatively painless way for me to debug the console app when it's launched from the frontend? I've got mixed mode debugging on, and am linking the console app with /ASSEMBLYDEBUG, but I'm still not able to debug it.

I basically have this guy's question, and those answers aren't useful because they misunderstood what he's asking.

raminasi
Jan 25, 2005

a last drink with no ice

ljw1004 posted:

If the spreadsheets are in XLSX format, it'd be an order-of-magnitude faster for you to read the OpenXML format directly...

http://www.devproconnections.com/article/linq/taking-advantage-of-linq-and-xml-in-microsoft-office-2007.aspx

http://blogs.msdn.com/b/bethmassi/a...ffice-2007.aspx

Oh man I wish I had known about this four months ago :cripes:

e: Where did cripes go?

raminasi
Jan 25, 2005

a last drink with no ice
I have a COM question that I can't phrase to put into Google.

I have an application that launches Excel and starts building a spreadsheet. When my app is finished, I want it to release its control over Excel (with the window visible) so that the user can inspect the results, modify them if necessary, and change them. How should I handle this? If I have my app call ReleaseComObject on the Excel application instance, then if I close Excel before quitting my app, the Excel process hangs around until my app quits (in the best case) or gets killed off by DEP for some reason (in the worst case). I know that I'm not doing this "right" but I don't know where to read about how to do it correctly.

raminasi
Jan 25, 2005

a last drink with no ice

tunah posted:

I was going to suggest Marshal.FinalReleaseComObject, and after googling it led me to this:
http://blogs.msdn.com/b/geoffda/archive/2007/09/07/the-designer-process-that-would-not-terminate-part-2.aspx

Well this looks pretty obnoxious. So I have to make sure I'm not leaking anything onto the heap as well as fiddling with the garbage collector at the end?

raminasi
Jan 25, 2005

a last drink with no ice

tunah posted:

Yeah, you probably have a RCW that is hanging on to the COM object.
I have been bitten by COM interop while using DirectShow and it can be a pain to track down where the problem is.
I haven't need to use GC.Collect though, and the code at the end of the page I linked didn't have to either (although it does look pretty obnoxious):
code:
    static void Main(string[] args)
    {
        ApplicationClass excel = new ApplicationClass();
        Workbooks workbooks = excel.Workbooks;
        Workbook workbook = workbooks.Add(Type.Missing);
        Marshal.FinalReleaseComObject(workbook);
        Marshal.FinalReleaseComObject(workbooks);
        excel.Quit();  
        Marshal.FinalReleaseComObject(excel);

        Console.ReadKey();
    }
If you can't solve it, perhaps you can post an minimal example that reproduces the problem and I'll have a look when I'm at the office.

Well I don't want to manually do that for every single thing I touch inside the excel instance, and "Part 1" of that article uses the WaitForPendingFinalizers trick. I'll post an example when I get a chance.

LLJKSiLk posted:

PostMessage(App.Hwnd, WM_QUIT, 0, 0)
[/code]

That is what I got to kill the process every time. I'm sometimes generating 10-11 Excel instances in a row, and the inability to kill it was frustrating as hell.

Unfortunately, I don't want to kill the process, I just want to disconnect (?) the COM automation so that the user has full control over it. (I think that's one of the confounding factors.)

raminasi
Jan 25, 2005

a last drink with no ice

LLJKSiLk posted:

Ummm... Application.UserControl if it isn't read-only could be set to true.

So:

Application.Visible = True
Application.UserControl = True

That gives the user control over Excel's lifetime.


http://support.microsoft.com/kb/302084

I know about Application.UserControl. Here is what happens: My app launches Excel, does its thing, makes Excel visible. User finishes in Excel. User quits Excel. Excel process stays open. User quits my app. Excel process crashes.

raminasi
Jan 25, 2005

a last drink with no ice

LLJKSiLk posted:

Are you using COM interop or have you tried declaring it without the interop as just a new object?

Interop. I wasn't aware there was any other way to do it (well, I had an inkling there might be, but this kind of had to be glued on at the last minute originally).

raminasi
Jan 25, 2005

a last drink with no ice

LLJKSiLk posted:

http://www.developerdotstar.com/community/automate_excel_dotnet

Do it via "Late Binding"

You lose some of the Intellitext stuff, but if your code is valid it works fine.

Well this looks doable. I'll give it a look when I find the time.

What I really want is a way to just write an xlsx file, but I haven't been able to find a library.

raminasi
Jan 25, 2005

a last drink with no ice

Is this only possible using VB?

raminasi
Jan 25, 2005

a last drink with no ice

wwb posted:

Generally no, might be some specific bits that are easier in VB.NET. But I've got a few K LOC building xslx files in pure C#. Managed code is, after all, managed code . .

Yeah, but that first link (at least) has stuff like

quote:

Visual Basic 9 in Visual Studio 2008 has a set of language features that allows developers to work with XML in a much more productive way when using LINQ to XML through what’s called XML literals and XML axis properties. These features allow you to use a familiar, convenient syntax for working with XML in your Visual Basic code. LINQ to XML is an in-memory XML programming API specifically designed to leverage the LINQ framework. Even though you can call the LINQ APIs directly, only Visual Basic allows you to declare XML literals and directly access XML axis properties.

and all the examples are vb. Whatever, guess I'll get on trying to puzzle it out.

raminasi
Jan 25, 2005

a last drink with no ice
How can I create a (mathematical) set of object references? My only equality criterion is "reference the same object," but I can't figure out how to override GetHashCode() to achieve this so I can't figure out how to make a HashSet work.

As I see it, my options are:
-hope that someone here can point me toward a way to do what I want directly,
-modify the referenced objects to each have a unique ID and hash that, or
-decide that my design is bad and rework it somehow.

This is .Net 3.5.

edit: although I'm still curious about the answer to my question, I realized the internal ID thing makes another issue much easier to handle so I'm going with it.

raminasi fucked around with this message at 00:29 on Aug 30, 2010

raminasi
Jan 25, 2005

a last drink with no ice

Kekekela posted:

Not really understanding what you're trying to do here, that's how reference type equality comparisons work by default.

My understanding was that HashSets need a working GetHashCode as well as a working Equals. I can't figure out what the GetHashCode should be.

raminasi
Jan 25, 2005

a last drink with no ice

dwazegek posted:

If you're only interested in reference equality, the default GetHashCode will do exactly what you want. You literally don't have to do a thing.

Microsoft posted:

The default implementation of the GetHashCode method does not guarantee unique return values for different objects. Furthermore, the .NET Framework does not guarantee the default implementation of the GetHashCode method, and the value it returns will be the same between different versions of the .NET Framework. Consequently, the default implementation of this method must not be used as a unique object identifier for hashing purposes.

http://msdn.microsoft.com/en-us/library/system.object.gethashcode%28v=VS.90%29.aspx

raminasi
Jan 25, 2005

a last drink with no ice

shrughes posted:

See RuntimeHelpers.GetHashCode (e: if you already have .GetHashCode doing value equality and want to "not" do that).

This is exactly what I was looking for, thanks!

raminasi
Jan 25, 2005

a last drink with no ice
I'm asking this general design question in the .Net thread in the hope that there's some .Net trick or feature that will help me out.

I'm writing a library that loads a data file at runtime according to a schema specified in another data file I'm loading at runtime. I'm loading a bunch of objects, each of which has some number of fields, each which has a type (integer, real, or string). I'm not quite sure how to allow the user to get the fields out of the objects (with respect to typing issues). For example, I could offer LoadedObject.ValueInteger and LoadedObject.ValueReal and LoadedObject.ValueString and have two of them throw for any particular field, but each field also has a minimum, maximum, and default value, and having to also offer LoadedObject.MinimumInteger and LoadedObject.MinimumReal etc. seems unnecessarily cumbersome.

This isn't a new problem but it's not one I've had to grapple with before. Can anyone point me in the right direction?

(This is .Net 3.5)

raminasi
Jan 25, 2005

a last drink with no ice

Perfectly Cromulent posted:

Perhaps you should use generic GetValue<T>(), GetMinimum<T>(), GetMaximum<T>(), and GetDefault<T>() methods and if the backing field cannot be cast to the specified type, then throw an exception. Would that work, or is there something about your problem that I am not understanding?

No, this is the kind of thing I was looking for. I'm still pretty inexperienced with .Net generics and even simple things like this are not yet intuitive to me. Thanks!

edit: Ok, here's a best practices question for this. None of those four fields are required to actually have a value (even Value). Should I force T to be nullable (is this possible?) or have separate HasValue, HasMinimum, HasMaximum, and HasDefault properties?

raminasi fucked around with this message at 00:48 on Sep 17, 2010

raminasi
Jan 25, 2005

a last drink with no ice

gibbed posted:

Here's how I would do it: I would make a dedicated type to hold these values, provide explicit casts on this type for whatever types it needs to support. Then I would define Value/Minimum/Maximum as this type.

So you'd end up doing (int)x.Value, etc.

How do I distinguish "no value" from "you tried to cast the value to the wrong type?"

raminasi
Jan 25, 2005

a last drink with no ice

Perfectly Cromulent posted:

Well you can't set a struct to null. Also, throwing exceptions for non-exceptional behavior is a bad idea.

Well, I can make FieldValue a reference type. Why don't you think trying to convert the value to the wrong type is exceptional?

raminasi
Jan 25, 2005

a last drink with no ice
One thing I think I neglected to mention was that the "numeric" fields can also have "Autosize" and "Autocalculate" as possible values, so I think I'm just going to say gently caress it and make a FieldValue class with all sorts of fun properties like "IsInteger" and "IsAutosize" and "IsNothing" and some explicit casts and just make the user do all the stupid checking.

e: this will be backed by a couple of F# discriminated unions so the implementation code won't be completely unholy.

raminasi
Jan 25, 2005

a last drink with no ice
I couldn't figure out whether to post this here or in the C++ thread.

If I'm writing an app that needs to talk to both a heavily templated C++ library and a .Net assembly, should I dive right in and do the whole thing in C++/CLI, or should I stick with straight C++ and try to wall off the .Net assembly with some kind of wrapped reverse platform invoke?

In the former case, when the C++ standard library duplicates functionality supplied by .Net, which should I use?

I'm ok with the app being Windows-only.

edit: looks like the decision is made for me because I can't get Visual Studio to respect my #pragma unmanageds so I can't use the C++ math library I need. .Net concentration camp it is.

raminasi fucked around with this message at 03:38 on Oct 28, 2010

raminasi
Jan 25, 2005

a last drink with no ice
Practices question: I'm writing a library for an application that targets .Net 3.5, but will eventually switch to targeting .Net 4.0. I have some APIs that return sets of data. Which is the best solution:
-return HashSets now, switch to ISets when the client application switches to 4.0
-return ICollections now, switch to ISets when the client application switches to 4.0
-something else?

edit: I just realized (hurr) that option #2 might break client code down the road while option #1 won't, so I guess this post is really fishing for some other solution I haven't thought of (or else I'll go with HashSets)

raminasi fucked around with this message at 23:04 on Nov 5, 2010

raminasi
Jan 25, 2005

a last drink with no ice

bobua posted:

Thanks, that explained everything.

I've been going back and forth change\adding\removing stuff and my variable names and what not are probably as bad or worse than my code. I think I read a webpage long ago that had a big 'FORMAT YOUR poo poo LIKE THIS PLEASE' section, is there an accepted goto way to do it in .net\c# ?

http://msdn.microsoft.com/en-us/library/ms229042.aspx

raminasi
Jan 25, 2005

a last drink with no ice
e: never mind, I think I found a MSVS bug and I'm testing it out more now!

raminasi fucked around with this message at 07:31 on Nov 16, 2010

raminasi
Jan 25, 2005

a last drink with no ice
code:
        private void generationWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            MessageBox.Show("what");
            BackgroundWorker worker = (BackgroundWorker)sender;
            Excel.Application excel = new Excel.Application();
            SimpleModelMapper.Generator.Generate(iddFileNameTextBox.Text, groupsFileNameTextBox.Text, cbGenerateRaw.Checked, cbGenerateFolded.Checked, worker, excel);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
        }
As written, that function is never reached (that message box doesn't show and breakpoints aren't hit) after calling generationWorker.RunWorkerAsync(), although generationWorker_RunWorkerCompleted is. If I comment out the fourth line (the call to Generate()), the function is reached.

What the gently caress? This worked fine before I added two parameters to Generate()

edit: ok i figured this stupid poo poo out
The problem was caused by me simultaneously upgrading and downgrading my Office install by upgrading my 2003 to 2007 when the 2010 beta expired. My interop assemblies got borked, but Visual Studio couldn't figure this out for me. I solved the problem by removing and re-adding references to the assemblies.

The only explanation I can think of for the heisenbug is that when the function call that actually used the Excel object wasn't present in the code, the JIT removed the object's construction as well, and so there was no problem. When the Excel object was used, something went wrong with the COM interface but the error was just swallowed. Or something. I'm grasping at straws here.

raminasi fucked around with this message at 03:51 on Nov 19, 2010

raminasi
Jan 25, 2005

a last drink with no ice

uXs posted:

Are you reading interface properties in a backgroundworker? Is that allowed?

You mean pulling information off the GUI? I've never had a problem with it before, and usually problems with that kind of thing cause crashes, not mystery no-ops.

raminasi
Jan 25, 2005

a last drink with no ice

ljw1004 posted:

Microsoft's replacement for all this stuff is called "Async", and is planned for a future version of C#/VB. We released a public CTP of it last month. Download at http://msdn.com/vstudio/async

In the meantime, until that ships, you're stuck with either iterators or RX. Every async iterator library is more or less the same. There are some standard TPL samples that demonstrate a slightly simpler API for doing iterators rather than CCR. Also consider looking at Jeff Richter's AsyncEnumerator.

Am I understanding correctly that the features in this CTP are already in the current version of F#? (Not that it's necessarily relevant to the question you were responding to.)

raminasi
Jan 25, 2005

a last drink with no ice

IratelyBlank posted:

Do any of you guys use F#? I have been reading through this site: http://en.wikibooks.org/wiki/F_Sharp_Programming and following along in VS but it's so different than what I'm used to and a little hard to wrap my head around. It seems really fun, though. I've done a bunch of the problems on http://projecteuler.net using C# and I am going to attempt to go back through and use F# to solve them. Hopefully it will be a good learning experience.

I've been teaching myself F# over the past six months or so and I loving love it. The ratio of "time spent getting work done" to "time spent debugging stupid poo poo" is far, far higher than any other language I've ever (seriously) worked in. I've always been kind of into functional programming, though.

raminasi
Jan 25, 2005

a last drink with no ice
I have an F# assembly that has as one of its dependencies the F# core assembly (naturally). Another of its assemblies is a different library that also depends on the F# core assembly. However, when I try to create an installation project, the project detects two different F# core assemblies (one with a path in the GAC somewhere and one in the Visual F# program files directory) and tries to install them both. Since they have the same name, only one of them ends up on the target machine, and then the application doesn't work because it can't find the F# core assembly.

I know I don't understand enough about the way assemblies and the GAC and all that stuff works, and now it's coming around to bite me in the rear end. How do I fix this problem?

raminasi
Jan 25, 2005

a last drink with no ice

Derpes Simplex posted:

I'll bet you're referencing two different versions of the assembly. Make sure both are targeting the same version of the .NET runtime, for starters.

Oh good lord why didn't I think of that :downs:

e: ok, how do I fix this? I'm not relying on any 4.0-specific code (that I know of), but I can't figure out how to get the project to "indirectly reference" 3.5 versions of assemblies instead of 4.0 versions (even when I change the targeted profile in the application tab of the project settings and remove all the references)

raminasi fucked around with this message at 03:04 on Dec 19, 2010

raminasi
Jan 25, 2005

a last drink with no ice
Is there a way, in WPF, to data bind to user settings in the designer/properties window/gui at all? All the ways I can find to do it online involve editing the xml directly.

raminasi
Jan 25, 2005

a last drink with no ice

PhonyMcRingRing posted:

Are you talking about your application settings? The one that inherits from System.Configuration.ApplicationSettingsBase? The class implements INotifyPropertyChanged so you should be able to bind to an instance just fine.

I just can't find my way around the visual studio gui to do it. I have the control that's the binding target (?) but I can't find what I'm looking for anywhere in the Common -> DataContext drop-down of its Properties window. I think I managed to add the settings to the DataSources for the project but they're still not showing up anywhere.

This is literally my first time using WPF so I have no idea how the gently caress anything works yet.

raminasi
Jan 25, 2005

a last drink with no ice
Yeah, if you're not doing something super-complicated then BackgroundWorkers are dead loving simple to use (so if you use one and it seems difficult at all there's probably an easier way).

Adbot
ADBOT LOVES YOU

raminasi
Jan 25, 2005

a last drink with no ice
I have a C application that receives a FILE * and writes stuff to it, and I want to use this functionality from .NET (4.0). I know how to do basic platform invoke, but I can't figure out what to use for the FILE * in the call into the native application. I tried using the unsafe handle from an anonymous PipeStream but I'm not receiving any data (even after I turned buffering off on the C side - I couldn't see how to try that on the C# side). I feel like I should be using an UnmanagedMemoryStream but I can't figure out how to set it up.

As icing on the cake, this needs to be asynchronous.

  • Locked thread