Tuesday, April 5, 2011

Tool to import Type Libraries as C# code

Is there a tool to import/convert COM type libraries into C# code rather than generating an assembly? The TLBIMP tool and the TypeLibaryConverter class only generate assemblies.

I've had some success ripping the C# ComImport definitions by running Reflector over the generated Interop assembly and copying a pasting the disassembled source, but this usually requires quite a bit of manual patching up before it'll compile.

Desired goal is a single EXE without satellite Interop DLLs, so perhaps the answer is to use ILMerge to effectively embed the interop DLL in the EXE.

I was sure in the past I'd come across such a tool - but maybe it dreamt it :-)

From stackoverflow
  • This won't help you out today, but there is a feature coming in the next version of C#. It's called NoPia or Type Embedding depending on which presentation you read. This feature essentially will link a PIA assembly into whatever project you reference it from. The end resulrt is a single EXE which no need to deploy an interop/PIA DLL.

    Misha's post on the subject: http://blogs.msdn.com/mshneer/archive/2008/10/28/type-embedding-support-in-c.aspx

    Short term though, you may have to go with ILMerge or reflector + copy code.

    Duncan Smart : Yes I'd heard about that. Roll on CLR 4.0!
  • I'm not so sure it is going to be useful to you, but the source code for a managed version of Tlbimp.exe has been released on CodePlex. VS2010 will definitely solve your problem.

    Duncan Smart : Cool - I didn't know that! I'll take a look...
  • As I originally suspected the best solution is going with ILMerge. I can't be selective about parts of a COM API to embed, but it works well enough.

    Here is the Post Build Event Command Line I'm using, which should be easy enough to reuse:

    set MERGEFILES=Interop.Foo.dll Interop.Bar.dll
    
    if "$(ConfigurationName)" == "Release" (
       ren "$(TargetFileName)" "_$(TargetFileName)"
       "$(ProgramFiles)\Microsoft\ILMerge\ILMerge.exe" /out:"$(TargetFileName)" "_$(TargetFileName)" %MERGEFILES%
    
       del "_$(TargetFileName)"
       del %MERGEFILES%
    )
    

Can I interact with Camtasia's player using Javascript?

I have a site where i'm showing 2 "tutorial" videos recorded with Camtasia.
They are both "autostart=false"

I'm using the combination of an mp4 file, and the movie_controller.swf files.

I would like to be able to start a movie through Javascript (i'm assuming this is possible), and also get notified in Javascript when the movie finishes.

Is this possible? Is it documented anywhere?

Thanks!

From stackoverflow

How can I handle an ASX stream which uses features that Silverlight doesn't support (e.g. REPEAT)

I'm trying to display a video feed which is provided as a server side playlist (ASX) by another party. The playlist contains some unsupported features, such as repeat:

<ASX VERSION="3.0">
  <REPEAT COUNT="4">
    <EntryRef href="http://some-ad-network.com/ad.asx" />
    <Entry>
      <Ref href="http://video-host/content-primary-source"></Ref>
    </Entry>
    <Entry>
      <Ref href="http://video-host/content-secondary-source"></Ref>
    </Entry>
  </REPEAT>
</ASX>

Silverlight 2.0 doesn't support the REPEAT element and throws an exception:

REPEAT Element: This is not supported and will raise a MediaError with AG _ E _ ASX _ UNSUPPORTED _ ELEMENT.

Is there a workaround? Can I pull the ASX file down via HttpWebRequest, parse it, and request the streams individually? Do you know of a library or some sample code somewhere which handles ASX file parsing?

From stackoverflow
  • The Attributes gets the collection of MediaAttribute objects that corresponds to the current entry in the ASX file that Source is set to. here is a javascript example:

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

    Jon Galloway : I can't load the ASX file in Silverlight - it throws an exception. How can I get at the Attributes if I can't load it?
  • I ended up having to parse the ASX file myself and manually load the elements. Peter's suggestion is helpful if the ASX file will load, but the Silverlight ASX parser throws exceptions when it encounters most unsupported elements so you never get the chance to load from the Attributes property.

  • I also made a custom asx parser because of bad asx handling in the MediaElement. It corrects several bugs, see http://blog.revolunet.com/index.php/general/wpf-mediaelement-asx-workaround

How to obtain the IDbCommand output to the DB? (.NET)

I have a SqlCommand object, and I execute its ExecuteNonQuery method. The query fails, but I can't see how to obtain the query to debug it. Could you help me?

Update I am currently using Wireshark (tcpdump) to read the command, but I think that its not the best solution

Update The CommandText property only provides the Stored Procedure name. I want the whole command, with the parameters.

From stackoverflow
  • You can use SQL Profiler to see what is the query/call to stored procedure being sent along with parameterrs.

    Russ Cam : and also connection settings, such as NOCOUNT, ARITHABORT, etc.
  • You can get the value of the CommandText property of your SqlCommand ? If an exception is thrown, you can catch it, and access the CommandText property which will give you the SQL command like you've set it. Offcourse, if it contains parameters, the parameters won't be replaced by the appropriate values.

    Jader Dias : The CommandText property only provides the Stored Procedure name. I want the whole command, with the parameters.
  • If you also want to see the parameters then you have to look at the Parameters property of the command object (not just the CommandText), and look at each parameter in this collection to extract the value and datatype, if that's what you're interested in.

    Now, it sounds like what you're trying to debug is the stored procedure itself, not the C# code, is that right? If that's the case you need to attach your visual studio debugger to the SQL server to debug the T-SQL code. I know you can do this with Oracle, so I'm assuming you should be able to do this right out of the box with SQL server.

  • You should probably be using a try/catch block around your SQL anyway but the upside of doing this is you can easily return your SQL command string along with the error.

    Something like this should do it:

    try
    {
        ***Execute your SQL query here***
    }
    catch (Exception e)
    {
        Console.WriteLine(e.ToString());
        Console.WriteLine(***My SQL command string***);
    
    }
    

Putting existing versions and branches of a project under version control

I am the only developer of a software project. I did not use any version control until now. I know I can put the last version of the project under version control. The question is whether it is possible to put older versions and branches of the project under version control. If it is possible, how ? which version control software should I use ? (I am using Visual Studio 2008)

Edit: I have almost all previous versions.

From stackoverflow
  • You could do it, assuming you have copies of the older revisions that you want to put into source control (you can't magically make them appear, of course).

    What I would do is take the oldest version, put it somewhere, and commit the folder to your source control (this would become Revision 1). Then, take the second-oldest version, overwrite the first version on your hard drive with that, then check in again (this becomes Revision 2 in source control). Repeat, overwriting with the next-newest revision each time until all of the versions you want are checked in.

    There are good, free version control systems available. I use SVN (with the TortoiseSVN shell add-on), and I'm quite happy with it. CVS is alright too, but gets very slow as projects get large.

    Andy : Deleted files will be a problem, but I agree. This will preserve the history best.
    DannySmurf : True, but there's no way he's going to get a blow-by-blow of development, like he would if he had been using source control all along. These are necessarily just snapshots, and files that were previously deleted can just be removed from the most recent revision.
    Multilist : What about branches ? I have currently 2 branches (without version control)
    Keltia : All VCS support branches so just import on separate ones.
    Multilist : These 2 branches share some of the code, if I import them separately, will I be able change the share code once.
    DannySmurf : That depends on the VCS. As far as I know, with SVN or CVS you can't do that. Changes are made on the branch, then merged with the trunk (or vice versa).
    Andrew Swan : @Andy - deleted files needn't be a problem. After committing the oldest version, delete everything from the working copy and paste in the second oldest version. The SCM should correctly detect what's been added, changed, and deleted.
  • Which VCS you should use is really up to you. I'd recommend Mercurial as it is a very good distributed VCS and runs rather well under Windows. I don't know what VS support but you may want to use a supported VCS (which probably means Subversion I guess). There is TortoiseHg available there as well.

    If you have all previous versions, you can import them manually, one after the other to get to the last one then work from that.

Team Foundation Explorer - Check In for the First Time

How do you check in code for the first time in Team Foundation Server?

I created a local path, dropped some code in it, now what? Hitting refresh doesn't help.

From stackoverflow
  • you have to right-click on the solution in your project explorer and select "Add project to source control". Then it will walk you through the process of adding it to TFS.

    tyndall : +1 That worked great! Thanks. Now, hypothetically, lets say I have some Ruby files in a separate folder (not a project) how would I check those in?
    rwmnau : Another poster mentioned it, but in the Source Control viewer in Visual Studio, there are "Add files" and "Add folders" buttons on the toolbar that let you add files that aren't part of a project. If you don't have VS, another option is http://www.teamprise.com
  • If you just want to add files to source control without using a solution, then you need to actually add them to TFS. TFS will only show the files it knows about in source control.

    In the Source Control Explorer window there should be an add file button. You can hit that and use it to add files/folders to source control.

  • I would also suggest you install the latest edition of Power Tools for TFS - which includes the Windows Explorer Shell (you need to select custom install for that). This will add a context menu in Windows Explorer for directories that are mapped to a Workspace - so you won't have to start Visual Studio to do simple file manipulation like this.

    The download is here: http://msdn.microsoft.com/en-us/tfs2008/bb980963.aspx

    Herms : +1 - You, sir, are my hero. I've wanted something like TFS/explorer integration for a while now. Thanks!
    tyndall : +1 very cool. Thanks

Convert List<List<T>> into List<T> in C#

I have a List<List<int>>. I would like to convert it into a List<int> where each int is unique. I was wondering if anyone had an elegant solution to this using LINQ.

I would like to be able to use the Union method but it creates a new List<> everytime. So I'd like to avoid doing something like this:

List<int> allInts = new List<int>();

foreach(List<int> list in listOfLists)
   allInts = new List<int>(allInts.Union(list));

Any suggestions?

Thanks!

From stackoverflow
  • How about:

    HashSet<int> set = new HashSet<int>();
    foreach (List<int> list in listOfLists)
    {
        set.UnionWith(list);
    }
    return set.ToList();
    
    : This is nice. I didn't know that the HashSet had a UnionWith method. Thanks.
    Spence : perfect job for a reduce function if it existed in linq.
    D.Shawley : I personally like this approach... use a set since it will eliminate duplicates. No magic here. It works anywhere ;)
  • List<List<int>> l = new List<List<int>>();
    
    l.Add(new List<int> { 1, 2, 3, 4, 5, 6});
    l.Add(new List<int> { 4, 5, 6, 7, 8, 9 });
    l.Add(new List<int> { 8, 9, 10, 11, 12, 13 });
    
    var result = (from e in l
                  from e2 in e
                  select e2).Distinct();
    
    Jon Skeet : This is in many ways a nicer solution than mine. +1.
    : This is what I was looking for. Just add a .ToList() at the end of the Distinct and I have what I need. Thanks!
    Jon Skeet : My comment was aka "Darn - why didn't I think of that?" :)
    Frederik Gheysels : It might be faster then Jon's solution , but I think Jon's is more readable.
    ctacke : +1 for beautiful code
    j0rd4n : +1 for having Jon tell you it was a nicer solution. ;)
    Ria : +1 because this rocks -- have you considered putting in a "where e != null" though, so it does not start throwing things when you have a null list inside your list?
  • List<int> result = listOfLists
      .SelectMany(list => list)
      .Distinct()
      .ToList();