こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

VC++で、msiを実行する方法???

こんにちは。よろしくお願いします。

Visual Studio 2005 を使っています。
関数CreateProcessWithLogonW()への引数に
拡張子がexeやbatのファイルを渡すと実行できるのですが、
拡張子がmsiだと実行できません><

batファイルの中に
msiexec /i C:\ファイル名.msi
と記述しておいて、
関数CreateProcessWithLogonW()ではそのbatファイルを実行させ、
どうにか目的のmsiファイルを実行することは可能でしたが、

batファイルを経由せずに直接、
関数CreateProcessWithLogonW()への引数で
msiファイルを実行できる方法は無いでしょうか?

何か方法をご存知の方、同じような事をご経験された方、
アドバイスよろしくお願い致します。

投稿日時 - 2009-10-29 14:10:07

QNo.5405962

すぐに回答ほしいです

質問者が選んだベストアンサー

こんにちは。

#1さんの言われるようにWindowsAPIのShellExecute関数で実行可能かと
思われます。

下記のサンプルは、ShellExecute関数を使用した一例です。

ShellExecute関数の"open"コマンドで、実行ファイルを指定しない場合は、
開くファイルに関連付けされたアプリケーションでファイルが開かれますので
それを利用します。

■サンプルプログラム(C++版)
注1)msiファイル用のインストーラーアプリのパス名及びファイル名は、
   Windows及びアプリのバージョンにより変更する必要があります。
注2)サンプルは処理系およびWindowsのバージョンにより、正常にビルド
   及び実行ができない可能性があります。
注3)ソース内にはインデントのため全角スペースを入れています。

==============================
/*
* OpenMsi.cpp : Msiインストールファイルの起動テスト
*/
#include <windows.h>
#include <shellapi.h>
#include <iostream>
#include <cstring>
using namespace std;

int main(int argc, char *argv[])
{
  BOOL bApp;      //Shell起動の方法
            // =false:関連付けで起動、=true:指定アプリで起動
  HINSTANCE hInst;  //インスタンス取得用
  char szCmd[256];  //アプリ起動時のコマンド文字列

  // msiファイル名をセット
  const char szMsiFn[] =
    { "F:\\Soft\\Tools\\hogehoge.msi" };

  // msi用インストーラーアプリのフルパス名をセット
  const char szAppPath[] =
    { "C:\\WINDOWS\\SYSTEM\\msiexec.exe" };

  // Shell起動の方法を選択
  // ※コマンドラインオプションで切替え
  bApp = false;      //初期値をセット(関連付けで起動)
  if( argc < 2 ){      //オプション指定なし
    bApp = false;    //関連付けで起動
  }
  else {          //オプション指定あり
    if( !strcmp(argv[1], "/1") ){
      bApp = false;  //関連付けで起動
    }
    else if( !strcmp(argv[1], "/2") ){
      bApp = true;  //指定アプリで起動
    }
    else{
      cout << "オプション指定が違います。" << endl;
      return 1;
    }
  }

  // msiファイルを開く
  if( !bApp ){
    // 関連付けされたアプリケーションで開く
    strcpy( szCmd, szMsiFn );
    cout << "Shell Execute Command:\n";
    cout << "=>Open " << szCmd << endl;
    hInst = ::ShellExecute( NULL, "open", szCmd, NULL, NULL, SW_SHOWNORMAL );
  }
  else{
    // 指定のアプリケーションで開く
    strcpy( szCmd, "/i " );
    strcat( szCmd, szMsiFn );
    cout << "Shell Execute Command:\n";
    cout << "=>" << szAppPath << " " << szCmd << endl;
    hInst = ::ShellExecute( NULL, "open", szAppPath, szCmd, NULL, SW_SHOWNORMAL );
  }

  // Shell起動の可否チェック
  if( (int)hInst <= 32 ){
    // 戻り値が32以下の時は起動に失敗
    cout << "msiファイルが開けません。" << endl;
    return 2;
  }

  return 0;
}
==============================

以上です。上手くいかなかった場合はすみません。
参考になれば幸いです。

投稿日時 - 2009-10-29 20:06:30

お礼

ファイル名.msi
では実行できませんでしたが、
msiexec /i C:\ファイル名.msi
とコマンドごと文字列で渡してみると
関数CreateProcessWithLogonW()
から実行することが出来ました!
回答いただきありがとうございました!!!

投稿日時 - 2009-11-05 12:01:21

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

-広告-
-広告-

回答(2)

ANo.1

ShellExecute()関数ではいかがでしょうか?

投稿日時 - 2009-10-29 16:13:44

お礼

関数CreateProcessWithLogonW()でも
実行することができました!
回答ありがとうございました!!!

投稿日時 - 2009-11-05 12:02:11

-広告-
-広告-

あなたにオススメの質問

-広告-
-広告-