2010-12-06 10 views
0

私はC++(Visual Studio 2010)でWindowsサービスを作成していますが、このサービスは安全なコピーを使ってリモートサーバーにファイルを送信する必要がありますそのためにはpscp.exeを使用してください)。Windowsサービスから外部プログラム(pscp)を実行すると動作しない

私はsystem関数を使用してpscp.exeを起動しています。通常のアプリケーションとして実行しても問題ないです。

サービスとして実行しようとすると、サービスはpscp.exeを起動しますが、これはタスクマネージャで表示されますが、pscp.exeはフリーズしてリモートホストに何も送信しません。サービスを停止しても、自分でpscpプロセスを終了する必要があります。

私はいくつかのフォーラムでサービスを「デスクトップとやりとりする」ことができますが、これは私の問題を解決しません。

サービスログオンのユーザーアカウントを変更しましたが、結果は表示されません。

アイデア?

この外部プログラムにpscp.exeのようなGUIがない場合でも、Windowsサービスから外部プログラムを実行するのは非常に難しいようです。

ありがとうございます!

- アウグストCaringi

+0

あなたはどのアカウントを使用していますか?ほとんどのサービスは、「**ローカル**システム」として実行されます。明らかに、リモートホストに接続する必要がある場合は、pscpには十分ではありません。 – MSalters

答えて

0

pscp呼び出しにあなたのオプションは何ですか? 「サイレント」オプションがある場合は、コンソールの操作を避けるためにそのオプションを使用します。多くの場合、これは-qまたは/qです。

起動したアプリはサービスと同じユーザーアカウントで実行されることに注意してください。そのアカウントには、あなたが求めていることをする権限がありますか?コンテキスト(実行ディレクトリ、パス)は正しいですか?pscpは正しいですか?

+0

私はすでにpscp(-q)に 'silent'オプションを使用しています。 –

+0

サービスは問題なく指定されたディレクトリにファイルを書き込むことができます。そして、私は、同じユーザーアカウントでpscpプログラムを実行すると、ファイルも読み取ることができると思います。 –

0

偽装を試みることがあります。このようなもの...

wchar_t* cmPath=readRegistryString(L"Software\\" TO_WCHAR(ORG_NAME) L"\\" TO_WCHAR(APP_NAME) L"\\" TO_WCHAR(APPLICATION_GROUP),TO_WCHAR(APPLICATION_EXEC_PATH)); 
if (!cmPath) 
{ 
    return false; 
} 
HANDLE userToken=NULL; 
DWORD sessId=WTSGetActiveConsoleSessionId(); 
if((long)sessId==-1) 
{ 
    sessId=0; 
} 
WTSQueryUserToken (sessId, &userToken); 
bool result=false; 
if(userToken/**/) 
{ 
    SECURITY_ATTRIBUTES sa; 
    ZeroMemory(&sa,sizeof(SECURITY_ATTRIBUTES)); 
    sa.nLength=sizeof(SECURITY_ATTRIBUTES); 
    STARTUPINFOW si; 
    ZeroMemory(&si,sizeof(STARTUPINFOW)); 
    si.cb=sizeof(STARTUPINFOW); 
    PROCESS_INFORMATION pi; 
    ZeroMemory(&pi,sizeof(PROCESS_INFORMATION)); 
    CStringW str= L"\""; 
    str=str+cmPath; 
    str=str+L"\""; 
    str.Replace(L"/",L"\\"); 

    if(CreateProcessAsUserW(userToken,NULL,str.GetBuffer(),NULL,NULL,false,NULL,NULL,NULL,&si,&pi)) 
    { 
      result=true; 
      CloseHandle(pi.hProcess); 
      CloseHandle(pi.hThread); 
    } 
    else 
    { 
     DWORD err = GetLastError(); 
     //nop; 
    } 
} 
if(userToken) 
    CloseHandle(userToken); 
delete[] cmPath; 

このコードは、サービスからGUIアプリケーションを呼び出すために使用しますが、コンソールアプリケーションの変更はそれほど必要ないと思います。

0

システムではなくCreateProcess関数を使用してpscpアプリケーションを起動する必要があります。後者はコマンドをサービスからアクセスできないコマンドインタプリタ(cmd.exe)にリレーします。

+0

私はシステムの代わりに_popen関数を使っていくつかのテストをしていますが、pscpの出力をキャプチャしています。私は、プログラムがリモートホストに接続しようとするとフリーズするだけであることを知ります。たとえば、pscp -vを実行して(バージョンのみを表示して終了する)、それはOkを実行します。 –

+0

そのような問題はネットワークのアクセス許可です – jalf

+0

jalf、私はこれを考えました。しかし、私はlibcurlからcurl.exeでpscp.exeを置き換えました。これが私の問題を解決しました。 –

0

問題を修正しました。

pscp.exeはサービスから実行できません。どうしてか分かりません。

しかし、curl.exe(libcurlから)が行い、安全なコピーをサポートしています!

ありがとうございました。

関連する問題