Googles appar
Huvudmeny

Post a Comment On: cbloom rants

"08-06-10 - Visual Studio File Associations"

19 Comments -

1 – 19 of 19
Blogger Jeff Roberts said...

Can't you just associate c and h to a batch 4dos batch file that looks for the MSVC that's running?

August 8, 2010 at 11:22 PM

Blogger cbloom said...

4dos can look for an MSVC?

August 9, 2010 at 12:20 AM

Blogger Unknown said...

Easier. Why not to create a batch file for each VS you are using, that will modify the register to change file association for the one its going about to run, like

vs08.bat
-> associate cpp,hpp with vs08
-> run vs08

vs10.bat
-> associate cpp,hpp with vs10
-> run vs10

should be quite simple

August 9, 2010 at 7:34 AM

Blogger cbloom said...

That's a pretty good idea. How do I do :

-> associate cpp,hpp with vs08

?

August 9, 2010 at 9:50 AM

Blogger Unknown said...

You can use "assoc" to change file associations from the command line.

I don't have VisualStudio on this machine to check the exact syntax but running "assoc .cpp" will show you the current association. Just changing the version number is usually enough ...

August 9, 2010 at 2:03 PM

Anonymous Anonymous said...

Try ASSOC and FTYPE. Looks like ASSOC maps extension to type, and FTYPE maps type to application. I guess you could create one type for each version of VS, then use ASSOC to change the mapping.

A quick google suggests http://ss64.com/nt/assoc.html has some info...

August 9, 2010 at 2:21 PM

Anonymous Anonymous said...

BTW Here's what my PC says for .cpp:

[0][ C:\bin\4nt ]assoc .cpp
.cpp=VisualStudio.cpp.8.0

[0][ C:\bin\4nt ]ftype VisualStudio.cpp.8.0
VisualStudio.cpp.8.0="C:\vs2005\Common7\IDE\devenv.exe" /dde

August 9, 2010 at 2:22 PM

Anonymous Anonymous said...

Goddamnit, blogger ate my first post with my second one. My first post was basically "see ASSOC and FTYPE, the mapping is 2-step, oh and here's a link: http://ss64.com/nt/assoc.html".

August 9, 2010 at 2:24 PM

Blogger cbloom said...

Whoah , I had no idea assoc & ftype existed. Awesome.

August 9, 2010 at 3:24 PM

Blogger Sam said...

Woah, assoc and ftype. That is awesome!

August 10, 2010 at 6:25 AM

Blogger Tom Johnstone said...

That doesn't support the default "open in notepad" though. That same problem has been pissing me off for a while, so I wrote a little app which reroutes file opens-

#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

#include <string>

// Forward declarations:
BOOL ListProcessModules( DWORD dwPID, const char* filename );
BOOL ListProcessThreads(const char* filename);

void main( int argc, const char** argv )
{
if (argc != 2)
{
printf("usage: %s [filename]\n", argv[0]);
return;
}

if (!ListProcessThreads(argv[1]))
{
std::string path;
path += "start notepad ";
path += argv[1];
system(path.c_str());
}
}

BOOL ListProcessModules( DWORD dwPID, const char* filename )
{
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 me32;

// Take a snapshot of all modules in the specified process.
hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwPID );
if( hModuleSnap == INVALID_HANDLE_VALUE )
{
return( TRUE );
}

// Set the size of the structure before using it.
me32.dwSize = sizeof( MODULEENTRY32 );

// Retrieve information about the first module,
// and exit if unsuccessful
if( !Module32First( hModuleSnap, &me32 ) )
{
CloseHandle( hModuleSnap ); // Must clean up the snapshot object!
return( TRUE );
}

// Now walk the module list of the process,
// and display information about each module
do
{
if (strstr(me32.szModule, "devenv.exe"))
{
std::string path = "start \"";
path += me32.szExePath;
path += "\" ";
path += filename;
printf(path.c_str());
system(path.c_str());
CloseHandle( hModuleSnap );
return FALSE;
}
} while( Module32Next( hModuleSnap, &me32 ) );

// Do not forget to clean up the snapshot object.
CloseHandle( hModuleSnap );
return( TRUE );
}

BOOL ListProcessThreads(const char* filename)
{
HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
THREADENTRY32 te32;

// Take a snapshot of all running threads
hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
if( hThreadSnap == INVALID_HANDLE_VALUE )
return( TRUE );

// Fill in the size of the structure before using it.
te32.dwSize = sizeof(THREADENTRY32 );

// Retrieve information about the first thread,
// and exit if unsuccessful
if( !Thread32First( hThreadSnap, &te32 ) )
{
CloseHandle( hThreadSnap ); // Must clean up the snapshot object!
return( TRUE );
}

// Now walk the thread list of the system,
// and display information about each thread
// associated with the specified process
do
{
if (!ListProcessModules(te32.th32OwnerProcessID, filename))
return TRUE;
} while( Thread32Next(hThreadSnap, &te32 ) );

// Don't forget to clean up the snapshot object.
CloseHandle( hThreadSnap );
return( FALSE );
}

August 14, 2010 at 10:08 PM

Blogger cbloom said...

Well done sir, I just built it and it seems to work dandy.

Yeah the assoc/ftype thing is awesome but doesn't actually solve the problem in question.

I mean, say I run vs08.bat , then vs10.bat , then close my vs10, it's associated to the wrong thing. Buggy, fragile.

August 14, 2010 at 10:33 PM

Blogger Tom Johnstone said...

This version's a little bit quicker. I was finding it a little bit laggy when running through VM Ware on my laptop-


#include <tlhelp32.h> 
#include <stdio.h> 
#include <string>

#pragma comment(lib, "User32.lib")

// Forward declarations: 
BOOL ListProcessModules( DWORD dwPID, const char* filename ); 
BOOL CALLBACK EnumWindowsProc(__in HWND hwnd, __in LPARAM lParam);

void main( int argc, const char** argv )
{
    if (argc != 2)
    {
        printf("usage: %s [filename]\n", argv[0]);
        return;
    }
    
    if (EnumWindows(&EnumWindowsProc, (LPARAM)argv[1]))
    {
        std::string path;
        path += "start notepad ";
        path += argv[1];
        system(path.c_str());
    }
}

BOOL ListProcessModules( DWORD dwPID, const char* filename ) 

    HANDLE hModuleSnap = INVALID_HANDLE_VALUE; 
    MODULEENTRY32 me32; 

    // Take a snapshot of all modules in the specified process. 
    hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwPID ); 
    if( hModuleSnap == INVALID_HANDLE_VALUE ) 
    { 
        return( TRUE ); 
    } 

    // Set the size of the structure before using it. 
    me32.dwSize = sizeof( MODULEENTRY32 ); 

    // Retrieve information about the first module, 
    // and exit if unsuccessful 
    if( !Module32First( hModuleSnap, &me32 ) ) 
    { 
        CloseHandle( hModuleSnap ); // Must clean up the snapshot object! 
        return( TRUE ); 
    } 

    // Now walk the module list of the process, 
    // and display information about each module 
    do 
    {
        if (!strcmp(me32.szModule, "devenv.exe"))
        {
            std::string path = "start \"";
            path += me32.szExePath;
            path += "\" ";
            path += filename;
            printf(path.c_str());
            system(path.c_str());
            CloseHandle( hModuleSnap ); 
            return FALSE;
        }
    } while( Module32Next( hModuleSnap, &me32 ) ); 

    // Do not forget to clean up the snapshot object. 
    CloseHandle( hModuleSnap ); 
    return( TRUE ); 
}

BOOL CALLBACK EnumWindowsProc(__in HWND hwnd, __in LPARAM lParam)
{
    DWORD threadId;
    GetWindowThreadProcessId(hwnd, &threadId);
    const char* filename = (const char*)lParam;
    return ListProcessModules(threadId, filename);
}

August 15, 2010 at 7:49 AM

Blogger cbloom said...

Why don't you just use TH32CS_SNAPPROCESS ?

I'm turning this into a more generic utility I'll call SendTo , which will look for any process name and send the file to it, and errorlevel return if not found, so you can then run the default from a batch file.

August 15, 2010 at 8:18 AM

Blogger Tom Johnstone said...

Well I guess you don't really need to enumerate all processes, just the ones with windows

August 15, 2010 at 8:23 AM

Blogger Tom Johnstone said...

In fact you only need to check the first module of each process too, as that is guaranteed to be the exe

August 15, 2010 at 8:38 AM

Blogger cbloom said...

" Well I guess you don't really need to enumerate all processes, just the ones with windows "

Yeah but the number of processes is like an order of magnitude smaller than the number of windows typically (a few hundred vs a few thousand)

August 15, 2010 at 9:22 AM

Blogger Tom Johnstone said...

sendto.cpp-

#include <Windows.h>
#include <tlhelp32.h>
#include <stdio.h>
#include <string>
BOOL ListProcessModules( DWORD dwPID, const char* processName, const char* filename )
{
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 me32;
// Take a snapshot of all modules in the specified process.
hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwPID );
if( hModuleSnap == INVALID_HANDLE_VALUE )
{
return( TRUE );
}
// Set the size of the structure before using it.
me32.dwSize = sizeof( MODULEENTRY32 );
// Retrieve information about the first module,
// and exit if unsuccessful
if( !Module32First( hModuleSnap, &me32 ) )
{
CloseHandle( hModuleSnap ); // Must clean up the snapshot object!
return( TRUE );
}
CloseHandle( hModuleSnap ); // Must clean up the snapshot object!
if (strstr(processName, me32.szModule) == processName)
{
std::string path;
path += "start \"\" /B \"";
path += me32.szExePath;
path += "\" ";
path += processName + strlen(me32.szModule);
path += " \"";
path += filename;
path += "\"";
printf("%s\n", path.c_str());
system(path.c_str());
return FALSE;
}
return( TRUE );
}
BOOL ListProcessThreads(const char* processName, const char* filename)
{
HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
THREADENTRY32 te32;
// Take a snapshot of all running threads
hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
if( hThreadSnap == INVALID_HANDLE_VALUE )
return( TRUE );
// Fill in the size of the structure before using it.
te32.dwSize = sizeof(THREADENTRY32 );
// Retrieve information about the first thread,
// and exit if unsuccessful
if( !Thread32First( hThreadSnap, &te32 ) )
{
CloseHandle( hThreadSnap ); // Must clean up the snapshot object!
return( TRUE );
}
// Now walk the thread list of the system,
// and display information about each thread
// associated with the specified process
do
{
if (!ListProcessModules(te32.th32OwnerProcessID, processName, filename))
return TRUE;
} while( Thread32Next(hThreadSnap, &te32 ) );
// Don't forget to clean up the snapshot object.
CloseHandle( hThreadSnap );
return( FALSE );
}
int main( int argc, const char** argv )
{
if (argc != 3)
{
printf("usage: %s [process name] [filename]\n", argv[0]);
return -1;
}
if (!ListProcessThreads(argv[1], argv[2]))
{
return 1;
}
return 0;
}

August 23, 2010 at 7:31 PM

Blogger Tom Johnstone said...

vcsendto.bat-

@echo off
"%~dp0sendto" "devenv.exe /Edit" %1
if ERRORLEVEL 1 start notepad %1

August 23, 2010 at 7:32 PM

You can use some HTML tags, such as <b>, <i>, <a>

This blog does not allow anonymous comments.

Comment moderation has been enabled. All comments must be approved by the blog author.

You will be asked to sign in after submitting your comment.