Thread: Using a program to open a program?

  1. #1
    Registered User muffinman8641's Avatar
    Join Date
    Feb 2011
    Location
    Eastern-Central PA
    Posts
    76

    Using a program to open a program?

    I tried a few I found online with no help.

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    There are a couple of ways, mostly platform-specific. The only portable way is system, but it has its own problems.
    May I assume it's for Windows? In that is the case, I have some code that might help.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User muffinman8641's Avatar
    Join Date
    Feb 2011
    Location
    Eastern-Central PA
    Posts
    76
    It is for Windows.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Here is what I use. It's not perfect, it needs work, but at least it's something.
    If you can't figure out how to get it compiling, let me know.
    Code:
    #ifndef RUN_PROCESS_H_20100822_1318
    #define RUN_PROCESS_H_20100822_1318
    
    #include <Windows.h>
    #include <string>
    #include <assert.h>
    #include "StringTraits.h"
    #include "Utility\Identifier.h"
    
    namespace Stuff
    {
    	namespace Process
    	{
    		namespace detail
    		{
    			template<typename StructT, typename StrT, typename ExecuteT> HRESULT RunProcess(
    				const StrT& Process, const StrT& Parameters, int nShow, bool Wait, bool ManualWait, ExecuteT ExecuteFnc, HANDLE* pH)
    			{
    				StructT seinfo = {};
    				seinfo.cbSize = sizeof(seinfo);
    				seinfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
    				seinfo.lpVerb = StrTraits<StrT>::OpenText;
    				seinfo.lpFile = Process;
    				seinfo.lpParameters = Parameters;
    				seinfo.nShow = nShow;
    				HRESULT hr = S_OK;
    
    				if (! ExecuteFnc(&seinfo) )
    				{
    					hr = (HRESULT)GetLastError();
    					//auto hr = (HRESULT)GetLastError();
    					//std::wcout << L"Error calling ShellExecuteEx!\n";
    					//__asm int 3;
    				}
    				if (hr != S_OK)
    					return hr;
    				if (ManualWait)
    				{
    					assert(pH);
    					*pH = seinfo.hProcess;
    				}
    				else
    				{
    					WaitForSingleObject(seinfo.hProcess, INFINITE);
    					CloseHandle(seinfo.hProcess);
    				}
    				return hr;
    			}
    		}
    
    		__declspec(deprecated) inline HRESULT Run(const std::string& Process, const std::string& Parameters, int nShow = SW_SHOWNORMAL, bool Wait = false, bool ManualWait = false, HANDLE* pH = nullptr)
    		{
    			return detail::RunProcess<SHELLEXECUTEINFOA>(Process.c_str(), Parameters.c_str(), nShow, Wait, ManualWait, &ShellExecuteExA, pH);
    		}
    		__declspec(deprecated) inline HRESULT Run(const std::wstring& Process, const std::wstring& Parameters, int nShow = SW_SHOWNORMAL, bool Wait = false, bool ManualWait = false, HANDLE* pH = nullptr)
    		{
    			return detail::RunProcess<SHELLEXECUTEINFOW>(Process.c_str(), Parameters.c_str(), nShow, Wait, ManualWait, &ShellExecuteExW, pH);
    		}
    
    		inline HRESULT Run(const Utility::FullPathA_t& Process, const std::string& Parameters, int nShow = SW_SHOWNORMAL, bool Wait = false, bool ManualWait = false, HANDLE* pH = nullptr)
    		{
    			return detail::RunProcess<SHELLEXECUTEINFOA>(Process.get().c_str(), Parameters.c_str(), nShow, Wait, ManualWait, &ShellExecuteExA, pH);
    		}
    		inline HRESULT Run(const Utility::FullPathW_t& Process, const std::wstring& Parameters, int nShow = SW_SHOWNORMAL, bool Wait = false, bool ManualWait = false, HANDLE* pH = nullptr)
    		{
    			return detail::RunProcess<SHELLEXECUTEINFOW>(Process.get().c_str(), Parameters.c_str(), nShow, Wait, ManualWait, &ShellExecuteExW, pH);
    		}
    
    		inline HRESULT Run(const Utility::RelativePathA_t& Process, const std::string& Parameters, int nShow = SW_SHOWNORMAL, bool Wait = false, bool ManualWait = false, HANDLE* pH = nullptr)
    		{
    			return detail::RunProcess<SHELLEXECUTEINFOA>(Process.get().c_str(), Parameters.c_str(), nShow, Wait, ManualWait, &ShellExecuteExA, pH);
    		}
    		inline HRESULT Run(const Utility::RelativePathW_t& Process, const std::wstring& Parameters, int nShow = SW_SHOWNORMAL, bool Wait = false, bool ManualWait = false, HANDLE* pH = nullptr)
    		{
    			return detail::RunProcess<SHELLEXECUTEINFOW>(Process.get().c_str(), Parameters.c_str(), nShow, Wait, ManualWait, &ShellExecuteExW, pH);
    		}
    	}
    }
    
    #endif
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    How the hell can you read this code? May I know your resolution? 200 columns with 8-space tabs in addition. Seems a little too much to me.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes, well, did I say it needed work? I did.
    My resolution is 1920x1080.
    I can't be arsed to fix it.

    Btw, I use 4 spaces for tabs. The board simply insists on 8 spaces per tab.
    Last edited by Elysia; 03-15-2011 at 08:00 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User muffinman8641's Avatar
    Join Date
    Feb 2011
    Location
    Eastern-Central PA
    Posts
    76
    I'm not sure how to use this for my needs (I was just thinking a statement or two...?) and also my compiler returns that StrTraits doesn't exist.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yeah, it would complain, wouldn't it? That's because it's made to work with both char and wide char.
    Anyhoo, relevant code should be...
    Header file (StringTraits.h):
    Code:
    #ifndef STRING_TRAITS_H_2010_06_28_19_27
    #define STRING_TRAITS_H_2010_06_28_19_27
    
    #include <type_traits>
    #include <string>
    #include "Traits.h"
    #include "Utility\Identifier.h"
    
    namespace Stuff
    {
    	template<typename T> struct StrTraits: public StrTraits< typename BasicType<T>::type > {};
    	//template<typename T> struct StrTraits<T*>: public StrTraits< typename std::remove_reference<std::remove_const<T>>::type > {};
    	//template<typename T> struct StrTraits<std::remove_reference<std::remove_const<T>>::type
    
    	template<> struct StrTraits<char>
    	{
    		typedef char RawType;
    		static const char NullChar = '\0';
    		static const char PathSeparator = '\\';
    		static const char* const DotText;
    		static const char* const TwoDotsText;
    		static const char* const OpenText;
    		static const char* const EmptyText;
    		static const char* const StarDotStarText;
    	};
    
    	template<> struct StrTraits<wchar_t>
    	{
    		typedef wchar_t RawType;
    		static const wchar_t NullChar = L'\0';
    		static const wchar_t PathSeparator = L'\\';
    		static const wchar_t* const DotText;
    		static const wchar_t* const TwoDotsText;
    		static const wchar_t* const OpenText;
    		static const wchar_t* const EmptyText;
    		static const wchar_t* const StarDotStarText;
    	};
    
    	template<> struct StrTraits<std::string>: public StrTraits<char> {};
    	template<> struct StrTraits<std::wstring>: public StrTraits<wchar_t> {};
    	template<> struct StrTraits<Utility::FullPathA_t>: public StrTraits<char> {};
    	template<> struct StrTraits<Utility::FullPathW_t>: public StrTraits<wchar_t> {};
    	template<> struct StrTraits<Utility::RelativePathA_t>: public StrTraits<char> {};
    	template<> struct StrTraits<Utility::RelativePathW_t>: public StrTraits<wchar_t> {};
    }
    
    #endif
    And source file:
    Code:
    #include "StringTraits.h"
    
    const char* const Stuff::StrTraits<char>::OpenText = "open";
    const char* const Stuff::StrTraits<char>::DotText = ".";
    const char* const Stuff::StrTraits<char>::TwoDotsText = "..";
    const char* const Stuff::StrTraits<char>::EmptyText = "";
    const char* const Stuff::StrTraits<char>::StarDotStarText = "*.*";
    
    const wchar_t* const Stuff::StrTraits<wchar_t>::DotText = L".";
    const wchar_t* const Stuff::StrTraits<wchar_t>::TwoDotsText = L"..";
    const wchar_t* const Stuff::StrTraits<wchar_t>::OpenText = L"open";
    const wchar_t* const Stuff::StrTraits<wchar_t>::EmptyText = L"";
    const wchar_t* const Stuff::StrTraits<wchar_t>::StarDotStarText = L"*.*";
    After the code compiles, all you do it:
    Stuff::RunProcess("your_file", "arguments");
    And if you want to wait until it exits:
    Stuff::RunProcess("your_file", "arguments", SW_SHOWNORMAL, true);

    That's all.

    Here is Utility\Identifier.h if you want it:
    Code:
    #ifndef IDENTIFIER_20100828_1741
    #define IDENTIFIER_20100828_1741
    
    #include <string>
    //#include <Windows.h>
    
    namespace Stuff
    {
    	namespace Utility
    	{
    		template<typename T, int N> class Identifier
    		{
    		public:
    			typedef const T& const_reference;
    			typedef T value_type;
    
    			explicit Identifier(const T& Data): m_Data(Data) { } 
    			Identifier(): m_Data(T()) { }
    
    			Identifier& operator ++ () { ++m_Data; return *this; }
    			Identifier operator ++ (int) { Identifier tmp(*this); m_Data++; return tmp; }
    			Identifier& operator -- () { --m_Data; return *this; }
    			Identifier operator -- (int) { Identifier tmp(*this); m_Data--; return tmp; }
    
    			Identifier& operator = (const Identifier& rhs) { m_Data = rhs.m_Data; return *this; }
    			Identifier& operator += (const Identifier& rhs) { m_Data += rhs.m_Data; return *this; }
    
    			friend bool operator == (const Identifier& lhs, const Identifier& rhs) { return lhs.m_Data == rhs.m_Data; }
    			friend bool operator <= (const Identifier& lhs, const Identifier& rhs) { return lhs.m_Data <= rhs.m_Data; }
    			friend bool operator >= (const Identifier& lhs, const Identifier& rhs) { return lhs.m_Data >= rhs.m_Data; }
    			friend bool operator < (const Identifier& lhs, const Identifier& rhs) { return lhs.m_Data < rhs.m_Data; }
    			friend bool operator > (const Identifier& lhs, const Identifier& rhs) { return lhs.m_Data > rhs.m_Data; }
    
    			friend Identifier operator + (const Identifier& lhs, const Identifier& rhs) { return Identifier(lhs.m_Data + rhs.m_Data); }
    			friend Identifier operator - (const Identifier& lhs, const Identifier& rhs) { return Identifier(lhs.m_Data - rhs.m_Data); }
    			friend Identifier operator * (const Identifier& lhs, const Identifier& rhs) { return Identifier(lhs.m_Data * rhs.m_Data); }
    
    			template<typename T, typename Traits> friend std::basic_ostream<T, Traits>& operator << 
    				(std::basic_ostream<T, Traits>& lhs, const Identifier& rhs) { lhs << rhs.m_Data; return lhs; }
    
    			__declspec(deprecated) const T& GetDimensionLess() const { return m_Data; }
    			__declspec(deprecated) T& GetDimensionLess() { return m_Data; }
    			const T& get() const { return m_Data; }
    			T& get() { return m_Data; }
    
    		protected:
    			T m_Data;
    		};
    
    		typedef Identifier<int, 0> X_t;
    		typedef Identifier<int, 1> Y_t;
    
    		typedef Identifier<std::wstring, 2> FullPathW_t;
    		typedef Identifier<std::string, 2> FullPathA_t;
    
    		typedef Identifier<std::string, 3> RelativePathA_t;
    		typedef Identifier<std::wstring, 3> RelativePathW_t;
    
    		//typedef Identifier<std::wstring, 4> FullOrRelativePathW_t;
    		//typedef Identifier<std::string, 4> FullOrRelativePathA_t;
    	}
    }
    
    #endif
    Last edited by Elysia; 03-15-2011 at 08:53 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    OP, use ShellExecuteA(NULL, "open", <program>, <program arguments>, NULL, SW_SHOW);

    Job done. The above is just laughable considering you can make it work with char or wchar in a single function

  10. #10
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by Elysia View Post
    Code:
    #include "Utility\Identifier.h"
    I realize this code is for windows, and I hope understand that I have the utmost respect for you and recognize that your answers are always spot on, but in this case I would suggest using forward slashes ("/") as that is more portable than the windows-specific back slashes ("\"). Linux, and I suspect other unix-like operating systems, will reject the back slashes. Windows, however, will accept forward slashes without complaint.

    just my two cents.

  11. #11
    Registered User muffinman8641's Avatar
    Join Date
    Feb 2011
    Location
    Eastern-Central PA
    Posts
    76
    It says type_traits: no such file or directory when I try to compile your source code.

  12. #12
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by muffinman8641 View Post
    It says type_traits: no such file or directory when I try to compile your source code.
    Just use ShellExecute()... it's deadly easy.

    Code:
    #include <windows.h>    // yes, even in console mode
    #include <shellapi.h>
    
    int main ( void )
      { cout >> "Press Enter key to launch notepad" >> endl
         cin 
        
         ShellExecute(NULL,"Open", "C:\\windows\\notepad.exe",NULL,NULL,SW_SHOWNORMAL);
    
        return 0; }
    ShellExecute can also launch files by association, start explorer sessions and open windows browsers for you...

    Quote Originally Posted by Elkvis View Post
    I realize this code is for windows, and I hope understand that I have the utmost respect for you and recognize that your answers are always spot on, but in this case I would suggest using forward slashes ("/") as that is more portable than the windows-specific back slashes ("\"). Linux, and I suspect other unix-like operating systems, will reject the back slashes. Windows, however, will accept forward slashes without complaint.

    just my two cents.
    Ummmm... Windows 7 will accept forward slashes... don't try it on XP or previous.
    Last edited by CommonTater; 03-15-2011 at 10:55 AM.

  13. #13
    Registered User
    Join Date
    Sep 2010
    Posts
    69
    Quote Originally Posted by adeyblue View Post
    OP, use ShellExecuteA(NULL, "open", <program>, <program arguments>, NULL, SW_SHOW);

    Job done. The above is just laughable considering you can make it work with char or wchar in a single function
    What ? Are you nuts man ?

    Recent quotes by Elysia:
    Quote Originally Posted by Elysia
    Nonsense. Win32 should be avoided at all costs.

    There is no reason to use a pure win32 approach.

    You're a C programmer. What do you expect?

    But your roots are that of C. It's where your mindset is. It's how you look at the world. Everything that strays from that is biased in some way. Isn't it?

    So the point is, since you are used to working with it and is a C programmer at heart, it would be nice for you. But in reality it's horrible, difficult and a menace. It requires years of experience to use properly, and even then, it's entirely possible to make numerous mistakes. Not a very friendly environment.

    I am well versed in Win32. To a degree anyway. It's horrible. It's complex, and it's disgusting. Not only because it's pure C, but because of its complexity.

    This isn't about C or C++: if you use C, then go ahead, use the API. It might not be too horrendous. But to a C++ programmer, the API is horrendous. It will create bugs, and it will create substandard code for the language. And that is because C++ has tools which C does not, and the API can obviously not use those.

    And it creates bugs. Bugs which you can live without unless you really need the flexibility which only in about 0.000001% of the cases.

    I am wondering if you are aware of what the word complex means. Have you worked on libraries in C++? Of big templates systems? Meta template programming? I dare say it's pretty complex. And yes, I have done it.
    And you know algorithms? They can be pretty complicated, too. Yes, and I have written lots of them.

    It is, because in the end, the reason I embrace complexity is to reduce it. A library must be flexible. But it must also be easy to use. Win32 is not. It's a failure.

    Because it's inferior.
    "Hey, look, it's cold outside! Let's store our food outside instead of the freezer!"

    You misunderstand what I mean by inferior. It isn't that WinAPI produces inferior results--it does not. It is inferior in such a way that it is difficult to use to attain the correct results. The libraries simply the getting results right part.

    Yes, and I still claim that using WinAPI in its raw form introduces bugs into programs. More so than using 3rd party libraries.

    No, they are not logical.

    It means they are working in a field they should not be.

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by CommonTater
    Windows 7 will accept forward slashes... don't try it on XP or previous.
    Have you ever actually tried it on say, MSVC6 with Windows 2000? I recall it working just fine, though I could be mistaken as it was quite some time ago.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by muffinman8641 View Post
    It says type_traits: no such file or directory when I try to compile your source code.
    Eh, remove the include. It seems to be a legacy include.

    Quote Originally Posted by Elkvis View Post
    I realize this code is for windows, and I hope understand that I have the utmost respect for you and recognize that your answers are always spot on, but in this case I would suggest using forward slashes ("/") as that is more portable than the windows-specific back slashes ("\"). Linux, and I suspect other unix-like operating systems, will reject the back slashes. Windows, however, will accept forward slashes without complaint.

    just my two cents.
    Yeah, usually I do use "/" instead of "\". Unfortunately, code do get old and old programming habits do get littered throughout the code.
    The code really needs some cleanup and fixing, but eh... I'm too lazy right now.

    muffinman, it's really up to you if you want to use my library code or do it the Win32 way. All I can say is that I've made my code work with C++ string types, and the ability to wait for a process to finish before returning.

    Quote Originally Posted by adeyblue View Post
    OP, use ShellExecuteA(NULL, "open", <program>, <program arguments>, NULL, SW_SHOW);

    Job done. The above is just laughable considering you can make it work with char or wchar in a single function
    Good job! You just failed to launch a program correctly.
    Laughable? I dare you to make something better.
    The link isn't much better, just does it in a slightly different way. Suffice to say, it's not much better.
    Last edited by Elysia; 03-15-2011 at 11:29 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How To Make A Program Remain Open For Windows XP
    By BrandNew in forum C Programming
    Replies: 3
    Last Post: 02-22-2011, 08:28 AM
  2. Hi, Quiz C program Assignment updated
    By Eman in forum C Programming
    Replies: 19
    Last Post: 11-22-2009, 04:50 PM
  3. program to open IE
    By x2012 in forum C# Programming
    Replies: 2
    Last Post: 11-03-2006, 09:07 PM
  4. how to make certain file types open IN your program
    By DarkViper in forum Windows Programming
    Replies: 4
    Last Post: 02-06-2003, 11:37 PM
  5. drawing over the open program.
    By Unregistered in forum Windows Programming
    Replies: 6
    Last Post: 01-23-2002, 03:37 PM